⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 d3dfont.cs

📁 Game Engine Desing Direct X and C#.rar
💻 CS
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// File: D3DFont.cs
//
// Desc: Shortcut functions for using DX objects
//
// Copyright (c) 2001-2002 Microsoft Corporation. All rights reserved
//-----------------------------------------------------------------------------
using System;
using System.Drawing;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D=Microsoft.DirectX.Direct3D;


/// <summary>
/// A generic font class 
/// </summary>
public class GraphicsFont
{
    public const int MaxNumfontVertices = 50*6;
  
    // Font rendering flags
    [System.Flags]
    public enum RenderFlags
    {
        Centered = 0x0001,
        TwoSided = 0x0002, 
        Filtered = 0x0004,
    }
    private System.Drawing.Font systemFont;

    private bool isZEnable = false;
    public bool ZBufferEnable { get { return isZEnable; } set { isZEnable = value; } }
    string ourFontName;            // Font properties
    int ourFontHeight;

	public int LineHeight { get { return ourFontHeight*2; } }

    private Direct3D.Device device;
    private TextureState textureState0;
    private TextureState textureState1;
    private Sampler samplerState0;
    private RenderStates renderState;
    private Direct3D.Texture fontTexture;
    private Direct3D.VertexBuffer vertexBuffer;
    private CustomVertex.TransformedColoredTextured[] fontVertices = new CustomVertex.TransformedColoredTextured[MaxNumfontVertices];

    private int textureWidth;                 // Texture dimensions
    private int textureHeight;
    private float textureScale;
    public int spacingPerChar;
    private float[,] textureCoords = new float[128-32,4];

    // Stateblocks for setting and restoring render states
    private StateBlock savedStateBlock;
    private StateBlock drawTextStateBlock;




    /// <summary>
    /// Create a new font object
    /// </summary>
    /// <param name="f">The font to use</param>
    public GraphicsFont(System.Drawing.Font f)
    {
        ourFontName = f.Name;
        ourFontHeight = (int)f.Size;
        systemFont = f;
    }

    public GraphicsFont(string fontName) : this(fontName, FontStyle.Regular, 12){}
    public GraphicsFont(string fontName, FontStyle style) : this(fontName, style, 12){}
    /// <summary>
    /// Create a new font object
    /// </summary>
    /// <param name="fontName">The name of the font</param>
    /// <param name="style">The style</param>
    /// <param name="size">Size of the font</param>
    public GraphicsFont(string fontName, FontStyle style, int size)
    {
        ourFontName = fontName;
        ourFontHeight = size;
        systemFont = new System.Drawing.Font( fontName, ourFontHeight, style);
    }




    /// <summary>
    /// Initialize the device objects
    /// </summary>
    /// <param name="dev">The grpahics device used to initialize</param>
    public void InitializeDeviceObjects(Device dev)
    {
        if (dev != null)
        {
            // Set up our events
            dev.DeviceReset += new System.EventHandler(this.RestoreDeviceObjects);
        }

        // Keep a local copy of the device
        device = dev;
        textureState0 = device.TextureState[0];
        textureState1 = device.TextureState[1];
        samplerState0 = device.SamplerState[0];
        renderState = device.RenderState;

        // Establish the font and texture size
        textureScale  = 1.0f; // Draw fonts into texture without scaling

        // Large fonts need larger textures
        if( ourFontHeight > 60 )
            textureWidth = textureHeight = 2048;
        else if( ourFontHeight > 30 )
            textureWidth = textureHeight = 1024;
        else if( ourFontHeight > 15 )
            textureWidth = textureHeight = 512;
        else
            textureWidth  = textureHeight = 256;

        // If requested texture is too big, use a smaller texture and smaller font,
        // and scale up when rendering.
        Direct3D.Caps d3dCaps = device.DeviceCaps;

        if( textureWidth > d3dCaps.MaxTextureWidth )
        {
            textureScale = (float)d3dCaps.MaxTextureWidth / (float)textureWidth;
            textureWidth = textureHeight = d3dCaps.MaxTextureWidth;
        }

        Bitmap bmp = new Bitmap( textureWidth, textureHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb );
        Graphics g = Graphics.FromImage( bmp );
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
        g.TextContrast = 0;


        string str;
        float x = 0;
        float y = 0;
        Point p = new Point(0, 0);
        Size size = new Size(0,0);
            
        // Calculate the spacing between characters based on line height
        size = g.MeasureString( " ", systemFont).ToSize();
        x = spacingPerChar = (int) Math.Ceiling( size.Height * 0.3 );

        for( char c = (char)32; c < (char)127; c++ )
        {
            str = c.ToString();
            // We need to do some things here to get the right sizes.  The default implemententation of MeasureString
            // will return a resolution independant size.  For our height, this is what we want.  However, for our width, we 
            // want a resolution dependant size.
            Size resSize = g.MeasureString( str, systemFont).ToSize();
            size.Height = resSize.Height + 1;

            // Now the Resolution independent width
            if (c != ' ') // We need the special case here because a space has a 0 width in GenericTypoGraphic stringformats
            {
                resSize = g.MeasureString( str, systemFont, p, StringFormat.GenericTypographic).ToSize();
                size.Width = resSize.Width;
            }
            else
                size.Width = resSize.Width;

            if( ( x + size.Width + spacingPerChar ) > textureWidth )
            {
                x = spacingPerChar;
                y += size.Height;
            }

            if (c != ' ') // We need the special case here because a space has a 0 width in GenericTypoGraphic stringformats
                g.DrawString( str, systemFont, Brushes.White, new Point((int)x, (int)y), StringFormat.GenericTypographic);
            else
                g.DrawString( str, systemFont, Brushes.White, new Point((int)x, (int)y));
            textureCoords[c-32,0] = ((float) ( x + 0           - spacingPerChar )) / textureWidth;
            textureCoords[c-32,1] = ((float) ( y + 0           + 0              )) / textureHeight;
            textureCoords[c-32,2] = ((float) ( x + size.Width  + spacingPerChar )) / textureWidth;
            textureCoords[c-32,3] = ((float) ( y + size.Height + 0              )) / textureHeight;

            x += size.Width + (2 * spacingPerChar);
        }

        // Create a new texture for the font from the bitmap we just created
        fontTexture = Texture.FromBitmap(device, bmp, 0, Pool.Managed);
        RestoreDeviceObjects(null, null);
    }




    /// <summary>
    /// Restore the font after a device has been reset
    /// </summary>
    public void RestoreDeviceObjects(object sender, EventArgs e)
    {
        vertexBuffer = new VertexBuffer( typeof(CustomVertex.TransformedColoredTextured), MaxNumfontVertices,
            device, Usage.WriteOnly | Usage.Dynamic, 0, Pool.Default );

        // Create the state blocks for rendering text
        for( int which=0; which < 2; which++ )
        {
            device.BeginStateBlock();
            device.SetTexture( 0, fontTexture );

            if ( isZEnable )
                renderState.ZBufferEnable = true;
            else
                renderState.ZBufferEnable = false;

            renderState.AlphaBlendEnable = true;
            renderState.SourceBlend = Blend.SourceAlpha;
            renderState.DestinationBlend = Blend.InvSourceAlpha;
            renderState.AlphaTestEnable = true;
            renderState.ReferenceAlpha = 0x08;
            renderState.AlphaFunction = Compare.GreaterEqual;
            renderState.FillMode = FillMode.Solid;
            renderState.CullMode = Cull.CounterClockwise;
            renderState.StencilEnable = false;
            renderState.Clipping = true;
            device.ClipPlanes.DisableAll();
            renderState.VertexBlend = VertexBlend.Disable;
            renderState.IndexedVertexBlendEnable = false;
            renderState.FogEnable = false;
            renderState.ColorWriteEnable = ColorWriteEnable.RedGreenBlueAlpha;
            textureState0.ColorOperation = TextureOperation.Modulate;
            textureState0.ColorArgument1 = TextureArgument.TextureColor;
            textureState0.ColorArgument2 = TextureArgument.Diffuse;
            textureState0.AlphaOperation = TextureOperation.Modulate;
            textureState0.AlphaArgument1 = TextureArgument.TextureColor;
            textureState0.AlphaArgument2 = TextureArgument.Diffuse;
            textureState0.TextureCoordinateIndex = 0;
            textureState0.TextureTransform = TextureTransform.Disable; // REVIEW
            textureState1.ColorOperation = TextureOperation.Disable;
            textureState1.AlphaOperation = TextureOperation.Disable;
            samplerState0.MinFilter = TextureFilter.Point;
            samplerState0.MagFilter = TextureFilter.Point;
            samplerState0.MipFilter = TextureFilter.None;

            if( which==0 )
                savedStateBlock = device.EndStateBlock();
            else
                drawTextStateBlock = device.EndStateBlock();
        }

    
    }



    /// <summary>
    /// Draw some text on the screen
    /// </summary>
    public void DrawText( float xpos, float ypos, Color color, string text)
    {
        DrawText( xpos, ypos, color, text, RenderFlags.Filtered );
    }


    /// <summary>
    /// Draw some text on the screen
    /// </summary>
    public void DrawText( float xpos, float ypos, Color color, string text, RenderFlags flags)
    {
        if( text == null )
            return;

        // Setup renderstate
        savedStateBlock.Capture();
		try
		{
			drawTextStateBlock.Apply();
			device.SetTexture( 0, fontTexture );
			device.VertexFormat = CustomVertex.TransformedColoredTextured.Format;
			device.PixelShader = null;
			device.SetStreamSource( 0, vertexBuffer, 0);

			// Set filter states
			if( (flags & RenderFlags.Filtered) != 0 )
			{
				samplerState0.MinFilter = TextureFilter.Linear;
				samplerState0.MagFilter = TextureFilter.Linear;
			}

			// Adjust for character spacing
			xpos -= spacingPerChar;
			float fStartX = xpos;

			// Fill vertex buffer
			int iv = 0;
			int dwNumTriangles = 0;

			foreach( char c in text )
			{
				if( c == '\n' )
				{
					xpos = fStartX;
					ypos += (textureCoords[0,3]-textureCoords[0,1])*textureHeight;
				}

				if( (c-32) < 0 || (c-32) >= 128-32 )
					continue;

				float tx1 = textureCoords[c-32,0];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -