home *** CD-ROM | disk | FTP | other *** search
/ Microsoft DirectX SDK 7.0 / Dx7.bin / DXF / samples / multimedia / vbsamples / d3dim / src / tutorials / drawprims / drawprims.frm (.txt) next >
Encoding:
Visual Basic Form  |  1999-06-23  |  18.7 KB  |  431 lines

  1. VERSION 5.00
  2. Begin VB.Form Form1 
  3.    BorderStyle     =   1  'Fixed Single
  4.    Caption         =   "DrawPrimsVB"
  5.    ClientHeight    =   3195
  6.    ClientLeft      =   90
  7.    ClientTop       =   660
  8.    ClientWidth     =   3720
  9.    LinkTopic       =   "Form1"
  10.    MaxButton       =   0   'False
  11.    MinButton       =   0   'False
  12.    ScaleHeight     =   213
  13.    ScaleMode       =   0  'User
  14.    ScaleWidth      =   254
  15.    StartUpPosition =   3  'Windows Default
  16. Attribute VB_Name = "Form1"
  17. Attribute VB_GlobalNameSpace = False
  18. Attribute VB_Creatable = False
  19. Attribute VB_PredeclaredId = True
  20. Attribute VB_Exposed = False
  21. Option Explicit
  22. Const pi As Single = 3.141592
  23. Const NUM_OBJECTS As Integer = 4
  24. ' Define the walls.
  25. Const NUM_WALL_SIDES As Integer = 6
  26. Const NUM_WALL_VERTICES = 2 * NUM_WALL_SIDES
  27. Dim g_vWall(NUM_WALL_VERTICES + 4) As D3DVERTEX
  28. ' Define the cone.
  29. Private Type MyFlexibleVertex
  30.     vPosition As D3DVECTOR
  31.     vNormal As D3DVECTOR
  32. End Type
  33. Const CONE_HEIGHT As Single = 3#
  34. Const CONE_RADIUS As Single = 1#
  35. Const NUM_CONE_SIDES As Integer = 20
  36. Const NUM_CONE_VERTICES = NUM_CONE_SIDES + 1
  37. Dim g_vCone(NUM_CONE_VERTICES) As MyFlexibleVertex
  38. ' Define the cube.
  39. Const NUM_CUBE_VERTICES As Integer = 8
  40. Const NUM_CUBE_INDICES As Integer = 6 * 3 * 2
  41. Dim g_vCube(NUM_CUBE_VERTICES) As D3DTLVERTEX
  42. Dim g_nCubeIndices(NUM_CUBE_INDICES) As Integer
  43. Dim g_dx As New DirectX7
  44. Dim g_dd As DirectDraw7
  45. Dim g_ddsd As DDSURFACEDESC2
  46. Dim g_ddsPrimary As DirectDrawSurface7, _
  47.     g_ddsBackBuffer As DirectDrawSurface7, _
  48.     g_ddsZBuffer As DirectDrawSurface7
  49. Dim g_d3d As Direct3D7
  50. Dim g_d3dDevice As Direct3DDevice7
  51. Dim g_TriangleVert(5) As D3DVERTEX
  52. Dim g_rcDest As RECT, _
  53.     g_rcSrc As RECT
  54. Dim g_d3drcViewport(0) As D3DRECT
  55. Dim g_matLocal(NUM_OBJECTS) As D3DMATRIX
  56. Dim g_bRunning As Boolean
  57. Private Sub Form_Load()
  58.     Dim CNT As Single
  59.     Dim j As Long
  60.     ' Initialize the DirectDraw and Direct3D objects that this
  61.     ' sample application will use to render and display the triangle.
  62.     InitDDraw
  63.     InitD3D
  64.     InitGeometry
  65.     Me.Show
  66.     g_bRunning = True
  67.     Do While g_bRunning = True
  68.         CNT = CNT + 1
  69.         RenderScene
  70.         FrameMove (CNT / 360)
  71.         
  72.         g_dx.GetWindowRect Me.hWnd, g_rcDest
  73.         j = g_ddsPrimary.Blt(g_rcDest, g_ddsBackBuffer, g_rcSrc, DDBLT_WAIT)
  74.         If j <> DD_OK Then
  75.             MsgBox "Couldn't copy the source rectangle to the destination surface." & Chr$(13) & Hex(j)
  76.             End
  77.         End If
  78.         DoEvents
  79.     Loop
  80. End Sub
  81. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  82. '   Animate the scene.
  83. '   Called once per frame, the call is used for animating the scene. The device is
  84. '   used for changing various render states, and the stepVal parameter is used for
  85. '   the timing of the dynamics of the scene.
  86. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  87. Private Sub FrameMove(stepVal As Single)
  88.     ' Move the viewpoint around in a circle. The view is most conveniently defined by an
  89.     ' eye point, a lookat point, and a vector defining the up direction.
  90.     Dim vEyePt As D3DVECTOR, _
  91.         vLookatPt As D3DVECTOR, _
  92.         vUpVec As D3DVECTOR
  93.         
  94.     vEyePt = MakeVector(5 * Sin(stepVal), 3, 5 * Cos(stepVal))
  95.     vLookatPt = MakeVector(4 * Sin(stepVal + 0.1), 2.5, 4 * Cos(stepVal + 0.1))
  96.     vUpVec = MakeVector(0, 1, 0)
  97.     ' Use the above parameters to build a new view matrix and put it into effect.
  98.     Dim matView As D3DMATRIX
  99.     Call g_dx.ViewMatrix(matView, vEyePt, vLookatPt, vUpVec, stepVal / 360)
  100.                               
  101.     g_d3dDevice.SetTransform D3DTRANSFORMSTATE_VIEW, matView
  102.         
  103.    ' For TLVERTEX-type vertices, the application needs to do it's own transform and
  104.    ' lighting. That will be done here, after the matrices are set up. This tutorial uses
  105.    ' D3DTLVERTEX types to draw a cube. We start with untransformed vertices for the cube,
  106.    ' manually transform them, and then render them as normal during the render loop.
  107.       
  108.    ' Fill the array of TL vertices with untransformed data for the cube.
  109.     g_dx.CreateD3DTLVertex -1, -1, -1, 0, &HFFFFFF, 0, 0, 0, g_vCube(0)
  110.     g_dx.CreateD3DTLVertex 1, -1, -1, 0, &HFF&, 0, 0, 0, g_vCube(1)
  111.     g_dx.CreateD3DTLVertex -1, 1, -1, 0, &HFF00&, 0, 0, 0, g_vCube(2)
  112.     g_dx.CreateD3DTLVertex 1, 1, -1, 0, &HFF0000, 0, 0, 0, g_vCube(3)
  113.     g_dx.CreateD3DTLVertex -1, -1, 1, 0, &HFFFF&, 0, 0, 0, g_vCube(4)
  114.     g_dx.CreateD3DTLVertex 1, -1, 1, 0, &HFF0066, 0, 0, 0, g_vCube(5)
  115.     g_dx.CreateD3DTLVertex -1, 1, 1, 0, &H9966FF, 0, 0, 0, g_vCube(6)
  116.     g_dx.CreateD3DTLVertex 1, 1, 1, 0, &HFF00FF, 0, 0, 0, g_vCube(7)
  117.     ' Let the application transform the cube's 8 vertices.
  118.     Call TransformVertices(g_d3dDevice, g_vCube, NUM_CUBE_VERTICES)
  119.       
  120. End Sub
  121. ''''''''''''''''''''''''''''''''''''''''''''''''''''''
  122. ' Render the scene
  123. ''''''''''''''''''''''''''''''''''''''''''''''''''''''
  124. Private Sub RenderScene()
  125.     Dim i As Integer
  126.           
  127.     ' Clear the viewport to a blue color, and clear the z-buffer.
  128.     g_d3dDevice.Clear 1, g_d3drcViewport(), D3DCLEAR_TARGET Or D3DCLEAR_ZBUFFER, &HFF, 1, 0
  129.     ' Begin the scene.
  130.     g_d3dDevice.BeginScene
  131.     ' Draw the wall, composed of a D3DVERTEX-type triangle strip.
  132.     Call g_d3dDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX, g_vWall(0), _
  133.          NUM_WALL_VERTICES, D3DDP_DEFAULT)
  134.                                    
  135.     ' Draw the cone, which is a triangle fan of custom, flexible vertices.
  136.     Call g_d3dDevice.DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZ Or D3DFVF_NORMAL, g_vCone(0), _
  137.          NUM_CONE_VERTICES, D3DDP_DEFAULT)
  138.          
  139.     ' Draw the cube, which is application transformed (and lit), indexed vertices.
  140.     Call g_d3dDevice.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX, g_vCube(0), _
  141.          NUM_CUBE_VERTICES, g_nCubeIndices, NUM_CUBE_INDICES, D3DDP_DEFAULT)
  142.     ' End the scene.
  143.     g_d3dDevice.EndScene
  144. End Sub
  145. Private Sub Form_Unload(Cancel As Integer)
  146.     g_bRunning = False
  147. End Sub
  148. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  149. ' Initalize DirectDraw.
  150. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  151. Private Sub InitDDraw()
  152.     ' Create the DirectDraw object and set the application
  153.     ' cooperative level.
  154.     Set g_dd = g_dx.DirectDrawCreate("")
  155.     g_dd.SetCooperativeLevel Me.hWnd, DDSCL_NORMAL
  156.     ' Prepare and create the primary surface.
  157.     g_ddsd.lFlags = DDSD_CAPS
  158.     g_ddsd.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE
  159.     Set g_ddsPrimary = g_dd.CreateSurface(g_ddsd)
  160.     ' Now create the render-target surface. We are reusing g_ddsd here.
  161.     g_ddsd.lFlags = DDSD_HEIGHT Or DDSD_WIDTH Or DDSD_CAPS
  162.     g_ddsd.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN Or DDSCAPS_3DDEVICE
  163.     ' Use the size of the form to determine the size of the render target
  164.     ' and viewport rectangle.
  165.     g_dx.GetWindowRect Me.hWnd, g_rcDest
  166.     ' Set the dimensions of the surface description
  167.     g_ddsd.lWidth = g_rcDest.Right - g_rcDest.Left
  168.     g_ddsd.lHeight = g_rcDest.Bottom - g_rcDest.Top
  169.     ' Create the render-target surface
  170.     Set g_ddsBackBuffer = g_dd.CreateSurface(g_ddsd)
  171.         
  172.     ' Cache the dimensions of the render target. We'll use
  173.     ' it for blitting operations.
  174.     With g_rcSrc
  175.         .Left = 0: .Top = 0
  176.         .Bottom = g_ddsd.lHeight
  177.         .Right = g_ddsd.lWidth
  178.     End With
  179.     ' Create a DirectDrawClipper and attach it to the primary surface.
  180.     Dim pcClipper As DirectDrawClipper
  181.     Set pcClipper = g_dd.CreateClipper(0)
  182.     pcClipper.SetHWnd Me.hWnd
  183.     g_ddsPrimary.SetClipper pcClipper
  184.     '
  185.     ' Create the z-buffer after creating the backbuffer and before creating the
  186.     ' Direct3D device. Note: before creating the z-buffer, applications may want to check
  187.     ' the device capabilities for the D3DPRASTERCAPS_ZBUFFERLESSHSR flag. This flag is true
  188.     ' for certain hardware that can do HSR (hidden-surface removal) without a z-buffer.
  189.     ' For those devices, there is no need to create a z-buffer.
  190.     '
  191.     Dim ddpfZBuffer As DDPIXELFORMAT
  192.     Dim d3dEnumPFs As Direct3DEnumPixelFormats
  193.         
  194.     Set g_d3d = g_dd.GetDirect3D
  195.     Set d3dEnumPFs = g_d3d.GetEnumZBufferFormats("IID_IDirect3DRGBDevice")
  196.     ' For this tutorial we are only interested in z-buffers, so ignore any other
  197.     ' formats (e.g. DDPF_STENCILBUFFER) the get enumerated. An application could also
  198.     ' check the depth fo the z-buffer (16-bit, etc. and make a choice based on that,
  199.     ' as well. For this tutorial, we'll take the first one that we get.
  200.     Dim i As Long
  201.           
  202.     For i = 1 To d3dEnumPFs.GetCount()
  203.         Call d3dEnumPFs.GetItem(i, ddpfZBuffer)
  204.         If ddpfZBuffer.lFlags = DDPF_ZBUFFER Then
  205.             Exit For
  206.         End If
  207.     Next i
  208.     ' Prepare and create the z-buffer surface.
  209.     g_ddsd.lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT Or DDSD_PIXELFORMAT
  210.     g_ddsd.ddsCaps.lCaps = DDSCAPS_ZBUFFER
  211.     g_ddsd.lWidth = g_rcDest.Right - g_rcDest.Left
  212.     g_ddsd.lHeight = g_rcDest.Bottom - g_rcDest.Top
  213.     g_ddsd.ddpfPixelFormat = ddpfZBuffer
  214.     ' Specify DDSCAPS_VIDEOMEMORY if your surface exists in display memory.
  215.     ' See the SDK documentation for more information.
  216.     g_ddsd.ddsCaps.lCaps = g_ddsd.ddsCaps.lCaps Or DDSCAPS_SYSTEMMEMORY
  217.         
  218.     Set g_ddsZBuffer = g_dd.CreateSurface(g_ddsd)
  219.     ' Attach the z-buffer surface to the back buffer surface.
  220.     g_ddsBackBuffer.AddAttachedSurface g_ddsZBuffer
  221. End Sub
  222. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  223. ' Initalize Direct3D, including the rendering device, lighting,
  224. ' the viewport, and the material.
  225. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  226. Sub InitD3D()
  227.     Dim d3d As Direct3D7
  228.     Dim ddsd As DDSURFACEDESC2
  229.         
  230.     ' Retrieve a reference to the Direct3D7 class from the
  231.     ' DirectDraw7 object.
  232.     Set d3d = g_dd.GetDirect3D
  233.     ' Query DirectDraw for the current display mode. For simplicity, this
  234.     ' does not support palleted display modes (8-bit and lower).
  235.     g_dd.GetDisplayMode ddsd
  236.     If ddsd.ddpfPixelFormat.lRGBBitCount <= 8 Then
  237.         MsgBox "This application does not support screen display " & _
  238.                "modes lower than 16-bit."
  239.         End
  240.     End If
  241.     '
  242.     ' Create the device. The GUID is hardcoded for now, but should come from
  243.     ' device enumeration, which is the topic of a future tutorial. The device
  244.     ' is created off of our back buffer, which becomes the render target for
  245.     ' the newly created device.
  246.     '
  247.     Set g_d3dDevice = d3d.CreateDevice("IID_IDirect3DRGBDevice", g_ddsBackBuffer)
  248.     ' Define the viewport rectangle.
  249.     Dim VPDesc As D3DVIEWPORT7
  250.         
  251.     VPDesc.lWidth = g_rcDest.Right - g_rcDest.Left
  252.     VPDesc.lHeight = g_rcDest.Bottom - g_rcDest.Top
  253.     VPDesc.minz = 0#
  254.     VPDesc.maxz = 1#
  255.     g_d3dDevice.SetViewport VPDesc
  256.     ' Cache the viewport rectangle for use in clearing operations later.
  257.     With g_d3drcViewport(0)
  258.         .X1 = 0: .Y1 = 0
  259.         .X2 = VPDesc.lWidth
  260.         .Y2 = VPDesc.lHeight
  261.     End With
  262.         
  263.     '
  264.     ' Prepare a material
  265.     '
  266.     Dim mtrl As D3DMATERIAL7
  267.     mtrl.diffuse.r = 1#: mtrl.diffuse.g = 1#: mtrl.diffuse.b = 1#
  268.     mtrl.Ambient.r = 1#: mtrl.Ambient.g = 1#: mtrl.Ambient.b = 1#
  269.     ' Commit the material to the device.
  270.     g_d3dDevice.SetMaterial mtrl
  271.     '
  272.     ' Set up transformation matrices.
  273.     '
  274.     ' The world matrix controls the position and orientation of the polygons
  275.     ' in world space. We'll use it later to spin the triangle.
  276.     Dim matWorld As D3DMATRIX
  277.     g_dx.IdentityMatrix matWorld
  278.     g_d3dDevice.SetTransform D3DTRANSFORMSTATE_WORLD, matWorld
  279.     ' The view matrix defines the position and orientation of the camera.
  280.     ' Here, we are just moving it back along the z-axis by 15 units.
  281.     Dim matView  As D3DMATRIX
  282.     g_dx.IdentityMatrix matView
  283.     Call g_dx.ViewMatrix(matView, MakeVector(0, 0, -10), MakeVector(0, 0, 0), _
  284.                          MakeVector(0, 1, 0), 0)
  285.     g_d3dDevice.SetTransform D3DTRANSFORMSTATE_VIEW, matView
  286.     ' The projection matrix defines how the 3D scene is "projected" onto the
  287.     ' 2D render target (the backbuffer surface). Refer to the docs for more
  288.     ' info about projection matrices.
  289.     Dim matProj As D3DMATRIX
  290.     g_dx.IdentityMatrix matProj
  291.     Call g_dx.ProjectionMatrix(matProj, 1, 1000, pi / 3#)
  292.     g_d3dDevice.SetTransform D3DTRANSFORMSTATE_PROJECTION, matProj
  293.     ' Enable z-buffering for the application.
  294.     g_d3dDevice.SetRenderState D3DRENDERSTATE_ZENABLE, D3DZB_TRUE
  295.     'Set up the light.
  296.     Dim light As D3DLIGHT7
  297.     light.dltType = D3DLIGHT_POINT
  298.     light.diffuse.r = 1#
  299.     light.diffuse.g = 1#
  300.     light.diffuse.b = 1#
  301.     light.position.x = light.direction.x = 5#
  302.     light.position.y = light.direction.y = 5#
  303.     light.position.z = light.direction.z = 0#
  304.     'light.range = D3DLIGHT_RANGE_MAX
  305.     light.attenuation1 = 1#
  306.     g_d3dDevice.SetLight 0, light
  307.     g_d3dDevice.LightEnable 0, True
  308.     g_d3dDevice.SetRenderState D3DRENDERSTATE_LIGHTING, True
  309. End Sub
  310. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  311. ' Initalize the geometry.
  312. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  313. Private Sub InitGeometry()
  314.     ' Set up the wall geometry.
  315.     Dim x As Double, _
  316.         y As Double, _
  317.         z As Double
  318.         
  319.     Dim i As Integer
  320.     For i = 0 To NUM_WALL_SIDES - 1
  321.         x = Sin(2 * pi * i / (NUM_WALL_SIDES - 1))
  322.         z = Cos(2 * pi * i / (NUM_WALL_SIDES - 1))
  323.         
  324.         Call g_dx.CreateD3DVertex(x * 10#, -0.1 * 10#, z * 10#, -x, 0, -z, 0, 0, g_vWall(2 * i + 0))
  325.         Call g_dx.CreateD3DVertex(x * 10#, 0.1 * 10#, z * 10#, -x, 0, -z, 0, 0, g_vWall(2 * i + 1))
  326.                 
  327.     Next i
  328.     ' Set up the cone geometry.
  329.     Dim vectorNorm As D3DVECTOR
  330.     g_vCone(0).vPosition = MakeVector(0, CONE_HEIGHT / 2, 0)
  331.         
  332.     vectorNorm = MakeVector(0, 1, 0)
  333.     Call g_dx.VectorNormalize(vectorNorm)
  334.     g_vCone(0).vNormal = vectorNorm
  335.         
  336.     For i = 0 To NUM_CONE_SIDES - 1
  337.         x = Sin(2 * pi * i / (NUM_CONE_SIDES - 1))
  338.         y = -CONE_HEIGHT / 2
  339.         z = Cos(2 * pi * i / (NUM_CONE_SIDES - 1))
  340.         
  341.         g_vCone(i + 1).vPosition = MakeVector(x * CONE_RADIUS, y * CONE_RADIUS, z * CONE_RADIUS)
  342.         
  343.         vectorNorm = MakeVector(x, 0.5, z)
  344.         Call g_dx.VectorNormalize(vectorNorm)
  345.         g_vCone(i + 1).vNormal = vectorNorm
  346.    Next i
  347.    'Set the cube indices.
  348.     g_nCubeIndices(0) = 1: g_nCubeIndices(1) = 2: g_nCubeIndices(2) = 3
  349.     g_nCubeIndices(3) = 2: g_nCubeIndices(4) = 1: g_nCubeIndices(5) = 0
  350.     g_nCubeIndices(6) = 4: g_nCubeIndices(7) = 5: g_nCubeIndices(8) = 6
  351.     g_nCubeIndices(9) = 6: g_nCubeIndices(10) = 5: g_nCubeIndices(11) = 7
  352.     g_nCubeIndices(12) = 3: g_nCubeIndices(13) = 2: g_nCubeIndices(14) = 6
  353.     g_nCubeIndices(15) = 3: g_nCubeIndices(16) = 6: g_nCubeIndices(17) = 7
  354.     g_nCubeIndices(18) = 0: g_nCubeIndices(19) = 1: g_nCubeIndices(20) = 4
  355.     g_nCubeIndices(21) = 4: g_nCubeIndices(22) = 1: g_nCubeIndices(23) = 5
  356.     g_nCubeIndices(24) = 2: g_nCubeIndices(25) = 0: g_nCubeIndices(26) = 4
  357.     g_nCubeIndices(27) = 2: g_nCubeIndices(28) = 4: g_nCubeIndices(29) = 6
  358.     g_nCubeIndices(30) = 1: g_nCubeIndices(31) = 3: g_nCubeIndices(32) = 5
  359.     g_nCubeIndices(33) = 5: g_nCubeIndices(34) = 3: g_nCubeIndices(35) = 7
  360. End Sub
  361. Private Function MakeVector(a As Double, b As Double, c As Double) As D3DVECTOR
  362.     Dim vecOut As D3DVECTOR
  363.     With vecOut
  364.         .x = a
  365.         .y = b
  366.         .z = c
  367.     End With
  368.     MakeVector = vecOut
  369. End Function
  370. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  371. ' Manually transform vertices from local 3-D space to 2-D screen coordinates.
  372. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  373. Private Sub TransformVertices(d3dDevice As Direct3DDevice7, vVertices() As D3DTLVERTEX, nNumVertices As Integer)
  374.     Dim vp As D3DVIEWPORT7
  375.     Dim nClipWidth As Integer
  376.     Dim nClipHeight As Integer
  377.         
  378.     ' Get the height and width of the viewport. This is needed to scale the transformed vertices
  379.     ' to fit the render window.
  380.     d3dDevice.GetViewport vp
  381.     nClipWidth = vp.lWidth / 2
  382.     nClipHeight = vp.lHeight / 2
  383.     ' Get the current matrix set. This is needed for the transformation.
  384.     Dim matWorld As D3DMATRIX
  385.     Dim matView As D3DMATRIX
  386.     Dim matProj As D3DMATRIX
  387.     d3dDevice.GetTransform D3DTRANSFORMSTATE_WORLD, matWorld
  388.     d3dDevice.GetTransform D3DTRANSFORMSTATE_VIEW, matView
  389.     d3dDevice.GetTransform D3DTRANSFORMSTATE_PROJECTION, matProj
  390.     Dim matSet As D3DMATRIX
  391.     g_dx.IdentityMatrix matSet
  392.      
  393.     ' Concatenate the matrices using the right-to-left rule.
  394.     g_dx.MatrixMultiply matSet, matWorld, matView
  395.     g_dx.MatrixMultiply matSet, matSet, matProj
  396.     Dim i As Integer
  397.     Dim xp As Single
  398.     Dim yp As Single
  399.     Dim zp As Single
  400.     Dim wp As Single
  401.     Dim x As Double
  402.     Dim y As Double
  403.     Dim z As Double
  404.       
  405.     ' Transform each vertex through the current matrix set.
  406.     For i = 0 To nNumVertices - 1
  407.         ' Get the untransformed vertex position.
  408.         x = vVertices(i).sx
  409.         y = vVertices(i).sy
  410.         z = vVertices(i).sz
  411.         
  412.        ' Transform the vertex position through the current matrix set.
  413.         xp = matSet.rc11 * x + matSet.rc21 * y + matSet.rc31 * z + matSet.rc41
  414.         yp = matSet.rc12 * x + matSet.rc22 * y + matSet.rc32 * z + matSet.rc42
  415.         zp = matSet.rc13 * x + matSet.rc23 * y + matSet.rc33 * z + matSet.rc43
  416.         wp = matSet.rc14 * x + matSet.rc24 * y + matSet.rc34 * z + matSet.rc44
  417.         
  418.         ' Finally, scale the vertices to screen coordinates. This first step "flattens"
  419.         ' the coordinates from 3-D space to 2-D device coordinates, by dividing each
  420.         ' coordinate by the wp value. Then, the x- and y-componenets are transformed from
  421.         ' device coordinates to screen coordinates.
  422.         ' Note 1: device coords range from -1 to +1 in the viewport
  423.         ' Note 2: the sz-coordinate will be used in the z-buffer
  424.         vVertices(i).sx = (1# + (xp / wp)) * nClipWidth
  425.         vVertices(i).sy = (1# - (yp / wp)) * nClipHeight
  426.         vVertices(i).sz = zp / wp
  427.         vVertices(i).rhw = wp
  428.    Next i
  429.                   
  430. End Sub
  431.