?? d3dfont.cs
字號:
//-----------------------------------------------------------------------------
// 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 + -