وبلاگ تخصصي برنامه نويسي با VB

آموزش DirectX8 قسمت نهم

موضوع :‌ترسيم متن دو بعدي در 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"x
fnt.Size = 18
fnt.Bold = True
Set MainFontDesc = fnt
Set MainFont = D3DX.CreateFont(D3DDevice, MainFontDesc.hFont)x


و در مورد فونت 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)x
end function


روتين Render بصورت زير خواهد بود :


Public Sub Render()x
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)x
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)x


1 - ابتدا بايستي مختصات texture را انتخاب کنيم . براي اينکار بايستي هر entry را در texture جدا کنيم :


Char = Mid$(strText, I, 1)x
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


۲ - حال بايستي 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))x


۳ - رندر vertex ها :


D3DDevice.SetTexture 0, fntTex
D3DDevice.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, vertChar(0), Len(vertChar(0))x
Next I
End Sub

+ حامد شیدائیان ; ٤:٥٧ ‎ب.ظ ; دوشنبه ٢۸ امرداد ،۱۳۸۱
comment نظرات ()