در این تاپیک قصد دارم به آموزش DirectX-Graphic که ابزاري است براي ساخت تصاوير ثابت و متحرک دو بعدي و سه بعدي که در محیط VB فراخوانی شده است
بپردازم . این آموزش ها شامل 10 مقاله میباشد. امیدوارم که مفید باشه.
با تشکر security
منبع : سايت كامپيوتر من
Security
01-02-07, 18:50
آموزش DirectX-Graphic ( قسمت اول ) :
DirectX8 ابزاري براي ساخت تصاوير ثابت و متحرک دو بعدي و سه بعدي مي باشد .
براي کار با DirectX8 ابتدا بايستي آنرا روي سيستم خود نصب کنيد . سپس در محيط vb از منوي project گزينه References را انتخاب کنيد . در فرمي که ظاهر مي شود اطمينان حاصل کنيد که گزينه DirectX8 for VB type library فعال باشد .
براي کار با DirectX8 بايستي از تعريف نمودن شي پايه DirectX8 شروع نمود :
Dim Dx as DirectX8
شي Direct3D8 براي کنترل اشيا سه بعدي بکار مي رود :
Dim D3D as Direct3D8
شي Direct3DDevice8 ، سخت افزار مربوط به رندر تصاوير را مشخص مي کند :
Dim D3DDevice as Direct3DDevice8
حال براي شروع کار با Direct3D ، تابع ( ) initialise را تعريف مي کنيم . اگر اينکار درست انجام شود تابع ، مقدار true را برمي گرداند :
public function initialise () as boolean
Dim DispMode as D3DISPLAYMODE
شي D3DISPLAYMODE حالت نمايش را مشخص مي نمايد :
Dim D3Dwindow as D3DPRESENT_PARAMETERS
شي فوق مشخص مي کند که viewport شما چگونه باشد .
حال شي اصلي DirectX8 را مي سازيم :
Set Dx=New DirectX8
سپس شي اصلي ساخت واسط سه بعدي را مي سازيم :
()set D3D.Dx.Direct3Dcreate
سپس حالت فعلي نمايش را با دستور زير استخراج مي کنيم :
حال دو حالت براي کار با DirectX داريم :
1 - windowed mode
2 - fullscrean mode
1 - براي کار با حالت پنجره اي ابتدا اين موضوع را به DirectX اطلاع مي دهيم :
D3Dwindow.windowed=1
سپس نوع referesh تصوير را مشخص مي کنيم :
D3Dwindow.swapeffect=D3DSWAPEFFECT_COPY_VSYNC
سپس بايستي فرمت بافر نگهدارنده تصاوير را مشخص کنيم :
D3Dwindow.backbufferformat=dispmode.format
2 - براي کار با حالت تمام صفحه ، ابتدا نوع refresh را مشخص کرده سپس تعداد بافر هاي تصوير و سرانجام نوع و سايز بافر را مشخص مي نمائيم :
حال بايستی يک device ساخته شود که يا از طريق سخت افزار و يا نرم افزار تصاوير را رندر نمايد :
Set D3DDevice=D3Dcreatedevice(D3DADAPTER_DEFAULT
,D3DDEVTYPE_HAL,
frmMain.hwnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,
D3Dwindow)x,
end sub
درصورتي که کارت گرافيک شما امکانات رندر سخت افزاري تصاوير را ندارد از D3DDEVTYPE_REF بجاي D3DDEVTYPE_HAL استفاده کنيد .
حال بايستي روتين render را بنويسيم . البته در اين درس تصويري براي رندر نداريم و تنها چگونگي نوشتن اين روتين را بيان خواهم کرد :
۱ - ابتدا بايستي device مربوط به رندر ، قبل از کشيدن تصوير در آن پاک شود :
عدد hex اي که در دستور فوق آمده رنگ زمينه صفحه را مشخص مي کند
۲ - سپس بايستي تصاوير مورد نظر را رندر کنيم . اينکار توسط دستورات زير انجام مي شود :
D3DDevice.beginscence
all rendering calls go between these two lines '
D3DDEvice.endscence
3 - در پايان بايستي صفحه را update کنيد :
D3DDevice.present byval 0,byval 0,0,byval 0
Security
01-02-07, 19:05
آموزش DirectX-Graphic (قسمت دوم)
موضوع : بدست آوردن مشخصات و تواناييهاي گرافيکي يک سيستم توسط DirectX-Graphic
1 - شمارش تعداد آداپتورهاي گرافيکي يک سيستم : فرض کنيد متغير nAdapters متغيري از نوع long باشد . همچنين شي D3DADAPTER_IDENTIFIER8 يک ساختار است که اطلاعات مربوط به آداپتور را نگه مي دارد . در اينصورت روتين enumerateAdapters بصورت زير خواهد بود :
Dim adapterinfo as D3DADAPTER_IDENTIFIER8
Private Sub EnumerateAdapters
Dim i as integer
nadapters=D3D.Getadaptercount
for i=0 to nadapters-1
D3D.GetadapterIdentifier i ,0,adapterinfo
نام اين آداپتور بصورت ليستي از کدهاي اسکي است که بايستي آنها را درون يک string قرار دهيم :
for j=0 to 511
name=name & chr$(adapterinfo.description(j)) x
next j
name=replace(name,chr$(0)," ") x
end sub
بنابراين در متغير name نام آداپتور قرار خواهد گرفت .
۲ - مشخص کردن نوع Rendering : فرض کنيد شي D3DCAPS8 توانايي rendering آداپتور را نشان دهد . در اينصورت روتين EnumerateDevices بصورت زير خواهد بود :
Private EnumerateDevices
On Local Error resume next
Dim Caps as D3DCAPS8
deviceindex=0 'For Example
D3D.Getdevicecaps deviceindex,D3DDEVTYPE_HAL,caps
if err.number=D3DERR_NOTAVAILABLE then
اگر آداپتور امکان رندر سخت افزاري نداشته باشد در اينصورت :
MsgBox("Reference Rasterizer(REF)") x
else
MsgBox("Hardware Acceleration(HAL)+Reference Rasterizer(REF)") x
end if
end sub
3 - شمارش تعداد Mode نمايشي آداپتور :
فرض کنيد در صورت REF بودن امکان رندر ، متغير r=2 و در غيراينصورت r=1
باشد . همچنين شي D3DDISPLAYMODE اطلاعات مدهاي نمايشي را در خود
دارد . همچنين فرض کنيد متغير nModes از نوع longباشد . در اينصورت روتين enumeratedispmodes بصورت زير خواهد بود :
Private Sub EnumerateDispModes(r as Long,n as Long) x
Dim i as integer
Dim mode_tmp as D3DDISPLAYMODE
deviceindex=0 'For Example
nModes=D3D.Getadaptermodecount(deviceindex) x
for i=0 to nModes-1
D3D.EnumAdapterModes(deviceindex,i,mode_tmp) x
ابتدا Mode ها را به دو گروه ۱۶ بيتي و ۳۲ بيتي تقسيم مي کنيم :
if mode_tmp.format=D3DFMT_R8G8B8 or mode_tmp=D3DFMT_X8R8G8B8 or mode_tmp=D3DFMT_A8R8G8B8 then
حال چک مي کنيم که device قابل پذيرش و معتبر است يا نه :
if D3D.checkdevicetype(deviceindex,r,mode_tmp.format, mode_tmp.format,Flase)>=0 then
MsgBox(mode_tmp.width & "X" & mode_tmp.height & "32 Bit
FMT:" & mode_tmp.format ) x & "
end if
else
if D3D.checkdevicetype(deviceindex,r,mode_tmp.format, mode_tmp.format,Flase)>=0 then
MsgBox(mode_tmp.width & "X" & mode_tmp.height & "16 Bit
FMT:" & mode_tmp.format ) x & "
end if
end if
next i
4 - مشخص کردن توانايي هاي آداپتور گرافيکي : فرض کنيد در صورت REF بودن امکان رندر ، متغير r=2 و در غيراينصورت r=1 باشد :
Private Sub EnumerateHardware(r as long) x
Dim caps as D3DCAPS8
D3D.Getdevicecaps deviceindex,r,caps
If Caps.MaxActiveLights = -1 Then
MsgBox "Maximum Active Lights: Unlimited" x
Else
MsgBox "Maximum Active Lights: " & Caps.MaxActiveLights
End If
MsgBox "Maximum Point Vertex size: " & Caps.MaxPointSize
MsgBox "Maximum Texture Size: " & Caps.MaxTextureWidth & "X" & Caps.MaxTextureHeight
MsgBox "Maximum Primatives in one call: " & Caps.MaxPrimitiveCount
If Caps.TextureCaps And D3DPTEXTURECAPS_SQUAREONLY Then
MsgBox "Textures must always be square" x
End If
If Caps.TextureCaps And D3DPTEXTURECAPS_CUBEMAP Then
MsgBox "Device Supports Cube Mapping" x
End If
If Caps.TextureCaps And D3DPTEXTURECAPS_VOLUMEMAP Then
MsgBox "Device Supports Volume Mapping" x
End If
If Caps.DevCaps And D3DDEVCAPS_PUREDEVICE Then
MsgBox "Device supports the Pure Device Option" x
End If
If Caps.DevCaps And D3DDEVCAPS_HWTRANSFORMANDLIGHT Then
MsgBox "Device supports hardware transform and lighting" x
End If
If Caps.DevCaps And D3DDEVCAPS_HWRASTERIZATION Then
MsgBox "Device can use Hardware Rasterization" x
End If
If Caps.Caps2 And D3DCAPS2_CANCALIBRATEGAMMA Then
MsgBox "Device can Calibrate Gamma" x
End If
If Caps.Caps2 And D3DCAPS2_CANRENDERWINDOWED Then
MsgBox "Device can Render in Windowed Mode" x
End If
If Caps.Caps2 And D3DCAPS2_FULLSCREENGAMMA Then
MsgBox "Device can calibrate gamma in fullscreen mode" x
End If
If Caps.RasterCaps And D3DPRASTERCAPS_FOGRANGE Then
MsgBox "Device supports range based fog calculations" x
End If
If Caps.RasterCaps And D3DPRASTERCAPS_ANISOTROPY Then
MsgBox "Device supports Anisotropic Filtering" x
End If
If Caps.RasterCaps And D3DPRASTERCAPS_ZBUFFERLESSHSR Then
MsgBox "Device does not require a Z-Buffer/Depth Buffer" x
End If
Security
02-02-07, 11:42
آموزش DirectX-Graphic (قسمت سوم)
موضوع : رسم اشکال دو بعدي
مروري بر object هاي DirectX8
1 - DirectX8 : اين شي ، شي مرکزي براي directX است و به شما امکان دسترسي به توابع و اشيا DirectX را مي دهد .
۲ - Direct3D8 : شي اصلي براي کار با محيط سه بعدي مي باشد . هدف از آن ، ساخت Direct3DDevice8 است و همچنين شامل توابعي براي مشخص کردن توانايي هاي کارت گرافيک است .
۳ - Direct3DDevice8 : اين شي مسئول ساخت بافتها textures ، مديريت نورها در يک صحنه ، مديريت مواد materials و همچنين render صحنه است . در واقع اين شي ، قلب نمايشي کار شماست .
4 - D3DX8 : گر چه هميشه نيازي به استفاده از اين شي نيست ، اما اين شي شامل توابعي براي ساخت برنامه هاي userfriendly تر توسط DirectX است . مثلاً ساخت اشيا سه بعدي ( مثل کره ، مکعب و ... ) ، ساخت بافتها ، ساخت سطوح و غيره
شروع کار براي رسم اشيا دوبعدي
ابتدا ثابت FVF را تعريف مي کنيم . اين ثابت توصيف " فرمت قابل انعطاف نقطه flexible-vertex-format " براي يک vertex دو بعدي انتقال يافته و ساده شده مي باشد .
سپس بايستي يک ساختار براي توصيف اين vertex معرفي کنيم :
Const FVF = D3DFVF_XYZRHW Or D3DFVF_TEX1 Or D3DFVF_DIFFUSE Or D3DFVF_SPECULAR
Private Type TLVERTEX
X As Single
Y As Single
Z As Single
rhw As Single
color As Long
specular As Long
tu As Single
tv As Single
End Type
فرض کنيد بخواهيم يک مربع را در صفحه رسم کنيم . براي رسم آن نياز به 4 عدد vertex داريم . بنابراين آرايه TriStrip را از نوع TLVERTEX تعريف ميکنيم :
Dim TriStrip (0 To 3) As TLVERTEX
حال به سراغ تابع initialize که در درس ۱ با آن آشنا شديد مي رويم و دستورات زير را به آن اضافه مي کنيم :
Private Function Initialize as boolean
.
.
.
ابتدا سيستم سايه زني vertex را طوري تنظيم مي کنيم که از FVF استفاده کند .
D3DDevice.SetVertexShader FVF
حال سيستم lighting را براي vertex هاي دو بعدي غير فعال مي کنيم زيرا نيازي به آن نداريم :
D3DDevice.SetRenderState D3DRS_LIGHTING,false
حال بايستي تابع initializeGeometry را اجرا کنيم . اين تابع را در ادامه توضيح خواهم داد . اگر نتيجه اين تابع true باشد دراينصورت initialize به درستي انجام شده است :
if initializeGeometry()=true then initialize=true
end function
تابع initializeGeometry در اين درس ، تابعي ساده است که تنها آرايه Vertex ها را مقدار دهي مي کند . براي رسم يک مربع نياز به مقداردهي ۴ vertex در جهت عقربه هاي ساعت داريم ( اين مربع شامل ۲ مثلث است )
Private Function InitialiseGeometry() As Boolean
On Error GoTo BOut:
color = RGB(200, 100, 0)
TriStrip(0) = CreateTLVertex(100, 100, 0, 1, color, 0, 0, 0)
TriStrip(1) = CreateTLVertex(300, 100, 0, 1, color, 0, 0, 0)
TriStrip(2) = CreateTLVertex(100, 300, 0, 1, color, 0, 0, 0)
TriStrip(3) = CreateTLVertex(300, 300, 0, 1, color, 0, 0, 0)
InitialiseGeometry = True
Exit Function
BOut:
InitialiseGeometry = False
End Function
همانطور که مشاهده مي کنيد براي تعريف vertex از تابع CreateTLVERTEX استفاده شده است . اين تابع صرفاً مقادير ساختار TLVERTEX را مقداردهي مي کند :
Private Function CreateTLVertex(X As Single, Y As Single, Z As Single, rhw As Single, color As Long, specular As Long, tu As Single, tv As Single) As TLVERTEX
نکته : ضمن اينکه شما مي توانيد مقادير اعشاري floating point را براي مختصاتهاي x و y و z بکار ببريد ، Direct3D مختصاتها را با گردکردن آنها تخمين مي زند و بنابراين ممکنست باعث ايجاد نتايج ناخواسته شود .
CreateTLVertex.X = X
CreateTLVertex.Y = Y
CreateTLVertex.Z = Z
CreateTLVertex.rhw = rhw
CreateTLVertex.color = color
CreateTLVertex.specular = specular
CreateTLVertex.tu = tu
CreateTLVertex.tv = tv
End Function
حال بايستي تابع Render را بنويسيم :
Public Sub Render()
D3DDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET, 0, 1#, 0
D3DDevice.BeginScene
D3DDevice.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, TriStrip(0), Len(TriStrip(0))x
D3DDevice.EndScene
D3DDevice.Present ByVal 0, ByVal 0, 0, ByVal 0
End Sub
ساختار اصلي براي اجراي توابع فوق بصورت زير است :
Main part--
Initialize
Do While yourevent=true
Render
DoEvents
Loop
Security
02-02-07, 11:45
آموزشDirectX-Graphic (قسمت چهارم)
موضوع : آشنايي با برخي اصطلاحات
1- Mesh : مش ، مجموعه اي از face ها است که يک شي سه بعدي را روي صفحه تشکيل مي دهند .
۲ - Face : يک چند ضلعی است که توسط مجموعه ای از نقاط به نام vertex ساخته مي شود .
۳ - Vertex : يک نقطه در فضاي سه بعدي است که براي دادن موقعيت ، scale و زاويه يک face استفاده مي شود .
۴ - Direct3D از شيي بنام D3DVERTEX براي نمايش يک Vertex استفاده مي کند . براي ساخت face نيز از آرايه اي از vertex ها استفاده مي شود . آرايه هميشه بايستي قابل تقسيم به سه باشد زيرا اشکال از face هاي مثلثي ساخته مي شوند . هنگاميکه اين مثلثها کنار هم گذاشته شوند ، شي سه بعدي را مي سازند . Direct3D از بافري با نام Index Buffer استفاده مي کند که با direct3D مي گويد که با چه ترتيبي vertex ها را رسم نمايد . index ها بايستي هميشه در جهت عقربه هاي ساعت مشخص شوند .
Security
02-02-07, 11:49
آموزشDirectX-Graphic (قسمت پنجم)
موضوع : اختصاص بافت Texture به اشکال دو بعدي
در اين درس مي خواهيم يک مربع که داراي بافت مي باشد را رسم کنيم . براي اينکار از کتابخانه کمکي D3DX8 استفاده مي کنيم . همچنين شي Direct3DTexture8 را نيز استفاده مي نمائيم .
Dim D3DX as D3DX8
Dim Texture as Direct3DTexture8
حال بايستي در تابع Initialize بافت مربوطه را از روي يک فايل تصويري load کنيم :
Private Function Initialize as boolean
.
.
.
Set Texture=D3DX8.CreateTextureFromFile(D3DDevice,app. path & yourfilename) x
end function
تابع Render نيز بصورت زير خواهد بود :
Private Sub Render
D3DDevice.clear 0,byval 0,D3DCLEAR_TARGET,0,1#,0
D3DDevice.beginscence
D3DDevice.SetTexture 0,Texture
D3DDevice.DrawprimitiveUP D3DPT_TRIANGLESTRIP,2,Tripstrip(0),len(Tristrip(0) )x
.
.
.
end function
Security
02-02-07, 12:01
آموزشDirectX-Graphic (قسمت ششم)
موضوع : مفاهيم اوليه رسم اشکال سه بعدي در DirectX 8
در اين درس با استفاده از Direct3D يک مکعب را رسم مي کنيم . براي اين منظور ابتدا نياز به يک بافر داريم که بتوانيم شکل مورد نظر خود را در آن ذخيره کنيم :
Dim VBuffer as Direct3DVertexBuffer8
براي رسم مکعب از vertex هاي سه بعدي استفاده مي کنيم . براي اينکار نياز به تعريف يک تايپ جديد داريم :
Private Type LITVERTEX
x as single
y as single
z as single
color as long
specular as long
tu as single
tv as single
end type
توصيف گر اين فرمت ، بصورت زير است :
Const Lit_FVF = (D3DFVF_XYZ Or D3DFVF_DIFFUSE Or D3DFVF_SPECULAR Or D3DFVF_TEX1)x
براي توصيف مکعب در اين درس از روشي غيرکارامد استفاده شده است . به اين ترتيب که از ۳۶ عدد vertex استفاده شده ( در درسهاي بعدي متدهايي معرفي خواهند شد که اجازه مي دهند از ۸ عدد vertex باري توصيف مکعب استفاده کنيد ) .
Dim cube(35) as LITVERTEX
سپس بايد يکسري ماتريس سه بعدي تعريف کنيم :
اولين ماتريس ، matworld است که نشان مي دهد چگونه vertex ها در فضاي سه بعدي قرار گرفته اند . دومين ماتريس ، matview است که نشان مي دهد دوربين ( نقطه ديد ) در کجا قرار گرفته و سومين ماتريس ، matproj است که نشان مي دهد دوربين چگونه دنياي سه بعدي را روي صفحه دو بعدي نشان مي دهد :
Dim matworld as D3DMATRIX
Dim matview as D3DMATRIX
Dim matproj as D3DMATRIX
در تابع Initialize قبل از ساخت device بايستي چک کنيم که آيا مي توانيم از يک بافر Z شانزده بيتي استفاده کنيم يا نه ؟
If D3D.CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, DispMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16) = D3D_OK Then
D3DWindow.AutoDepthStencilFormat = D3DFMT_D16 '16 bit Z-Buffe
حال بايستي متد D3DCreateDevice را اجرا کنيد . سپس بايد سيستم سايه زني vertex را با فرمت vertex مان تنظيم کنيم :
D3DDevice.SetVertexShader Lit_FVF
همچنين سيستم نورپردازي را غير فعال مي کنيم :
D3DDevice.SetRenderState D3DRS_LIGHTING, False
Direct3D هيچ مثلثي را که در ديد شما نباشد رسم نخواهد کرد . براي متوقف کردن اين امر بايستي حالت culling آنرا متوقف کنيد همچنين vertex ها را بترتيب عقربه هاي ساعت معرفي کنيد :
1 - World Matrix : اين ماتريس براي نگهداري تمام vertex هايي که براي رندر فرستاده مي شوند بکار مي رود . مقادير موجود در اين ماتريس ، موقعيت يک vertex را مي تواند تغيير دهد . يکي از کاربردهاي آن انجام دورانrotation ، انتقال transmittion و تغییر اندازه scaling است .
برای ساخت اين ماتريس از دستور زير استفاده می کنيم :
D3DXMatrixIdentify matworld
حال اين ماتريس را براي device مربوطه تاييد مي کنيم :
D3DDevice.SetTransform D3DTS_WORLD,matworld
۲ - View Matrix : اين ماتريس را بعنوان يک دوربين در نظر بگيريد که بوسيله يک نقطه شروع و يک نقطه پاياني مشخص مي شود ( مشابه يک up vector که معمولاً در طول محور y رو به بالاست ) :
تابع MakeV که در اينجا استفاده شده بصورت زير است :
Private Function MakeV(x As Single, y As Single, z As Single) As D3DVECTOR
MakeV.x = x
MakeV.y = y
MakeV.z = z
End Function
۳ - Projection Matrix : اين ماتريس مشخص مي کند چه منطقه اي از فضاي جهاني براي رندر کردن visible باشد . همچنين مشخص مي کند چه مقدار مي توانيم بطور افقي ببينيم ( زاويه ديد بزرگتر منجر به ديد بزرگتر مي شود ) :
D3DXMatrixPerspectiveFovLH matProj, pi / 4, 1, 0.1, 500
در دستور فوق از زاويه ديد pi/4 راديان استفاده شده همچنين نسبت 1:1 استفاده شده است . قسمتهاي سوم و چهارم مشخص مي کنند فقط مثلثهايي کشيده شوند که با ابعاد بزرگتر از يکدهم دوربين و کوچکتر از ۵۰۰ برابر دوربين هستند .
حال دستور اختصاص به device را خواهيم داشت :
D3DDevice.SetTransform D3DTS_PROJECTION, matProj
عد از تعريف ماتريسها بايستي تابع InitializeGeometry را صدا کنيم . در اين تابع از يک ثابت با نام DFC استفاده شده است . اگر DFC=1 باشد مکعب بطور کامل کشيده مي شود و اگر بزرگتر از يک باشد ، face هاي آن جدا از هم ديده خواهند شد . همچنين توجه کنيد که از بافرهاي vertex براي ذخيره داده vertex ها استفاده شده است . ساختار اين تابع بصورت زير خواهد بود :
۱ - پر کردن ساختارهاي vertex
Public Sub Render
D3DDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET Or D3DCLEAR_ZBUFFER, 0, 1#, 0 '//Clear the screen black
D3DDevice.BeginScene
D3DDevice.SetStreamSource 0, VBuffer, Len(Cube(0))x
D3DDevice.DrawPrimitive D3DPT_TRIANGLELIST, 0, 12
D3DDevice.EndScene
D3DDevice.Present ByVal 0, ByVal 0, 0, ByVal 0
End Sub
ساختار اصلي برنامه بصورت زير خواهد بود :
im RotateAngle As Single
Dim matTemp As D3DMATRIX '//To hold temporary
call Initialize
Do While bRunning
RotateAngle = RotateAngle + 0.1
If RotateAngle >= 360 Then RotateAngle = RotateAngle - 360
D3DXMatrixIdentity matWorld '//Reset our world matrix
D3DXMatrixIdentity matTemp
D3DXMatrixRotationX matTemp, RotateAngle * (pi / 180) x
D3DXMatrixMultiply matWorld, matWorld, matTemp
D3DXMatrixIdentity matTemp
D3DXMatrixRotationZ matTemp, RotateAngle * (pi / 180) x
D3DXMatrixMultiply matWorld, matWorld, matTemp
D3DDevice.SetTransform D3DTS_WORLD, matWorld
Render
DoEvents
Loop
Security
02-02-07, 12:27
آموزشDirectX-Graphic (قسمت هشتم)
موضوع : نورپردازي و اختصاص بافت به اشيا سه بعدي
در اين درس مي خواهيم به مکعب درس قبل بافت اختصاص داده و نيز آنرا با يک منبع نور ، نورپردازي کنيم .
ابتدا تايپ vertex ها را بصورت زير تعريف مي کنيم :
Private Type UnlitVertex
X As Single
Y As Single
Z As Single
nx As Single
ny As Single
nz As Single
tu As Single
tv As Single
End Type
توصيفگر اين فرمت بصورت زير خواهد بود :
Const Unlit_FVF = (D3DFVF_XYZ Or D3DFVF_NORMAL Or D3DFVF_TEX1
همچنين مکعب ما توسط ارايه زير مشخص مي شود :
Dim Cube2(35) As UnlitVertex
دو ثابت pi و rad را نيز بصورت زير تعريف مي کنيم :
Const pi As Single = 3.141592
Const Rad = pi / 180
براي اختصاص بافت به مکعب ، از شي Direct3DTexture8 استفاده مي شود :
Dim CubeTexture As Direct3DTexture8
براي نورپردازي ، از شي D3DLIGHT8 استفاده مي شود :
Dim Lights As D3DLIGHT8
تغييرات مورد نياز در تابع Initialize
بعد از ساخت شي D3DDevice در اين تابع ، پارامترهاي آنرا بصورت زير تنظيم مي کنيم :
مقدار ambient يک کد هگزا RRGGBB است .
بعد از دستورات فوق ماتريسهاي matworld ، matview و matproj مطابق مطابل درس قبل تعريف مي شوند . پس از آن بايستي بافت مکعب را از درون فايل تصويري مورد نظرتان load کنيد :
در دستورات فوق تابعي با نام GenerateTraingleNormals استفاده شده است . اين تابع دو بردار را از روي سه vertex داده شده با آن مي سازد و سپس ضرب برداري ايندو را حساب مي کند و سپس بردار حاصله را نرمال مي نمايد :
Private Function GenerateTriangleNormals(p0 As UnlitVertex, p1 As UnlitVertex, p2 As UnlitVertex) As D3DVECTOR
Dim v01 As D3DVECTOR 'Vector from points 0 to 1
Dim v02 As D3DVECTOR 'Vector from points 0 to 2
Dim vNorm As D3DVECTOR 'The final vector
'Create the vectors from points 0 to 1 and 0 to 2
D3DXVec3Subtract v01, MakeVector(p1.X, p1.Y, p1.Z), MakeVector(p0.X, p0.Y, p0.Z)
D3DXVec3Subtract v02, MakeVector(p2.X, p2.Y, p2.Z), MakeVector(p0.X, p0.Y, p0.Z)
'Get the cross product
D3DXVec3Cross vNorm, v01, v02
'Normalize this vector
D3DXVec3Normalize vNorm, vNorm
'Return the value
GenerateTriangleNormals.X = vNorm.X
GenerateTriangleNormals.Y = vNorm.Y
GenerateTriangleNormals.Z = vNorm.Z
End Function
حال به توضيح تابع SetupLights مي پردازيم . در اين تابع دو شي D3DMATERIAL8 و D3DCOLORVALUE استفاده شده است :
Private Function SetupLights() As Boolean
Dim Mtrl As D3DMATERIAL8, Col As D3DCOLORVALUE
Col.a = 1: Col.r = 1: Col.g = 1: Col.b = 1
Mtrl.Ambient = Col
Mtrl.diffuse = Col
D3DDevice.SetMaterial Mtrl
در متد D3DDevice.LightEnable پارامتر اول شماره منبع نور و پارمتر دوم enable بودن آنرا نشان مي دهد .
Security
02-02-07, 12:42
آموزش DirectX-Graphic (قسمت نهم)
موضوع :ترسيم متن دو بعدي در 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 را مي آوريم :
براي رندر متن با فونت 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 هاي مورد نياز براي رسم کاراکتر را توليد کنيم :
D3DDevice.SetTexture 0, fntTex
D3DDevice.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, vertChar(0), Len(vertChar(0))x
Next I
End Sub
Security
02-02-07, 14:56
آموزشDirectX-Graphic (قسمت دهم)
موضوع : ترسيم اشيا سه بعدي با استفاده از شي Mesh
شي Mesh که جزو اشيا D3DX مي باشد امکان ترسيم اشيا سه بعدي پايه و همچنين ترسيم مش هاي custom دلخواه را به شما مي دهد . در اين درس از شي Mesh براي ترسيم يک کره ( sphere ) استفاده مي کنيم . ابتدا متغير sphere را بصورت زير تعريف کنيد :
Dim sphere as D3DXMesh
همچنين براي نورپردازي و اختصاص material به کره به متغيرهاي زير نياز داريم :
Dim d3dLight As D3DLIGHT8
Dim material As D3DMATERIAL8
Dim Col As D3DCOLORVALUE
در تابع Initial پس از ساخت اشيا D3D و D3DX و D3DDevice بايستي پارامترهاي رنگ ، نورپردازي و اختصاص ماده ( material ) به کره را بصورت زير تنظيم کنيد :
نورپردازي از نوع جهت دار با رنگ col و بردار جهت (1-,1-,1-) است .
نکته :
رنگ ambient رنگي است که هنگاميکه جسم در سايه باشد به خود مي گيرد . بعبارت ديگر اين رنگ را جسم وقتي که در معرض يک نور ambient باشد از خود منعکس مي کند .
رنگ diffuse رنگي است که هنگاميکه جسم در معرض نور مستقيم قرار بگيرد از خود منعکس مي کند .
material.Ambient = Col
material.diffuse = Col
d3dDevice.SetMaterial material
d3dDevice.SetLight 0, d3dLight
d3dDevice.LightEnable 0, 1
Set Sphere = d3dx.CreateSphere(d3dDevice, 2, 1000, 20, Nothing)x
که ۲ شعاع کره و ۱۰۰۰ تعداد slice هايي است که کره با آن ساخته مي شود .
سپس بردارهاي نقطه ديد و مکان دوربين و رنگ زمينه را تنظيم کنيد ( viewpoint و camerapoint از نوع D3DVECTOR هستند ) .