[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[cinvoke-svn] r136 - trunk/skorpion
From: |
will |
Subject: |
[cinvoke-svn] r136 - trunk/skorpion |
Date: |
13 Dec 2006 03:54:06 -0500 |
Author: vmy
Date: 2006-12-13 03:54:06 -0500 (Wed, 13 Dec 2006)
New Revision: 136
Added:
trunk/skorpion/TextSystem.cs
Log:
class for creating text overlays, with 3d capability
Added: trunk/skorpion/TextSystem.cs
===================================================================
--- trunk/skorpion/TextSystem.cs (rev 0)
+++ trunk/skorpion/TextSystem.cs 2006-12-13 08:54:06 UTC (rev 136)
@@ -0,0 +1,710 @@
+using System;
+using System.Drawing;
+using Microsoft.DirectX.Direct3D;
+
+namespace skorpion
+{
+ /// <summary>
+ /// Summary description for TextSystem.
+ /// </summary>
+ public class TextSystem
+ {
+ 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 Device device;
+ private TextureStateManager textureState0;
+ private TextureStateManager textureState1;
+ private SamplerStateManager samplerState0;
+ private RenderStateManager renderState;
+ private Texture fontTexture;
+ private 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 TextSystem(System.Drawing.Font f)
+ {
+ ourFontName = f.Name;
+ ourFontHeight = (int)f.Size;
+ systemFont = f;
+ }
+
+
+
+ /// <summary>
+ /// Create a new font object
+ /// </summary>
+ public TextSystem(string fontName) : this(fontName,
FontStyle.Regular, 12)
+ {
+ }
+
+
+
+
+ /// <summary>
+ /// Create a new font object
+ /// </summary>
+ public TextSystem(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 TextSystem(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.
+ 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(Sprite sprite, float xpos, float ypos,
Color color, string text)
+ {
+ DrawText(sprite, xpos, ypos, color, text,
RenderFlags.Filtered);
+ }
+
+
+
+
+ /// <summary>
+ /// Draw some text on the screen
+ /// </summary>
+ public void DrawText(Sprite sprite, float xpos, float ypos,
Color color, string text, RenderFlags flags)
+ {
+ if (text == null)
+ return;
+
+ // Setup renderstate
+ savedStateBlock.Capture();
+ 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];
+ float ty1 = textureCoords[c-32,1];
+ float tx2 = textureCoords[c-32,2];
+ float ty2 = textureCoords[c-32,3];
+
+ float w = (tx2-tx1) * textureWidth /
textureScale;
+ float h = (ty2-ty1) * textureHeight /
textureScale;
+
+ int intColor = color.ToArgb();
+ if (c != ' ')
+ {
+ fontVertices[iv++] = new
CustomVertex.TransformedColoredTextured(new
Microsoft.DirectX.Vector4(xpos+0-0.5f,ypos+h-0.5f,0.9f,1.0f), intColor, tx1,
ty2);
+ fontVertices[iv++] = new
CustomVertex.TransformedColoredTextured(new
Microsoft.DirectX.Vector4(xpos+0-0.5f,ypos+0-0.5f,0.9f,1.0f), intColor, tx1,
ty1);
+ fontVertices[iv++] = new
CustomVertex.TransformedColoredTextured(new
Microsoft.DirectX.Vector4(xpos+w-0.5f,ypos+h-0.5f,0.9f,1.0f), intColor, tx2,
ty2);
+ fontVertices[iv++] = new
CustomVertex.TransformedColoredTextured(new
Microsoft.DirectX.Vector4(xpos+w-0.5f,ypos+0-0.5f,0.9f,1.0f), intColor, tx2,
ty1);
+ fontVertices[iv++] = new
CustomVertex.TransformedColoredTextured(new
Microsoft.DirectX.Vector4(xpos+w-0.5f,ypos+h-0.5f,0.9f,1.0f), intColor, tx2,
ty2);
+ fontVertices[iv++] = new
CustomVertex.TransformedColoredTextured(new
Microsoft.DirectX.Vector4(xpos+0-0.5f,ypos+0-0.5f,0.9f,1.0f), intColor, tx1,
ty1);
+ dwNumTriangles += 2;
+
+ if (dwNumTriangles*3 >
(MaxNumfontVertices-6))
+ {
+ // Set the data for the
vertexbuffer
+
vertexBuffer.SetData(fontVertices, 0, LockFlags.Discard);
+
device.DrawPrimitives(PrimitiveType.TriangleList, 0, dwNumTriangles);
+ dwNumTriangles = 0;
+ iv = 0;
+ }
+ }
+
+ xpos += w - (2 * spacingPerChar);
+ }
+
+ // Set the data for the vertex buffer
+ vertexBuffer.SetData(fontVertices, 0,
LockFlags.Discard);
+ if (dwNumTriangles > 0)
+
device.DrawPrimitives(PrimitiveType.TriangleList, 0, dwNumTriangles);
+
+ // Restore the modified renderstates
+ savedStateBlock.Apply();
+ }
+
+
+
+
+ /// <summary>
+ /// Draws scaled 2D text. Note that x and y are in viewport
coordinates
+ /// (ranging from -1 to +1). fXScale and fYScale are the size
fraction
+ /// relative to the entire viewport. For example, a fXScale of
0.25 is
+ /// 1/8th of the screen width. This allows you to output text
at a fixed
+ /// fraction of the viewport, even if the screen or window size
changes.
+ /// </summary>
+ public void DrawTextScaled(float x, float y, float z,
+ float fXScale, float fYScale,
+ System.Drawing.Color color,
+ string text, RenderFlags flags)
+ {
+#if false
+ if (device == null)
+ throw new System.ArgumentNullException();
+
+ // Set up renderstate
+ savedStateBlock.Capture();
+ drawTextStateBlock.Apply();
+ 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;
+ }
+
+ Viewport vp = device.Viewport;
+ float xpos = (x+1.0f)*vp.Width/2;
+ float ypos = (y+1.0f)*vp.Height/2;
+ float sz = z;
+ float rhw = 1.0f;
+ float fLineHeight = (textureCoords[0,3] -
textureCoords[0,1]) * textureHeight;
+
+ // Adjust for character spacing
+ xpos -= spacingPerChar *
(fXScale*vp.Height)/fLineHeight;
+ float fStartX = xpos;
+
+ // Fill vertex buffer
+ int numTriangles = 0;
+ int realColor = color.ToArgb();
+ int iv = 0;
+
+ foreach (char c in text)
+ {
+ if (c == '\n')
+ {
+ xpos = fStartX;
+ ypos += fYScale*vp.Height;
+ }
+
+ if ((c-32) < 0 || (c-32) >= 128-32)
+ continue;
+
+ float tx1 = textureCoords[c-32,0];
+ float ty1 = textureCoords[c-32,1];
+ float tx2 = textureCoords[c-32,2];
+ float ty2 = textureCoords[c-32,3];
+
+ float w = (tx2-tx1)*textureWidth;
+ float h = (ty2-ty1)*textureHeight;
+
+ w *= (fXScale*vp.Height)/fLineHeight;
+ h *= (fYScale*vp.Height)/fLineHeight;
+
+ if (c != ' ')
+ {
+ fontVertices[iv++] = new
CustomVertex.TransformedColoredTextured(new
Vector4(xpos+0-0.5f,ypos+h-0.5f,sz,rhw), realColor, tx1, ty2);
+ fontVertices[iv++] = new
CustomVertex.TransformedColoredTextured(new
Vector4(xpos+0-0.5f,ypos+0-0.5f,sz,rhw), realColor, tx1, ty1);
+ fontVertices[iv++] = new
CustomVertex.TransformedColoredTextured(new
Vector4(xpos+w-0.5f,ypos+h-0.5f,sz,rhw), realColor, tx2, ty2);
+ fontVertices[iv++] = new
CustomVertex.TransformedColoredTextured(new
Vector4(xpos+w-0.5f,ypos+0-0.5f,sz,rhw), realColor, tx2, ty1);
+ fontVertices[iv++] = new
CustomVertex.TransformedColoredTextured(new
Vector4(xpos+w-0.5f,ypos+h-0.5f,sz,rhw), realColor, tx2, ty2);
+ fontVertices[iv++] = new
CustomVertex.TransformedColoredTextured(new
Vector4(xpos+0-0.5f,ypos+0-0.5f,sz,rhw), realColor, tx1, ty1);
+ numTriangles += 2;
+
+ if (numTriangles*3 >
(MaxNumfontVertices-6))
+ {
+ // Unlock, render, and relock
the vertex buffer
+
vertexBuffer.SetData(fontVertices, 0, LockFlags.Discard);
+
device.DrawPrimitives(PrimitiveType.TriangleList , 0, numTriangles);
+ numTriangles = 0;
+ iv = 0;
+ }
+ }
+
+ xpos += w - (2 * spacingPerChar) *
(fXScale*vp.Height)/fLineHeight;
+ }
+
+ // Unlock and render the vertex buffer
+ vertexBuffer.SetData(fontVertices, 0,
LockFlags.Discard);
+ if (numTriangles > 0)
+
device.DrawPrimitives(PrimitiveType.TriangleList , 0, numTriangles);
+
+ // Restore the modified renderstates
+ savedStateBlock.Apply();
+#endif
+ }
+
+
+
+
+ /// <summary>
+ /// Draws scaled 2D text. Note that x and y are in viewport
coordinates
+ /// (ranging from -1 to +1). fXScale and fYScale are the size
fraction
+ /// relative to the entire viewport. For example, a fXScale of
0.25 is
+ /// 1/8th of the screen width. This allows you to output text
at a fixed
+ /// fraction of the viewport, even if the screen or window size
changes.
+ /// </summary>
+ public void DrawTextScaled(float x, float y, float z,
+ float fXScale, float fYScale,
+ System.Drawing.Color color,
+ string text)
+ {
+ this.DrawTextScaled(x,y,z,fXScale, fYScale, color,
text, 0);
+ }
+
+
+
+
+ /// <summary>
+ /// Renders 3D text
+ /// </summary>
+ public void Render3DText(string text, RenderFlags flags)
+ {
+#if true
+ if (device == null)
+ throw new System.ArgumentNullException();
+
+ // Set up renderstate
+ savedStateBlock.Capture();
+ drawTextStateBlock.Apply();
+ device.VertexFormat =
CustomVertex.PositionNormalTextured.Format;
+ device.PixelShader = null;
+ device.SetStreamSource(0, vertexBuffer, 0,
VertexInformation.GetFormatSize(CustomVertex.PositionNormalTextured.Format));
+
+ // Set filter states
+ if ((flags & RenderFlags.Filtered) != 0)
+ {
+ samplerState0.MinFilter = TextureFilter.Linear;
+ samplerState0.MagFilter = TextureFilter.Linear;
+ }
+
+ // Position for each text element
+ float x = 0.0f;
+ float y = 0.0f;
+
+ // Center the text block at the origin
+ if ((flags & RenderFlags.Centered) != 0)
+ {
+ System.Drawing.SizeF sz = GetTextExtent(text);
+ x = -(((float)sz.Width)/10.0f)/2.0f;
+ y = -(((float)sz.Height)/10.0f)/2.0f;
+ }
+
+ // Turn off culling for two-sided text
+ if ((flags & RenderFlags.TwoSided) != 0)
+ renderState.CullMode = Cull.None;
+
+ // Adjust for character spacing
+ x -= spacingPerChar / 10.0f;
+ float fStartX = x;
+
+ // Fill vertex buffer
+ Microsoft.DirectX.GraphicsStream strm =
vertexBuffer.Lock(0, 0, LockFlags.Discard);
+ int numTriangles = 0;
+
+ foreach (char c in text)
+ {
+ if (c == '\n')
+ {
+ x = fStartX;
+ y -=
(textureCoords[0,3]-textureCoords[0,1])*textureHeight/10.0f;
+ }
+
+ if ((c-32) < 0 || (c-32) >= 128-32)
+ continue;
+
+ float tx1 = textureCoords[c-32,0];
+ float ty1 = textureCoords[c-32,1];
+ float tx2 = textureCoords[c-32,2];
+ float ty2 = textureCoords[c-32,3];
+
+ float w = (tx2-tx1) * textureWidth / (10.0f *
textureScale);
+ float h = (ty2-ty1) * textureHeight / (10.0f *
textureScale);
+
+ if (c != ' ')
+ {
+ strm.Write(new
CustomVertex.PositionNormalTextured(new Microsoft.DirectX.Vector3(x+0,y+0,0),
new Microsoft.DirectX.Vector3(0,0,-1), tx1, ty2));
+ strm.Write(new
CustomVertex.PositionNormalTextured(new Microsoft.DirectX.Vector3(x+0,y+h,0),
new Microsoft.DirectX.Vector3(0,0,-1), tx1, ty1));
+ strm.Write(new
CustomVertex.PositionNormalTextured(new Microsoft.DirectX.Vector3(x+w,y+0,0),
new Microsoft.DirectX.Vector3(0,0,-1), tx2, ty2));
+ strm.Write(new
CustomVertex.PositionNormalTextured(new Microsoft.DirectX.Vector3(x+w,y+h,0),
new Microsoft.DirectX.Vector3(0,0,-1), tx2, ty1));
+ strm.Write(new
CustomVertex.PositionNormalTextured(new Microsoft.DirectX.Vector3(x+w,y+0,0),
new Microsoft.DirectX.Vector3(0,0,-1), tx2, ty2));
+ strm.Write(new
CustomVertex.PositionNormalTextured(new Microsoft.DirectX.Vector3(x+0,y+h,0),
new Microsoft.DirectX.Vector3(0,0,-1), tx1, ty1));
+ numTriangles += 2;
+
+ if (numTriangles*3 >
(MaxNumfontVertices-6))
+ {
+ // Unlock, render, and relock
the vertex buffer
+ vertexBuffer.Unlock();
+
device.DrawPrimitives(PrimitiveType.TriangleList , 0, numTriangles);
+ strm = vertexBuffer.Lock(0, 0,
LockFlags.Discard);
+ numTriangles = 0;
+ }
+ }
+
+ x += w - (2 * spacingPerChar) / 10.0f;
+ }
+
+ // Unlock and render the vertex buffer
+ vertexBuffer.Unlock();
+ if (numTriangles > 0)
+
device.DrawPrimitives(PrimitiveType.TriangleList , 0, numTriangles);
+
+ // Restore the modified renderstates
+ savedStateBlock.Apply();
+#endif
+ }
+
+
+
+
+ /// <summary>
+ /// Get the dimensions of a text string
+ /// </summary>
+ private System.Drawing.SizeF GetTextExtent(string text)
+ {
+ if (null == text || text == string.Empty)
+ throw new System.ArgumentNullException();
+
+ float fRowWidth = 0.0f;
+ float fRowHeight =
(textureCoords[0,3]-textureCoords[0,1])*textureHeight;
+ float fWidth = 0.0f;
+ float fHeight = fRowHeight;
+
+ foreach (char c in text)
+ {
+ if (c == '\n')
+ {
+ fRowWidth = 0.0f;
+ fHeight += fRowHeight;
+ }
+
+ if ((c-32) < 0 || (c-32) >= 128-32)
+ continue;
+
+ float tx1 = textureCoords[c-32,0];
+ float tx2 = textureCoords[c-32,2];
+
+ fRowWidth += (tx2-tx1)*textureWidth -
2*spacingPerChar;
+
+ if (fRowWidth > fWidth)
+ fWidth = fRowWidth;
+ }
+
+ return new System.Drawing.SizeF(fWidth, fHeight);
+ }
+
+
+
+
+ /// <summary>
+ /// Cleanup any resources being used
+ /// </summary>
+ public void Dispose(object sender, EventArgs e)
+ {
+ if (systemFont != null)
+ systemFont.Dispose();
+
+ systemFont = null;
+ }
+ }
+}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [cinvoke-svn] r136 - trunk/skorpion,
will <=