...I was asked "Why do you use RHW? What's that?"
I've choosen to use transformed vertices because of their simplicity.
Anyway, here's the same example, this time slightly adjusted to show
how to setup the needed matrices in order to display the triangle in
model space.
(BTW: rhw = reciprocal of homogeneous W)
Code: Select all
XIncludeFile "include/dx8.h.pb"
#PI = 3.14159265
Structure VECTOR3
x.f
y.f
z.f
EndStructure
Structure MATRIX
_11.f : _12.f : _13.f : _14.f
_21.f : _22.f : _23.f : _24.f
_31.f : _32.f : _33.f : _34.f
_41.f : _42.f : _43.f : _44.f
EndStructure
;----------------------------------------------------------------------
; vector math
; normalize
Procedure VectorNormalize(*v.VECTOR3)
len.f = 1/Sqr(*v\x * *v\x + *v\y * *v\y + *v\z * *v\z)
*v\x * len : *v\y * len : *v\z * len
ProcedureReturn *v
EndProcedure
; dotproduct
Procedure.f VectorDot(*v1.VECTOR3, *v2.VECTOR3)
ProcedureReturn *v1\x * *v2\x + *v1\y * *v2\y + *v1\z * *v2\z
EndProcedure
; crossproduct
Procedure VectorCross(*out.VECTOR3, *v1.VECTOR3, *v2.VECTOR3)
*out\x = (*v1\y * *v2\z) - (*v1\z * *v2\y)
*out\y = (*v1\z * *v2\x) - (*v1\x * *v2\z)
*out\z = (*v1\x * *v2\y) - (*v1\y * *v2\x)
ProcedureReturn *out
EndProcedure
; subtraction
Procedure VectorSubstract(*out.VECTOR3, *a.VECTOR3, *b.VECTOR3)
*out\x = *a\x - *b\x
*out\y = *a\y - *b\y
*out\z = *a\z - *b\z
ProcedureReturn *out
EndProcedure
; matrix math (look ma! no d3dx needed! ;))
;
; Builds a left-handed perspective projection matrix
;
Procedure MatrixLookAtLH(*out.MATRIX, *eye.VECTOR3, *at.VECTOR3, *up.VECTOR3)
; zaxis = normal(At - Eye)
VectorSubstract(zaxis.VECTOR3, *at, *eye)
VectorNormalize(zaxis.VECTOR3)
; xaxis = normal(cross(Up, zaxis))
VectorCross(xaxis.VECTOR3, *up, zaxis)
VectorNormalize(xaxis)
; yaxis = cross(zaxis, xaxis)
VectorCross(yaxis.VECTOR3, zaxis, xaxis)
xdot.f = VectorDot(xaxis, *eye)
ydot.f = VectorDot(yaxis, *eye)
zdot.f = VectorDot(zaxis, *eye)
*out\_11 = xaxis\x : *out\_12 = yaxis\x : *out\_13 = zaxis\x : *out\_14 = 0.0
*out\_21 = xaxis\y : *out\_22 = yaxis\y : *out\_23 = zaxis\y : *out\_24 = 0.0
*out\_31 = xaxis\z : *out\_32 = yaxis\z : *out\_33 = zaxis\z : *out\_34 = 0.0
*out\_41 = -xdot : *out\_42 = -ydot : *out\_43 = -zdot : *out\_44 = 1.0
ProcedureReturn *out
EndProcedure
;
; Builds a left-handed perspective projection matrix based on a field of view (FOV).
;
Procedure MatrixPerspectiveFovLH(*out.MATRIX, fov.f, aspect.f, zn.f, zf.f)
h.f = Cos(fov/2) / Sin(fov/2)
w.f= h / aspect
*out\_11 = 2*zn/w : *out\_12 = 0.0 : *out\_13 = 0.0 : *out\_14 = 0.0
*out\_21 = 0.0 : *out\_22 = 2*zn/h : *out\_23 = 0.0 : *out\_24 = 0.0
*out\_31 = 0.0 : *out\_32 = 0.0 : *out\_33 = zf/(zf-zn) : *out\_34 = 1.0
*out\_41 = 0.0 : *out\_42 = 0.0 : *out\_43 = zn*zf/(zn-zf) : *out\_44 = 0.0
ProcedureReturn *out
EndProcedure
;
; Builds a matrix using the specified offsets.
;
Procedure MatrixTranslation(*out.MATRIX, x.f, y.f, z.f)
*out\_11 = 1.0 : *out\_12 = 0.0 : *out\_13 = 0.0 : *out\_14 = 0.0
*out\_21 = 0.0 : *out\_22 = 1.0 : *out\_23 = 0.0 : *out\_24 = 0.0
*out\_31 = 0.0 : *out\_32 = 0.0 : *out\_33 = 1.0 : *out\_34 = 0.0
*out\_41 = x : *out\_42 = y : *out\_43 = z : *out\_44 = 1.0
ProcedureReturn *out
EndProcedure
;----------------------------------------------------------------------
Structure MYVERTEX
x.f : y.f : z.f
color.l
EndStructure
#D3DFVF_MYVERTEX = #D3DFVF_XYZ | #D3DFVF_DIFFUSE
Dim Vertices.MYVERTEX(2)
Vertices(0)\x = 0.0 : Vertices(0)\y = 1.0 : Vertices(0)\z = 0.0 : Vertices(0)\color = $ffff0000
Vertices(1)\x = 1.0 : Vertices(1)\y = -1.0 : Vertices(1)\z = 0.0 : Vertices(1)\color = $ff00ff00
Vertices(2)\x = -1.0 : Vertices(2)\y = -1.0 : Vertices(2)\z = 0.0 : Vertices(2)\color = $ff00ffff
;
; INIT Direct3D8, setup and fill vertexbuffer
;
Procedure D3D8_Init(hWnd.l)
Shared d3d.IDirect3D8, d3dDevice.IDirect3DDevice8
If OpenLibrary(0, "d3d8.dll")
*F = IsFunction(0, "Direct3DCreate8")
If *F
d3d = CallFunctionFast(*F, #D3D_SDK_VERSION)
EndIf
d3ddm.D3DDISPLAYMODE
If d3d\GetAdapterDisplayMode(#D3DADAPTER_DEFAULT, @d3ddm) <> #D3D_OK
Debug "ERR @ GetAdapterDisplayMode"
CloseLibrary(0)
ProcedureReturn #False
EndIf
d3dpp.D3DPRESENT_PARAMETERS
ZeroMemory_( @d3dpp, SizeOf(d3dpp) )
d3dpp\Windowed = #True
d3dpp\SwapEffect = #D3DSWAPEFFECT_DISCARD
d3dpp\BackBufferFormat = d3ddm\Format
If d3d\CreateDevice( #D3DADAPTER_DEFAULT, #D3DDEVTYPE_HAL, hWnd, #D3DCREATE_SOFTWARE_VERTEXPROCESSING, @d3dpp, @d3dDevice ) <> #D3D_OK
Debug "ERR @ CreateDevice"
CloseLibrary(0)
ProcedureReturn #False
EndIf
;
Shared VB.IDirect3DVertexBuffer8
If d3dDevice\CreateVertexBuffer(3*SizeOf(MYVERTEX), #D3DUSAGE_WRITEONLY, #D3DFVF_MYVERTEX, #D3DPOOL_MANAGED, @VB) <> #D3D_OK
Debug "ERR @ CreateVertexBuffer"
CloseLibrary(0)
ProcedureReturn #False
EndIf
*pVertices.b
If VB\Lock(0, SizeOf(MYVERTEX)*3, @*pVertices, 0) <> #D3D_OK
Debug "ERR @ Lock"
CloseLibrary(0)
ProcedureReturn #False
EndIf
CopyMemory(Vertices(0), *pVertices, SizeOf(MYVERTEX)*3)
VB\Unlock()
ProcedureReturn #True
Else
Debug "ERR opening d3d8.dll"
ProcedureReturn #False
EndIf
EndProcedure
;
; CLEANUP
;
Procedure D3D8_Close()
Shared d3d.IDirect3D8, d3dDevice.IDirect3DDevice8
If d3dDevice <> #Null
d3dDevice\Release()
d3dDevice = #Null
EndIf
If d3d <> #Null
d3d\Release()
d3d = #Null
EndIf
CloseLibrary(0)
EndProcedure
;
; MAIN
;
D3D8_Init(OpenWindow(0, 0, 0, 640, 480, #PB_Window_SystemMenu, "Direct3D8"))
d3dDevice\SetRenderState(#D3DRS_LIGHTING, #False)
; setup view- and procection-matrix
eye.VECTOR3 : eye\z = -1.5
up.VECTOR3 : up\y = 1.0
MatrixLookAtLH(@view_matrix.MATRIX, @eye, @at.VECTOR3, @up)
d3dDevice\SetTransform(#D3DTS_VIEW, @view_matrix)
MatrixPerspectiveFovLH(@matProj.MATRIX, #PI/4, 640/480, 1.0, 100.0)
d3dDevice\SetTransform(#D3DTS_PROJECTION, @matProj)
; Set world-matrix
MatrixTranslation(@matWorld.MATRIX, 0.0, 0.0, 0.0)
d3dDevice\SetTransform(#D3DTS_WORLD, @matWorld)
Repeat
d3dDevice\Clear(0, #Null, #D3DCLEAR_TARGET, $FF000040, 1.0, 0)
d3dDevice\BeginScene()
d3dDevice\SetStreamSource(0, VB, SizeOf(MYVERTEX))
d3dDevice\SetVertexShader(#D3DFVF_MYVERTEX)
d3dDevice\DrawPrimitive(#D3DPT_TRIANGLELIST, 0, 1)
d3dDevice\EndScene()
d3dDevice\Present(#Null, #Null, #Null, #Null)
Until WaitWindowEvent() = #PB_Event_CloseWindow
D3D8_Close()
End
...and just in case someone thinks I'm drunk and talking to myself:
The mentionend questions arrive via PM yet I thought it's nice post
the answers publically for everyone to see.