So, if you want to render Doom3 fonts using Managed DirectX, here's the code. (
ResourceToStream
is a helper function that returns a MemoryStream from the byte array passed to it.Imports Microsoft.DirectXThe reason for returning the
Imports Microsoft.DirectX.Direct3D
Public Class idFont
Private _font As Texture
Private _device As Device
Private _sprite As Sprite
Private Structure fontchar
Dim height As Integer ' number of scan lines
Dim top As Integer ' top of glyph in buffer
Dim bottom As Integer ' bottom of glyph in buffer
Dim pitch As Integer ' width for copying
Dim xSkip As Integer ' x adjustment
Dim imageWidth As Integer ' width of actual image
Dim imageHeight As Integer ' height of actual image
Dim s As Single ' x offset in image where glyph starts
Dim t As Single ' y offset in image where glyph starts
Dim s2, t2 As Single
End Structure
Private xRes, yRes As Integer
Private height As Integer = 0
Private _chars(255) As fontchar
Public Sub New(ByVal fontdata() As Byte, _
ByVal fontlayoutdata() As Byte, _
ByVal device As Device)
_font = TextureLoader.FromStream(device, ResourceToStream(fontdata))
xRes = _font.GetSurfaceLevel(0).Description.Width
yRes = _font.GetSurfaceLevel(0).Description.Height
Dim s As New IO.BinaryReader(ResourceToStream(fontlayoutdata))
For x As Integer = 0 To 255
With _chars(x)
.height = s.ReadInt32
If .height > height Then height = .height
.top = s.ReadInt32
.bottom = s.ReadInt32
.pitch = s.ReadInt32
.xSkip = s.ReadInt32
.imageWidth = s.ReadInt32
.imageHeight = s.ReadInt32
.s = s.ReadSingle
.t = s.ReadSingle
.s2 = s.ReadSingle
.t2 = s.ReadSingle
s.ReadInt32() : s.ReadBytes(32) ' Dispose unneeded extra stuff
End With
Next
s.Close()
_sprite = New Sprite(device)
End Sub
Public Function DrawText(ByVal text As String, _
ByVal x As Integer, _
ByVal y As Integer, _
ByVal color As Color) As Integer
If text Is Nothing Then Return y
If text.Length = 0 Then Return y
Dim c As Integer, ch As fontchar
_sprite.Begin(SpriteFlags.AlphaBlend)
For z As Integer = 0 To text.Length - 1
c = Asc(text.Chars(z))
If c >= 0 And c <= 255 Then
ch = _chars(c)
' Valid char, let's go
_sprite.Draw2D(_font, _
New Rectangle(ch.s * xRes, ch.t * yRes, ch.imageWidth, ch.imageHeight), _
New Size(ch.imageWidth, ch.imageHeight), _
New PointF(x, y + height - ch.top), _
color)
x += ch.xSkip
End If
Next
_sprite.End()
Return x
End Function
End Class
x
variable is so you can mix fonts on a single line. It returns the horizontal position where it stopped rendering.
No comments:
Post a Comment