Direct3D For Dummiez (In VB6)


Well, don't take this title offensive. If you were smart enough to DL this tutorial, your not a dummy!

This simple tutorial will teach you how to use Direct3D and how to make games in it. If you like this, please vote for me! 

Chapter 1: About DirectX & Direct3D
Ok, well be using Direct3D 7 because it's near the top of the line, but easier to use than DX8. Once you learn DX7, you can move up to DX8, which won't be very hard.

DirectX-
Collection of Direct3D, DirectDraw, DirectInput, DirectSound, DirectMusic, Direct whatever else there is...

Direct Draw- Library of drawing functions made generally for drawing stuff on your screen. (Duh...)

Direct3D-  Direct3D is built on DirectDraw, and it provides many 3D drawing functions and all sorts of good stuff like that.

DirectInput: Allows your games to use the keyboard, mouse, force-feedback joy sticks, normal joy-sticks, control pads, steering wheels, and almost everything else. 

DirectSound: Plays sound in 2d stereo, 2d mono, or 3D Stereo. Also provides effects that work with D3D (Like the Doppler effect)

Direct3D Has 2 modes. IM (immediate Mode) which is faster, but every triangle/polygon has to be hard-coded into the program,  and RM (Retained Mode) The upper end to IM, allows you to load objects directly from the hard drive. MM (Mixed-Mode) doesn't exist, but Microsoft is considering to make one which will mix the two modes, to make games more flexible.

FYI, a Direct3D Game code would look roughly something like this:
 
Declare your variables and DirectX Objects
 
Form_Load()
   Initiate DirectX (DirectDraw and Direct3D, screen size, render quality, ext...)
   Create Objects (Load your objects from files, set where they go, ext...)
   Run Main game loop (Checks for user input, draws graphics, ext...)
   Computer Possession Code (Your computer becomes possessed and rampages through your house because it likes 
   your awesome direct3D game too much.) 
 
End Sub

A More detailed example of what a D3D Code would look like:

'Declare all the variables, DirectX Objects, frames, and stuff in this general declarations area... 

Private Sub Form_Load()
 DoEvents           
'Let the computer have time to do what it needs to do...
 DX_Init              
'Initialize DirectDraw and Direct3D
 DX_MakeObjects 
'Load the lights and objects
 DX_Render         
'Start the main loop
End Sub

Private Sub
DX_Init()
 
'Initialize DirectDraw and Direct3D
 'Also, set how big the drawing area is, background color, fog, and all that good stuff.
End Sub

Private Sub
DX_MakeObjects()
 
'Make the frames (Each object is put in a frame. There is the root frame, where everything else is placed under
 'it in a tree hierarchy. 
 'Make the 'MainFrame' frame
 'Make the 'LightFrame' frame and make it link to 'MainFrame'
 'Make the 'Camera' Frame and make it link to 'MainFrame'
 'Make the 'FirstObject' frame and make it link to 'MainFrame'
 'Note: Call your frames what ever you want.
 'Set your Camera Frame and set it as a viewport (which is where you see the images, like a camera)
 'Now, set up the main (
Ambient) light, and maybe a 'point' light (to make it more realistic)
 'Load your object from a file and add it to it's frame ('FirstObject' in this case) 
End Sub

Private Sub
DX_Render()
 Do
   DoEvents 
    'Give the computer time to do what it needs to do.
  
DX_Input     'Call the DirectInput sub, to check for keys pressed (like left, right, up, down) and run code for 
                    'them. 
   'Clear the viewport (screen)
   'Update the Direct3D Device
   'Render the image on the backbuffer [render the 'MainFrame' tree]
   'Swap the back buffer with the front buffer (Images are drawn on the back buffer before they are put on the 
   'front buffer (which is the actual screen) to make the rendering more smooth with the whole image/frame 
   'appearing at once, instead of pieces appearing at a time) 
 
Loop

Private Sub DX_Input
 
'Get the DirectInput Keyboard thingy
 'Run the code and see what keys have been pressed. If for example, the left arrow key was pressed, 
 'Make the viewport/camera turn left some. 
 'If for example, escape [esc] was pressed, end the program...
End Sub 
  


Chapter 2: Setting Up DirectDraw and Direct3D
This example program let's you walk around a 3D Building. I Included with this tutorial the source code (in a vb6 project) for this program, and a little file called 'building.x' this is the mesh file used for this program. the .x extension means DirectX mesh files.


For DirectX to work with your program, you need to make some DirectX objects for DirectDraw, Direct3D, and DirectInput. First, I'll show you what needs to be declared in the 'General Declarations' Section. OK! It's time to start your first 3D Program!   First, open up Visual Basic, and make a new project. Click the 'project' menu, then click 'References...'. Add the 'DirectX7 For Visual Basic Type Library' . 
     Now, Go to the 'General Declarations' in your form1. Then, Put this next code in it. (Please read this, don't just copy and paste it. If you read it, you will understand what is happening here better ;))

'General Declarations

'These three components are the big daddy of what your 3D Program. 
Dim DX_Main As New DirectX7 ' The DirectX core file (The heart of it all)
Dim DD_Main As DirectDraw4 ' The DirectDraw Object
Dim D3D_Main As Direct3DRM3 ' The direct3D Object

'DirectInput Components
Dim DI_Main As DirectInput ' The DirectInput core 
Dim DI_Device As DirectInputDevice ' The DirectInput device
Dim DI_State As DIKEYBOARDSTATE 'Array Holding the state of the keys

'DirectDraw Surfaces- Where the screen is drawn.
Dim DS_Front As DirectDrawSurface4 ' The frontbuffer (What you see on the screen)
Dim DS_Back As DirectDrawSurface4 ' The backbuffer, (Where everything is drawn before it's put on the screen.)
Dim SD_Front As DDSURFACEDESC2 ' The SurfaceDescription
Dim DD_Back As DDSCAPS2 ' General Surface Info

'ViewPort and Direct3D Device
Dim D3D_Device as Direct3DRMDevice3 'The Main Direct3D Retained Mode Device
Dim D3D_ViewPort as Direct3DRMViewport2 'The Direct3D Retained Mode Viewport (Kinda the camera) 

'The Frames 
Dim FR_Root as Direct3DRMFrame3 'The Main Frame (The other frames are put under this one (Like a tree))
Dim FR_Camera as Direct3DRMFrame3 'Another frame, just happens to be called 'camera'. We will use this
                                                   'as the viewport. Hence, the name camera. Doesn't have to be
                                                   'called 'camera'. It could be called 'BillyBob' for all I care. 
Dim FR_Light as Direct3DRMFrame3 'This frame contains our, guess what, spotlight!
Dim FR_Building as Direct3DRMFrame3 'Frame containing our 1st mesh that will be put in this "game". 

'Meshes (3D objects loaded from a .x file)
Dim MS_Building as Direct3DRMMeshBuilder3

'Lights
Dim LT_Ambient as Direct3DRMLight 'Our Main (Ambient) light that illuminates everything (not just part of something
                                                'like a spotlight. 
Dim LT_Spot as Direct3DRMLight 'Our Spot light, makes it look more realistic. 

'Camera Positions
Dim xx As Long
Dim yy As Long
Dim zz As Long

Dim
esc As Boolean 'If Escape is pressed, the DX_Input sub will make it true and the main loop will end. 
'Incase you haven't caught on, the prefix FR = frame, MS = Mesh, & LT = light. 

Yay! You just declared your declarations! Let's Party! Oh, wait, were not done yet. 
     Now that you declared your DirectDraw, Direct3D, and DirectInput stuff, let's initialize (or is the word I'm looking for initiate?) it. (Meaning set it all up and that kind of stuff.) Now, make a sub called DX_Init.  Now, Type (Not copy and paste) this next code in. If you read it word for word, AND type it word for word, you will begin to understand it much better! (It's proven by scientist peoples that it helps) 

Private Sub DX_Init()
 
'Type, not copy and paste!
 'This sub will initialize all your components and set them up. 
 
set DD_Main = DX_Main.DirectDraw4Create("") 'Create the DirectDraw Object

 DD_Main.SetCooperativeLevel Form1.hWnd, DDSCL_FULLSCREEN Or DDSCL_EXCLUSIVE 'Set Screen Mode (Full  'Screen)
 DD_main.SetDisplayMode 640, 480, 32, 0, DDSDM_DEFAULT
'Set Resolution and BitDepth (Lets use 32-bit color)
 
 
SD_Front.lFlags = DDSD_CAPS Or DDSD_BACKBUFFERCOUNT
 SD_Front.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_3DDEVICE Or DDSCAPS_COMPLEX OR _
 DDSCAPS_FLIP
'I used the line-continuation ( _ ) because the whole thing wouldn't fit on one line...
 SD_Front.lBackBufferCount = 1 '
Make one backbuffer 
 
Set DS_Front = DD_Main.CreateSurface(SD_Front) 'Initialize the front buffer (the screen)
 'The Previous block of code just created the screen and the backbuffer. 
 
 
DD_Back.lCaps = DDSCAPS_BACKBUFFER
 
Set DS_Back = DS_Front.GetAttachedSurface(DD_Back)
 DS_Back.SetForeColor RGB(255, 255, 255)
 
'The backbuffer was initialized and the DirectDraw text color was set to white. 

 
Set D3D_Main = DX_Main.Direct3DRMCreate() 'Creates the Direct3D Retained Mode Object!!!!!

 Set D3D_Device = D3D_Main.CreateDeviceFromSurface("IID_IDirect3DHALDevice", DD_Main, DS_Back, _
 D3DRMDEVICE_DEFAULT)
'Tell the Direct3D Device that we are using hardware rendering (HALDevice) instead
                                   'of software enumeration (RGBDevice).
 
D3D_Device.SetBufferCount 2 'Set the number of buffers
 
D3D_Device.SetQuality D3DRMRENDER_GOURAUD 'Set Rendering Quality. Can use Flat, or WireFrame, but
                                                                  'GOURAUD has the best rendering quality.
 
D3D_Device.SetTextureQuality D3DRMTEXTURE_NEAREST 'Set the texture quality
 
D3D_Device.SetRenderMode D3DRMRENDERMODE_BLENDEDTRANSPARENCY 'Set the render mode.

 
Set DI_Main = DX_Main.DirectInputCreate() 'Create the DirectInput Device
 
Set DI_Device = DI_Main.CreateDevice("GUID_SysKeyboard") 'Set it to use the keyboard.
 
DI_Device.SetCommonDataFormat DIFORMAT_KEYBOARD 'Set the data format to the keyboard format.
 
DI_Device.SetCooperativeLevel Me.hWnd, DISCL_BACKGROUND Or DISCL_NONEXCLUSIVE 'Set Coperative Level.
 
DI_Device.Acquire
 
'The above block of code configures the DirectInput Device and starts it.
End Sub

Chapter 3: Let's set up our world!
OK, Now you should have all your general declarations, and a sub called 'DX_Init" with the above code in it. That's a good start, but we need to create the frames, meshes, and stuff like that, so make a new sub called 'DX_MakeObjects'. Add this next code to it. 

Private Sub DX_MakeObjects()
 
Set FR_Root = D3D_Main.CreateFrame(Nothing) 'This will be the root frame of the 'tree'
 
Set FR_Camera = D3D_Main.CreateFrame(FR_Root) 'Our Camera's Sub Frame. It goes under FR_Root in the 'Tree'.
 
Set FR_Light = D3D_Main.CreateFrame(FR_Root) 'Our Light's Sub Frame
 
Set FR_Building = D3D_Main.CreateFrame(FR_Root) 'Our Building (the 3D Thingy that will be placed in our world's) 
                                                                      ' sub frame. 
 'That above code set up the hierarchy of frames where FR_Root is the parent, and the other frames are all 
 'owned by it.
 
 
FR_Root.SetSceneBackgroundRGB 0, 0, 1 'Set the background color. Use decimals, not the standerd 255 = max.
                                                         'What I have here will make the background/sky 100% blue. 
 
FR_Camera.SetPosition Nothing, 1, 4, -35 'Set The Camera position; X=1, Y=4, z=-35. 
 
Set D3D_Viewport = D3D_Main.CreateViewport(D3D_Device, FR_Camera, 0, 0, 640, 480) 'Make our viewport and 'set 
                                                                                                                  'it our camera to be it.
 
D3D_Viewport.SetBack 200 'How far back it will draw the image. (Kinda like a visibility limit)
  
 
FR_Light.SetPosition Nothing, 0, 25, 0 'Set our 'point' light.
 
Set LT_Spot = D3D_Main.CreateLightRGB(D3DRMLIGHT_POINT, 1, 1, 1) 'Set the light type and it's color.
 
FR_Light.AddLight LT_Spot 'Add the light to it's frame.
  
 
Set LT_Ambient = D3D_Main.CreateLightRGB(D3DRMLIGHT_AMBIENT, 0.5, 0.5, 0.5) 'Create our ambient light.
 
FR_Root.AddLight LT_Ambient 'Add the ambient light to the root frame.

 
Set MS_Building = D3D_Main.CreateMeshBuilder() 'Make the 3D Building Mesh
 
MS_Building.LoadFromFile app.path & "\building.x",0 ,0 ,nothing ,nothing 'Load our building mesh from its .X file.
 
MS_Building.ScaleMesh 1, 1, 1 'Set the it's scale. This is used to make the object smaller or bigger. 1 makes
                                          'it the same size as it was built in whatever program it was built in. 
 
FR_Building.AddVisual MS_Building 'Add the 3D Building mesh to it's frame. 

End Sub  

Chapter 4: Render your masterpiece
Now, the code that you have sets up your frames, background color, lights, and your one object. To make these objects appear on the screen, we need the main loop which draws the images at a rate of 20 to 120 frames per second (FPS). Make a sub called 'DX_Render'. Put this next code in it.  

Private Sub DX_Render()
 
'Lets put our main loop. Make it loop until esc = true (I'll explain later)
 
Do While esc = False
   On local error resume next
'Incase there is an error
  
DoEvents 'Give the computer time to do what it needs to do. 
   
  
DX_Input 'Call the input sub. 
  
D3D_Viewport.Clear D3DRMCLEAR_TARGET Or D3DRMCLEAR_ZBUFFER 'Clear your viewport. 
  
D3D_Device.Update 'Update the Direct3D Device. 
  
D3D_Viewport.Render FR_Root 'Render the 3D Objects (lights, and your building!)
  
DS_Back.DrawText 200, 0, "My First Direct3D Program!", False 'Draw some text! 
  
DS_Front.Flip Nothing, DDFLIP_WAIT 'Flip the back buffer with the front buffer. 
 
Loop
End Sub

*Pant* *Pant* All *pant* most *pant* there...
Just 3 more subs to go! Now, make a sub called 'DX_Input' then add the following code:

Private Sub DX_Input()
 DI_Device.GetDeviceStateKeyboard DI_State
'Get the array of keyboard keys and their current states
  

 If
DI_State.Key(DIK_ESCAPE) <> 0 Then Call DX_Exit 'If user presses [esc] then exit end the program.
 
 
If DI_State.Key(DIK_LEFT) <> 0 Then 'Quick Note: <> means 'does not'
  
FR_Camera.SetPosition FR_Camera, -1, 0, 0 'Move the viewport to the left
 
end if
 
 If
DI_State.Key(DIK_RIGHT) <> 0 Then
  
FR_Camera.SetPosition FR_Camera, 1, 0, 0 'Move the viewport to the right
 
End If
 
 If
DI_State.Key(DIK_UP) <> 0 Then
  
FR_Camera.SetPosition FR_Camera, 0, 0, 1 'Move the viewport forward
 
End If

 If
DI_State.Key(DIK_DOWN) <> 0 then 
   FR_Camera.SetPosition FR_Camera, 0, 0, -1
'Move the viewport back
 
End If  

End Sub

Chapter 5: Finishing Touches
Now, make a sub called 'DX_Exit' This will run when the user presses escape. It unloads the DirectX objects and returns the screen resolution and stuff back to normal, then ends the program. 

Private Sub DX_Exit()
 
Call DD_Main.RestoreDisplayMode
 
Call DD_Main.SetCooperativeLevel(Me.hWnd, DDSCL_NORMAL)
 
Call DI_Device.Unacquire
 
'Restore all the devices

 
End 'Ends the program.
End Sub

Ok, What makes this program start? The next code! Put this in the 'Form_Load' sub so this all happens when the program starts:

Private Sub Form_Load()
 Me.Show
'Some computers do weird stuff if you don't show the form.
 
DoEvents 'Give the computer time to do what it needs to do
 
DX_Init 'Initialize DirectX
 
DX_MakeObjects 'Make frames, lights, and mesh(es)
 
DX_Render 'The Main Loop
 'One More Line of code after this!!!
End Sub

Congratulations! If you actually typed this, and not copy and paste this, you have written your first Direct3D program! Now, Run the program! You should be able to walk around a building using the arrow keys. To escape, just press [esc].  Incase you are a slacker, here is the complete code in one table. Click here for the next chapter-

'General Declarations

'These three components are the big daddy of what your 3D Program. 
Dim DX_Main As New DirectX7 ' The DirectX core file (The heart of it all)
Dim DD_Main As DirectDraw4 ' The DirectDraw Object
Dim D3D_Main As Direct3DRM3 ' The direct3D Object

'DirectInput Components
Dim DI_Main As DirectInput ' The DirectInput core 
Dim DI_Device As DirectInputDevice ' The DirectInput device
Dim DI_State As DIKEYBOARDSTATE 'Array Holding the state of the keys

'DirectDraw Surfaces- Where the screen is drawn.
Dim DS_Front As DirectDrawSurface4 ' The frontbuffer (What you see on the screen)
Dim DS_Back As DirectDrawSurface4 ' The backbuffer, (Where everything is drawn before it's put on the screen.)
Dim SD_Front As DDSURFACEDESC2 ' The SurfaceDescription
Dim DD_Back As DDSCAPS2 ' General Surface Info

'ViewPort and Direct3D Device
Dim D3D_Device as Direct3DRMDevice3 'The Main Direct3D Retained Mode Device
Dim D3D_ViewPort as Direct3DRMViewport2 'The Direct3D Retained Mode Viewport (Kinda the camera) 

'The Frames 
Dim FR_Root as Direct3DRMFrame3 'The Main Frame (The other frames are put under this one (Like a tree))
Dim FR_Camera as Direct3DRMFrame3 'Another frame, just happens to be called 'camera'. We will use this
                                                   'as the viewport. Hence, the name camera. Doesn't have to be
                                                   'called 'camera'. It could be called 'BillyBob' for all I care. 
Dim FR_Light as Direct3DRMFrame3 'This frame contains our, guess what, spotlight!
Dim FR_Building as Direct3DRMFrame3 'Frame containing our 1st mesh that will be put in this "game". 

'Meshes (3D objects loaded from a .x file)
Dim MS_Building as Direct3DRMMeshBuilder3

'Lights
Dim LT_Ambient as Direct3DRMLight 'Our Main (Ambient) light that illuminates everything (not just part of something
                                                'like a spotlight. 
Dim LT_Spot as Direct3DRMLight 'Our Spot light, makes it look more realistic. 

'Camera Positions
Dim xx As Long
Dim yy As Long
Dim zz As Long

Dim
esc As Boolean 'If Escape is pressed, the DX_Input sub will make it true and the main loop will end. 
'Incase you haven't caught on, the prefix FR = frame, MS = Mesh, & LT = light.

'======================================================================================

Private Sub DX_Init()
 
'Type, not copy and paste!
 'This sub will initialize all your components and set them up. 
 
set DD_Main = DX_Main.DirectDraw4Create("") 'Create the DirectDraw Object

 DD_Main.SetCooperativeLevel Form1.hWnd, DDSCL_FULLSCREEN Or DDSCL_EXCLUSIVE 'Set Screen Mode (Full 'Screen)
 DD_Main.SetDisplayMode 640, 480, 32, 0, DDSDM_DEFAULT
'Set Resolution and BitDepth (Lets use 32-bit color)
 
 
SD_Front.lFlags = DDSD_CAPS Or DDSD_BACKBUFFERCOUNT
 SD_Front.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_3DDEVICE Or DDSCAPS_COMPLEX OR _
 DDSCAPS_FLIP
'I used the line-continuation ( _ ) because the whole thing wouldn't fit on one line...
 SD_Front.lBackBufferCount = 1 '
Make one backbuffer 
 
Set DS_Front = DD_Main.CreateSurface(SD_Front) 'Initialize the front buffer (the screen)
 'The Previous block of code just created the screen and the backbuffer. 
 
 
DD_Back.lCaps = DDSCAPS_BACKBUFFER
 
Set DS_Back = DS_Front.GetAttachedSurface(DD_Back)
 DS_Back.SetForeColor RGB(255, 255, 255)
 
'The backbuffer was initialized and the DirectDraw text color was set to white. 

 
Set D3D_Main = DX_Main.Direct3DRMCreate() 'Creates the Direct3D Retained Mode Object!!!!!

 Set D3D_Device = D3D_Main.CreateDeviceFromSurface("IID_IDirect3DHALDevice", DD_Main, DS_Back, _
 D3DRMDEVICE_DEFAULT)
'Tell the Direct3D Device that we are using hardware rendering (HALDevice) instead
                                   'of software enumeration (RGBDevice).
 
D3D_Device.SetBufferCount 2 'Set the number of buffers
 
D3D_Device.SetQuality D3DRMRENDER_GOURAUD 'Set Rendering Quality. Can use Flat, or WireFrame, but
                                                                  'GOURAUD has the best rendering quality.
 
D3D_Device.SetTextureQuality D3DRMTEXTURE_NEAREST 'Set the texture quality
 
D3D_Device.SetRenderMode D3DRMRENDERMODE_BLENDEDTRANSPARENCY 'Set the render mode.

 
Set DI_Main = DX_Main.DirectInputCreate() 'Create the DirectInput Device
 
Set DI_Device = DI_Main.CreateDevice("GUID_SysKeyboard") 'Set it to use the keyboard.
 
DI_Device.SetCommonDataFormat DIFORMAT_KEYBOARD 'Set the data format to the keyboard format.
 
DI_Device.SetCooperativeLevel Me.hWnd, DISCL_BACKGROUND Or DISCL_NONEXCLUSIVE 'Set Coperative Level.
 
DI_Device.Acquire
 
'The above block of code configures the DirectInput Device and starts it.
End Sub

'=====================================================================================

Private Sub DX_MakeObjects()
 
Set FR_Root = D3D_Main.CreateFrame(Nothing) 'This will be the root frame of the 'tree'
 
Set FR_Camera = D3D_Main.CreateFrame(FR_Root) 'Our Camera's Sub Frame. It goes under FR_Root in the 'Tree'.
 
Set FR_Light = D3D_Main.CreateFrame(FR_Root) 'Our Light's Sub Frame
 
Set FR_Building = D3D_Main.CreateFrame(FR_Root) 'Our Building (the 3D Thingy that will be placed in our world's) 
                                                                      ' sub frame. 
 'That above code set up the hierarchy of frames where FR_Root is the parent, and the other frames are all 
 'owned by it.
 
 
FR_Root.SetSceneBackgroundRGB 0, 0, 1 'Set the background color. Use decimals, not the standerd 255 = max.
                                                         'What I have here will make the background/sky 100% blue. 
 
FR_Camera.SetPosition Nothing, 1, 4, -35 'Set The Camera position; X=1, Y=4, z=-35. 
 
Set D3D_Viewport = D3D_Main.CreateViewport(D3D_Device, FR_Camera, 0, 0, 640, 480) 'Make our viewport and set 
                                                                                                                  'it our camera to be it.
 
D3D_Viewport.SetBack 200 'How far back it will draw the image. (Kinda like a visibility limit)
  
 
FR_Light.SetPosition Nothing, 0, 25, 0 'Set our 'point' light.
 
Set LT_Spot = D3D_Main.CreateLightRGB(D3DRMLIGHT_POINT, 1, 1, 1) 'Set the light type and it's color.
 
FR_Light.AddLight LT_Spot 'Add the light to it's frame.
  
 
Set LT_Ambient = D3D_Main.CreateLightRGB(D3DRMLIGHT_AMBIENT, 0.5, 0.5, 0.5) 'Create our ambient light.
 
FR_Root.AddLight LT_Ambient 'Add the ambient light to the root frame.

 
Set MS_Building = D3D_Main.CreateMeshBuilder() 'Make the 3D Building Mesh
 
MS_Building.LoadFromFile app.path & "\building.x",0 ,0 ,nothing ,nothing 'Load our building mesh from its .X file.
 
MS_Building.ScaleMesh 1, 1, 1 'Set the it's scale. This is used to make the object smaller or bigger. 1 makes
                                          'it the same size as it was built in whatever program it was built in. 
 
FR_Building.AddVisual MS_Building 'Add the 3D Building mesh to it's frame. 

End Sub  

'=====================================================================================

Private Sub DX_Render()
 
'Lets put our main loop. Make it loop until esc = true (I'll explain later)
 
Do While esc = False
   On local error resume next
'Incase there is an error
  
DoEvents 'Give the computer time to do what it needs to do. 
   
  
DX_Input 'Call the input sub. 
  
D3D_Viewport.Clear D3DRMCLEAR_TARGET Or D3DRMCLEAR_ZBUFFER 'Clear your viewport. 
  
D3D_Device.Update 'Update the Direct3D Device. 
  
D3D_Viewport.Render FR_Root 'Render the 3D Objects (lights, and your building!)
  
DS_Back.DrawText 200, 0, "My First Direct3D Program!", False 'Draw some text! 
  
DS_Front.Flip Nothing, DDFLIP_WAIT 'Flip the back buffer with the front buffer. 
 
Loop
End Sub

'=====================================================================================

Private Sub DX_Input()
 DI_Device.GetDeviceStateKeyboard DI_State
'Get the array of keyboard keys and their current states
  

 If
DI_State.Key(DIK_ESCAPE) <> 0 Then Call DX_Exit 'If user presses [esc] then exit end the program.
 
 
If DI_State.Key(DIK_LEFT) <> 0 Then 'Quick Note: <> means 'does not'
  
FR_Camera.SetPosition FR_Camera, -1, 0, 0 'Move the viewport to the left
 
end if
 
 If
DI_State.Key(DIK_RIGHT) <> 0 Then
  
FR_Camera.SetPosition FR_Camera, 1, 0, 0 'Move the viewport to the right
 
End If
 
 If
DI_State.Key(DIK_UP) <> 0 Then
  
FR_Camera.SetPosition FR_Camera, 0, 0, 1 'Move the viewport forward
 
End If

 If
DI_State.Key(DIK_DOWN) <> 0 then 
   FR_Camera.SetPosition FR_Camera, 0, 0, -1
'Move the viewport back
 
End If  

End Sub

'=====================================================================================

Private Sub DX_Exit()
 
Call DD_Main.RestoreDisplayMode
 
Call DD_Main.SetCooperativeLevel(Me.hWnd, DDSCL_NORMAL)
 
Call DI_Device.Unacquire
 
'Restore all the devices

 
End 'Ends the program.
End Sub

'=====================================================================================

Private Sub Form_Load()
 Me.Show
'Some computers do weird stuff if you don't show the form.
 
DoEvents 'Give the computer time to do what it needs to do
 
DX_Init 'Initialize DirectX
 
DX_MakeObjects 'Make frames, lights, and mesh(es)
 
DX_Render 'The Main Loop
 'One More Line of code after this!!!
End Sub

Chapter 5: Making it better

You probably noticed that when you move right or left, the camera moves right or left, but doesn't rotate. To fix this problem, change the DX_Input sub code to the following:

Private Sub DX_Input()
 
Const Sin5 = 8.715574E-02! ' Sin(5°)
 
Const Cos5 = 0.9961947! ' Cos(5°)
 
 DI_Device.GetDeviceStateKeyboard DI_State
'Get the array of keyboard keys and their current states
  

 If
DI_State.Key(DIK_ESCAPE) <> 0 Then Call DX_Exit 'If user presses [esc] then exit end the program.
 
 
If DI_State.Key(DIK_LEFT) <> 0 Then 'Quick Note: <> means 'does not'
  
FR_Camera.SetOrientation FR_Camera, -Sin5, 0, Cos5, 0, 1, 0 'Rotate viewport/camera left
 
end if
 
 If
DI_State.Key(DIK_RIGHT) <> 0 Then
  
FR_Camera.SetOrientation FR_Camera, Sin5, 0, Cos5, 0, 1, 0 'Rotate viewport/camera right
 
End If
 
 If
DI_State.Key(DIK_UP) <> 0 Then
  
FR_Camera.SetPosition FR_Camera, 0, 0, 1 'Move the viewport forward
 
End If

 If
DI_State.Key(DIK_DOWN) <> 0 then
   FR_Camera.SetPosition FR_Camera, 0, 0, -1
'Move the viewport back
 
End If 

End Sub

You also might want collision detection (So you can't walk through walls). But I don't know how to yet, so you won't either! HahahA!

Ok, if you liked this tutorial, PLEASE vote for me at PSC!