موضوع : ترسیم متن دو بعدی در DirectX
در این درس روش ترسیم متن با دو نوع فونت را نشان خواهم داد :
برای رسم یک متن با فونت تعریف شده در سیستم از شی D3DXFont استفاده می کنیم :
Dim MainFont as D3DXFont
Dim MainFontDesc as IFont
Dim TextRect as RECT
Dim fnt as new stdFont
در حالیکه برای ایجاد یک متن با فونت custom ابتدا یک texture تعریف می کنیم :
Dim fntTex as Direct3DTexture8
همچنین برای ترسیم هر کاراکتر یک آرایه vertex ای را از نوع TLVERTEX تعریف می نمائیم :
Dim vertchar(3) as TLVERTEX
حال به سراغ تابع Initialize می رویم . در این تابع ابتدا دستورات مربوط به ایجاد اشیا D3D و D3Dx را قرا دهید سپس دستورات مربوط به اختصاص آداپتور و نیز ایجاد شی D3DDevice را انجام می دهیم . حال دستورات تنظیم shader و rendering را می آوریم :
D3DDevice.SetVertexShader TL_FVF
D3DDevice.SetRenderState D3DRS_LIGHTING, False
سپس تنظیمات پارامترهای transparency برای rendering را انجام می دهیم :
D3DDevice.SetRenderState D3DRS_SRCBLEND, D3DBLEND_SRCALPHA
D3DDevice.SetRenderState D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA
D3DDevice.SetRenderState D3DRS_ALPHABLENDENABLE, True
حال بایستی textureرا طوری فیلتر کنیم که در زمان stretch شدن یا squash شدن بهتر بنظر برسد :
D3DDevice.SetTextureStageState 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR
D3DDevice.SetTextureStageState 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR
حال فیلتر Z را فعال می کنیم :
D3DDevice.SetRenderState D3DRS_ZENABLE, 1
سپس ماتریسهای world ، view و projection را تنظیم می کنیم :
D3DXMatrixIdentity matWorld
D3DDevice.SetTransform D3DTS_WORLD, matWorld
D3DXMatrixLookAtLH matView, MakeVector(0, 9, -9), MakeVector(0, 0, 0), MakeVector(0, 1, 0)
D3DDevice.SetTransform D3DTS_VIEW, matView
D3DXMatrixPerspectiveFovLH matProj, pi / 4, 1, 0.1, 500
D3DDevice.SetTransform D3DTS_PROJECTION, matProj
حال به بخش تنظیم پارامترهای فونت می رسیم . در مورد فونت دو بعدی عادی :
fnt.Name = "Verdana"
fnt.Size = 18
fnt.Bold = True
Set MainFontDesc = fnt
Set MainFont = D3DX.CreateFont(D3DDevice, MainFontDesc.hFont)< /FONT >
و در مورد فونت custom :
Set fntTex = D3DX.CreateTextureFromFileEx(D3DDevice, yourfilename, 256, 128, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_FILTER_POINT, D3DX_FILTER_POINT, &HFF00FF00, ByVal 0, ByVal 0)
end function
روتین Render بصورت زیر خواهد بود :
Public Sub Render()
D3DDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET Or D3DCLEAR_ZBUFFER, 0, 1#, 0
D3DDevice.BeginScene
برای رندر متن با فونت عادی بصورت زیر عمل می کنیم :
TextRect.Top = 440
TextRect.Left = 1
TextRect.bottom = 480
TextRect.Right = 640
D3DX.DrawText MainFont, &HFFCCCCFF, "Current Frame Rate: " & FPS_Current, TextRect, DT_TOP Or DT_CENTER
برای رندر متن با فونت custom بصورت زیر عمل می کنیم :
RenderStringFromCustomFont_2D "Hamed Sheidaian", 1, 1, 16, 16
D3DDevice.EndScene
D3DDevice.Present ByVal 0, ByVal 0, 0, ByVal 0
End Sub
همانطور که مشاهده می کنید از روتینی با نام RenderStringFromCustomFont_2D استفاده شده است :
Private Sub RenderStringFromCustomFont_2D(strText As String, startX As Single, StartY As Single, Height As Integer, Width As Integer)
Dim I As Integer
Dim CharX As Integer, CharY As Integer
Dim Char As String
Dim LinearEntry As Integer
If Len(strText) = 0 Then Exit Sub
For I = 1 To Len(strText< /FONT > )
1 - ابتدا بایستی مختصات texture را انتخاب کنیم . برای اینکار بایستی هر entry را در texture جدا کنیم :
Char = Mid$(strText, I, 1)
If Asc(Char) >= 65 And Asc(Char) <= 90 Then
LinearEntry = Asc(Char) - 65
ElseIf Asc(Char) >= 97 And Asc(Char) <= 122 Then
LinearEntry = Asc(Char) - 71
ElseIf Asc(Char) >= 48 And Asc(Char) <= 57 Then
LinearEntry = Asc(Char) + 4
ElseIf Char = " " Then
LinearEntry = 63
ElseIf Char = "." Then
LinearEntry = 62
ElseIf Char = ";" Then
LinearEntry = 66
ElseIf Char = "/" Then
LinearEntry = 64
ElseIf Char = "," Then
LinearEntry = 65
End If
بعد از مقداردهی LinearEntry بایستی مختصات grid کاراکتر را پردازش کنیم :
If LinearEntry <= 15 Then
CharY = 0
CharX = LinearEntry
End If
If LinearEntry >= 16 And LinearEntry <= 31 Then
CharY = 1
CharX = LinearEntry - 16
End If
If LinearEntry >= 32 And LinearEntry <= 47 Then
CharY = 2
CharX = LinearEntry - 32
End If
If LinearEntry >= 48 And LinearEntry <= 63 Then
CharY = 3
CharX = LinearEntry - 48
End If
If LinearEntry >= 64 And LinearEntry <= 79 Then
CharY = 4
CharX = LinearEntry - 64
End If
2 - حال بایستی vertex های مورد نیاز برای رسم کاراکتر را تولید کنیم :
vertChar(0) = CreateTLVertex(startX + (Width * I), StartY, 0, 1, &HFFFFF
(F,0,(1/16)*CharX,(1/8)*CharY
vertChar(1) = CreateTLVertex(startX + (Width * I) + Width, StartY, 0, 1, &HFFFFF
(F, 0,((1 / 16) * CharX) + (1 / 16), (1 / 8) * CharY
vertChar(2) = CreateTLVertex(startX + (Width * I), StartY + Height, 0, 1, &HFFFFF
((F, 0, (1 / 16) * CharX, ((1 / 8) * CharY) + (1 / 8
vertChar(3) = CreateTLVertex(startX + (Width * I) + Width, StartY + Height, 0, 1, HFFFFFF, 0, ((1 / 16) * CharX) + (1 / 16), ((1 / 8) * CharY) + (1 / 8))
3 - رندر vertex ها :
D3DDevice.SetTexture 0, fntTex
D3DDevice.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, vertChar(0), Len(vertChar(0))
Next I
End Sub