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

📄 d3dfont.cs

📁 Particle System Test Application on C#
💻 CS
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// File: D3DFont.cs
//
// Desc: Shortcut functions for using DX objects
//
// Copyright (c) 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;

    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;
    private 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;
    }

    
    
    /// <summary>
    /// Create a new font object
    /// </summary>
    public GraphicsFont(string fontName) : this(fontName, FontStyle.Regular, 12)
    {
    }


    
    
    /// <summary>
    /// Create a new font object
    /// </summary>
    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>
    /// Attempt to draw the systemFont alphabet onto the provided texture
    /// graphics.
    /// </summary>
    /// <param name="g"></param>Graphics object on which to draw and measure the letters</param>
    /// <param name="measureOnly">If set, the method will test to see if the alphabet will fit without actually drawing</param>
    public void PaintAlphabet(Graphics g, bool measureOnly)
    {
        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;
            }

            // Make sure we have room for the current character
            if ((y + size.Height) > textureHeight)
                throw new System.InvalidOperationException("Texture too small for alphabet");
                
            if (!measureOnly)
            {
                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);
        }

    }




    /// <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;

        // Create a bitmap on which to measure the alphabet
        Bitmap bmp = new Bitmap(1, 1, 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;
       
        // Establish the font and texture size
        textureScale  = 1.0f; // Draw fonts into texture without scaling

        // Calculate the dimensions for the smallest power-of-two texture which
        // can hold all the printable characters
        textureWidth = textureHeight = 128;
        for (;;)
        {
            try
            {
                // Measure the alphabet
                PaintAlphabet(g, true);
            }
            catch (System.InvalidOperationException)
            {
                // Scale up the texture size and try again
                textureWidth *= 2;
                textureHeight *= 2;
                continue;
            }

            break;
        }

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

        // If the needed texture is too large for the video card...
        if (textureWidth > d3dCaps.MaxTextureWidth)
        {
            // Scale the font size down to fit on the largest possible texture
            textureScale = (float)d3dCaps.MaxTextureWidth / (float)textureWidth;
            textureWidth = textureHeight = d3dCaps.MaxTextureWidth;

            for(;;)
            {
                // Create a new, smaller font
                ourFontHeight = (int) Math.Floor(ourFontHeight * textureScale);      
                systemFont = new System.Drawing.Font(systemFont.Name, ourFontHeight, systemFont.Style);
                
                try
                {
                    // Measure the alphabet
                    PaintAlphabet(g, true);
                }
                catch (System.InvalidOperationException)
                {
                    // If that still doesn't fit, scale down again and continue
                    textureScale *= 0.9F;
                    continue;
                }

                break;
            }
        }

        // Release the bitmap used for measuring and create one for drawing
        bmp.Dispose();
        bmp = new Bitmap(textureWidth, textureHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        g = Graphics.FromImage(bmp);
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
        g.TextContrast = 0;

        // Draw the alphabet
        PaintAlphabet(g, false);

        // 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);

        Surface surf = device.GetRenderTarget( 0 );
        bool bSupportsAlphaBlend = Manager.CheckDeviceFormat(device.DeviceCaps.AdapterOrdinal, 
            device.DeviceCaps.DeviceType, device.DisplayMode.Format, 
            Usage.RenderTarget | Usage.QueryPostPixelShaderBlending, ResourceType.Surface, 
            surf.Description.Format );

        // 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;

            if( bSupportsAlphaBlend )
            {
                renderState.AlphaBlendEnable = true;
                renderState.SourceBlend = Blend.SourceAlpha;
                renderState.DestinationBlend = Blend.InvSourceAlpha;
            }
            else
            {
                renderState.AlphaBlendEnable = false;
            }
            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);
    }



⌨️ 快捷键说明

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