Planet-Source-Code / simon-price-an-introduction-to-directx-8-and-more__1-14218

0 stars 0 forks source link



An Introduction To DirectX 8 - And More!!!

Description

Learn every aspect of DirectX8 now!

This HUGE tutorial covers DirectX 8, DirectSound8, DirectInput8, Direct3D8. It includes everything - from knowing nothing to having a good grasp of DirectX 8 with Visual Basic. It even goes beyond that and explains the logic needed to create 3D geometry and animation. There is a fully documented sample program too! And a glossary of terms - not just DirectX terms - but general programming and 3D mathematics too! The best DirectX 8 tutorial you are ever gonna get for free! Even people who already know DirectX should read this, as it goes onto more complex subjects. Especially people who have learnt DirectX 7 or earlier.

Please remember to give me lots of feedback and votes so I know how to make future tutorials!

More Info

Submitted On
By Simon Price
Level Beginner
User Rating 4.9 (247 globes from 50 users)
Compatibility VB 6.0
Category DirectX
World Visual Basic
Archive File

Source Code

An Introduction To DirectX8

By Simon Price

Visit www.VBgames.co.uk for more!

What you will learn

How you will learn it

Boring Intro

Back by popular demand is my DirectX tutorial series! Although I'm sort of starting again for DirectX 8. So for complete newbies, this tutorial is great, and for those who already know some DX7 or DX8, the tutorial includes some more complex stuff than previous tutorials. In DirectX 8, the API has become simpler in the initialization of objects and it also has many more maths functions to help you. But it's still alot of work to do by yourself, so that's why you should help spread the word by making free source demos and tutorials. At this point I acknowledge Richard Hayden for his free source Direct3D8 world, it is a great example of what I am talking about and helped me begin to learn the new API. Enough of the chit chat...

Before you begin

If you don't already have DirectX 8 and the DirectX 8 Type Libraries for Visual Basic then you've got some downloading to do! Sorry, but it is worth it. You don't need all the SDK documentation, although I recommend getting it, and you don't need the C++ SDK if you are a VB'er only, so your download might not be as big as mine was. I managed to download 135 MB though my cheap 56 K phone line though, and that was the full download including everything. So it is possible, but you will need to get a program such as GetRight to help you download such a big file. All developer information and downloads can be found at www.microsoft.com/directx . Once DirectX 8 is installed, and you have the DX VB Type Libs, read on.

Adding a reference to your project

Every time you start a new project that will use DirectX, you will need to do the following:

Now VB will know every class, type and enumeration that DirectX 8 contains, so you're ready to begin coding!

DirectX and 3D terminology

This is the part which gets most people. I wish I had someone to explain all the jargon to me when I was learning. After the language barrier, things get a bit easier. Here's some terms you need to know. If you already know a bit about DirectX, you should probably skip this whole section and only come back to it when you see a word you don't understand. It is not in alphabetical order, rather it is in logical order so that you can read the whole thing if you're new and you want to. As you can see, there is alot of it, and this is only the basics.

The sample program

You can download the sample program from here. You will need a program like Winzip to decompress it. It is written in Visual Basic 6, if you have another version of VB then there is information on www.planet-source-code.com/vb as to how to try to open the version 6 files.

The sample program uses hardware accelerated rasterization. If your computer does not have this, the request will fail, so use D3DDEVTYPE_REF instead of D3DDEVTYPE_HAL if this happens. A real program would be able to detect an error and automatically switch device. It also requests software vertex processing, which means the CPU has to transform and light geometry, but if you have a good graphics card, you might be able to use hardware vertex processing. 

The sample program assumes your computer can render in 16 bit (R5G6B5) color format, in 640 x 480 resolution. If this is not the case, it may fail but you can change those values in the source code.

The sample program renders the same texture mapped 3D cube in different positions. It uses the same cube but it makes it appear that there are 3, each of different sizes, and they are all spinning and rotating around everywhere. The camera can be zoomed in and out using the mouse and the program can be exited using the escape key. The program plays a sound every time the animation loop restarts. It attempts to show all the basic features of DirectX 8 simply. It is not optimized so as to keep it as simple to understand as possible.

The main point to note is the that the animation is achieved by moving the world transformation. Every single line is commented, an there are lengthy explanations of each main function. Here is the full source code and comment to view, but you can also download it.

---***---SOURCE CODE STARTS HERE---***---

'-----------------------------------------------------------------
'
' DX8 INTRODUCTION - DIRECTGRAPHICS,DIRECTSOUND, DIRECTINPUT
'
' BY SIMON PRICE
'
'-----------------------------------------------------------------

' For this tutorial program you will need the DirectX8 for Visual
' Basic Type Library, from www.microsoft.com/directx

' You should also have the tutorial in HTML format, if you don't
' you can download it from my website www.VBgames.co.uk

' Any questions go to ihaveaquestionforsimonaboutdx8@VBgames.co.uk,
' or you could use a shorter address :) (si@VBgames.co.uk will do)
' Any bug reports go to the same address too please, as do comments
' feedback, suggestions, erm whatever you feel like

' Every time you start a project which will use DirectX8, you need
' to click on the menu Project -> References and a dialog box will
' pop up. Check the box which says "DirectX8 for Visual Basic Type
' Library" and click OK. Now VB will know all the types, classes
' enumerations and functions of DirectX8.

Option Explicit

' GLOBAL VARIABLE DECLARATIONS

' No matter what you do with DirectX8, you will need to start with
' the DirectX8 object. You will need to create a new instance of
' the object, using the New keyword, rather than just getting a
' pointer to it, since there's nowhere to get a pointer from yet (duh!).

Dim DX As New DirectX8

' The DirectInput8 object is used to get data from input devices
' such as the mouse and keyboard. This is what we will use it for
' in this tutorial, since they are the most common input devices.
' Notice how we don't create a new instance of the object, rather
' DirectX does that for us and we just get a pointer to it.

Dim DI As DirectInput8

' Now we need 2 devices - keyboard and mouse...

Dim Keyboard As DirectInputDevice8
Dim Mouse As DirectInputDevice8

' ...and a structure (type) to hold the data from each device. DI
' provides us a custom keyboard and mouse type, since they are
' commonly used

Dim KeyboardState As DIKEYBOARDSTATE
Dim MouseState As DIMOUSESTATE

' Next, we have DirectSound8, this can be used for many things, but
' for now we just play a sound from a .wav file

Dim DS As DirectSound8

' A sound buffer is a piece of memory in which the sound is stored.
' We use a secondary buffer, because a primary buffer can actually
' be heard though the speakers, and the sound needs to be mixed
' before we allow the user to hear that. In this tutorial, we let
' DirectSound worry about mixing and copying to the primary buffer
' to play the sound for us

Dim Sound As DirectSoundSecondaryBuffer8

' The DSBUFFER type holds a description of a sound buffer. We won't
' use any of the more advanced flags in this tutorial

Dim SoundDesc As DSBUFFERDESC

' The Direct3D8 object is responsible for all graphics, yes, even 2D

Dim D3D As Direct3D8

' The D3DX8 object contains lots of helper functions, mostly math
' to make Direct3D alot easier to use. Notice we create a new
' instance of the object using the New keyword.

Dim D3DX As New D3DX8

' The Direct3DDevice8 represents our rendering device, which could
' be a hardware or a software device. The great thing is we still
' use the same object no matter what it is

Dim D3Ddevice As Direct3DDevice8

' The D3DPRESENT_PARAMETERS type holds a description of the way
' in which DirectX will display it's rendering

Dim D3Dpp As D3DPRESENT_PARAMETERS

' The D3DMATERIAL8 type stores information on the material our
' polygons are rendered with, such as color

Dim Material As D3DMATERIAL8

' The Direct3DTexture8 object represents a piece of memory used to
' store a texture to be mapped onto our polygons

Dim Texture As Direct3DTexture8

' The Direct3DVertexBuffer8 object stores an array of vertices from which
' our polygons are made

Dim VertexBuffer As Direct3DVertexBuffer8

' The D3DVERTEX type stores vertices temporarily before we copy
' them into the vertex buffer

Dim Vertex(1 To 24) As D3DVERTEX

' The Direct3DIndexBuffer8 object stores the order in which our
' vertices are rendered

Dim IndexBuffer As Direct3DIndexBuffer8

' These integers are used to temporarily store indices before they
' are copied into the index buffer

Dim Index(1 To 36) As Integer

' This stores the rotation of the cubes

Dim Rotation As Single






' FORM_LOAD

' The whole program is started and controlled from here

Private Sub Form_Load()
    On Error Resume Next
    ' initialize directx
   
If Init = False Then
        ' display error message
        MsgBox "Error! Could not initialize DirectX!"
    Else
        ' show form
        Show
        ' do main program loop
        MainLoop
        End If
    ' unload form and clean up directx
    Unload Me
End Sub


' FORM_UNLOAD

' Before the program ends, call the cleanup function

Private Sub Form_Unload(Cancel As Integer)
CleanUp
End Sub





' INITIALIZATION

' In this function we initialize all the global DirectX objects. We
' basically get the DirectInput, DirectSound, and DirectGraphics
' engines started up, and retrieve pointers so we can manipulate them

Function Init() As Boolean

    'On Error GoTo InitFailed

    ' DIRECTINPUT

    ' Get a pointer to DirectInput
   
Set DI = DX.DirectInputCreate()
    ' Check to see if the pointer is valid
   
If DI Is Nothing Then GoTo InitFailed

    ' Get a pointer to keyboard and mouse device objects
   
Set Keyboard = DI.CreateDevice("GUID_SysKeyboard")
    Set Mouse = DI.CreateDevice("guid_SysMouse")
    ' Check to see if pointers are valid
    If Keyboard Is Nothing Then GoTo InitFailed
    If Mouse Is Nothing Then GoTo InitFailed

    ' Set the data formats to the commmonly used keyboard and mouse
    Keyboard.SetCommonDataFormat DIFORMAT_KEYBOARD
    Mouse.SetCommonDataFormat DIFORMAT_MOUSE

    ' Set cooperative level, this tells DI how much control we need
    Keyboard.SetCooperativeLevel hWnd, DISCL_NONEXCLUSIVE Or DISCL_BACKGROUND
    Mouse.SetCooperativeLevel hWnd, DISCL_NONEXCLUSIVE Or DISCL_BACKGROUND

    ' Now we are ready to aquire (erm, get) our input devices
    Keyboard.Acquire
    Mouse.Acquire

    ' DIRECTSOUND

    ' Get a pointer to DirectSound
    Set DS = DX.DirectSoundCreate("")
    ' Check the pointer is valid
    If DS Is Nothing Then GoTo InitFailed

    ' Set cooperative level, we only need normal functionality
    DS.SetCooperativeLevel hWnd, DSSCL_NORMAL

    ' Create a sound buffer from a .wav file. We provide a filename
    ' and a DSBUFFER type, which stores any special information
    ' about the buffer we might need to know (not used here)
    Set Sound = DS.CreateSoundBufferFromFile(App.Path & "\sound.wav", SoundDesc)
    ' Check the pointer is valid
    If Sound Is Nothing Then GoTo InitFailed

    ' DIRECT3D

    ' Get a pointer to Direct3D
    Set D3D = DX.Direct3DCreate()
    ' Check the pointer is valid
    If D3D Is Nothing Then GoTo InitFailed

    ' Fill the D3DPRESENT_PARAMETERS type, describing how DirectX should
    ' display it's renders

    With D3Dpp
        ' set the most common fullscreen display mode
        .Windowed = False ' the app is not in a window
        .BackBufferWidth = 640 ' the size of the screen
        .BackBufferHeight = 480
        .BackBufferFormat = D3DFMT_R5G6B5 ' the color depth format (16 bit)
        ' the swap effect determines how the graphics get from
        ' the backbuffer to the screen - note : D3DSWAPEFFECT_DISCARD
        ' means that every time the render is presented, the backbuffer
        ' image is destroyed, so everything must be rendered again
        .SwapEffect = D3DSWAPEFFECT_DISCARD
        ' request a 16 bit z-buffer - this depth sorts the scene
        ' so we can't see polygons that are behind other polygons
        .EnableAutoDepthStencil = 1
        .AutoDepthStencilFormat = D3DFMT_D16
        ' 1 backbuffer
        .BackBufferCount = 1
       End With

    ' Create the rendering device. Here we request a hardware rasterization.
    ' If your computer does not have this, the request may fail, so use
    ' D3DDEVTYPE_REF instead of D3DDEVTYPE_HAL if this happens. A real
    ' program would be able to detect an error and automatically switch device.
    ' We also request software vertex processing, which means the CPU has to
    ' transform and light our geometry
    Set D3Ddevice = D3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,  D3DCREATE_SOFTWARE_VERTEXPROCESSING, D3Dpp)
    ' check the pointer is valid
    If D3Ddevice Is Nothing Then GoTo InitFailed

    ' Set rendering options
    D3Ddevice.SetRenderState D3DRS_CULLMODE, D3DCULL_NONE
    D3Ddevice.SetRenderState D3DRS_ZENABLE, D3DZB_TRUE ' enable z buffering
    D3Ddevice.SetRenderState D3DRS_FILLMODE, D3DFILL_SOLID ' render solid polygons
    D3Ddevice.SetRenderState D3DRS_LIGHTING, True ' enable lighting
    D3Ddevice.SetRenderState D3DRS_AMBIENT, vbWhite ' use ambient white light
    
    ' Set the material properties
    With Material.Ambient
        .a = 1: .r = 1: .g = 1: .b = 1
    End With

    ' Create a texture surface from a file
    Set Texture = D3DX.CreateTextureFromFile(D3Ddevice, App.Path & "\texture.bmp")
    ' Check the pointer is valid
    If Texture Is Nothing Then GoTo InitFailed

    ' Set the material and texture as the current ones to render from
    D3Ddevice.SetMaterial Material
    D3Ddevice.SetTexture 0, Texture

    ' Create a vertex buffer, using default usage and specifying enough memory for 24 vertices of format         D3DFVF_VERTEX
    Set VertexBuffer = D3Ddevice.CreateVertexBuffer(24 * Len(Vertex(1)), 0, D3DFVF_VERTEX, D3DPOOL_DEFAULT)
    ' Check pointer is valid
    If VertexBuffer Is Nothing Then GoTo InitFailed

    ' Create an index buffer, using default uage and specifying enough memory for 36 16 bit integers
    Set IndexBuffer = D3Ddevice.CreateIndexBuffer(36 * Len(Index(1)), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT)
    ' Check pointer is valid
    If IndexBuffer Is Nothing Then GoTo InitFailed

    ' Now we make a cube shape out of our vetices
    Vertex(1) = MakeVertex(-1, 1, -1, 0, 0, -1, 0, 0)
    Vertex(2) = MakeVertex(1, 1, -1, 0, 0, -1, 1, 0)
    Vertex(3) = MakeVertex(-1, -1, -1, 0, 0, -1, 0, 1)
    Vertex(4) = MakeVertex(1, -1, -1, 0, 0, -1, 1, 1)
    Vertex(5) = MakeVertex(1, 1, -1, 0, 0, 1, 0, 0)
    Vertex(6) = MakeVertex(-1, 1, -1, 0, 0, 1, 1, 0)
    Vertex(7) = MakeVertex(1, -1, -1, 0, 0, 1, 0, 1)
    Vertex(8) = MakeVertex(-1, -1, -1, 0, 0, 1, 1, 1)

    Vertex(9) = MakeVertex(-1, 1, 1, -1, 0, 0, 0, 0)
    Vertex(10) = MakeVertex(-1, 1, -1, -1, 0, 0, 1, 0)
    Vertex(11) = MakeVertex(-1, -1, 1, -1, 0, 0, 0, 1)
    Vertex(12) = MakeVertex(-1, -1, -1, -1, 0, 0, 1, 1)
    Vertex(13) = MakeVertex(1, 1, -1, 1, 0, 0, 0, 0)
    Vertex(14) = MakeVertex(1, 1, 1, 1, 0, 0, 1, 0)
    Vertex(15) = MakeVertex(1, -1, -1, 1, 0, 0, 0, 1)
    Vertex(16) = MakeVertex(1, -1, 1, 1, 0, 0, 1, 1)

    Vertex(17) = MakeVertex(-1, 1, -1, 0, 1, 0, 0, 0)
    Vertex(18) = MakeVertex(1, 1, -1, 0, 1, 0, 1, 0)
    Vertex(19) = MakeVertex(-1, 1, 1, 0, 1, 0, 0, 1)
    Vertex(20) = MakeVertex(1, 1, 1, 0, 1, 0, 1, 1)
    Vertex(21) = MakeVertex(-1, -1, -1, 0, -1, 0, 0, 0)
    Vertex(22) = MakeVertex(1, -1, -1, 0, -1, 0, 1, 0)
    Vertex(23) = MakeVertex(-1, -1, 1, 0, -1, 0, 0, 1)
    Vertex(24) = MakeVertex(1, -1, 1, 0, -1, 0, 1, 1)

    ' Copy the vertices into the vertex buffer
D3DVertexBuffer8SetData VertexBuffer, 0, 24 * Len(Vertex(1)), 0, Vertex(1)

    ' Make a list which tells the order in which to render these vertices
    MakeIndices 1, 2, 3, 3, 2, 4, 5, 6, 7, 7, 6, 8, 9, 10, 11, 11, 10, 12, 13, 14, 15, 15, 14, 16, 17, 18, 19, 19, 18, 20, 21, 22, 23, 23, 22, 24

    ' Copy the indices into the index buffer
    D3DIndexBuffer8SetData IndexBuffer, 0, 36 * Len(Index(1)), 0, Index(1)

    ' Set the vertex format
    D3Ddevice.SetVertexShader D3DFVF_VERTEX

    ' Set the vertex and index buffers as current ones to render from
    D3Ddevice.SetStreamSource 0, VertexBuffer, Len(Vertex(1))
    D3Ddevice.SetIndices IndexBuffer, -1

    ' Initializtion is complete!
    Init = True
    Exit Function

InitFailed: ' the initialization function has failed
    Init = False

End Function





' MAKEVECTOR

' This function creates vectors

Function MakeVector(x As Single, y As Single, z As Single) As D3DVECTOR
    With MakeVector
        .x = x
        .y = y
        .z = z
    End With
End Function





' MAKEVERTEX

' This function creates vertices

Function MakeVertex(x As Single, y As Single, z As Single, nx As Single, ny As Single, nz As Single, tu As Single, tv As Single) As D3DVERTEX
    With MakeVertex
        .x = x
        .y = y
        .z = z
        .nx = nx
        .ny = ny
        .nz = nz
        .tu = tu
        .tv = tv
    End With
End Function





' MAKEINDICES

' This function creates a list of indices

Function MakeIndices(ParamArray Indices()) As Integer()
    Dim i As Integer
    For i = LBound(Indices) To UBound(Indices)
        Index(i + 1) = Indices(i)
    Next
End Function





' MAINLOOP

' This sub animates the scene by moving the positions of the
' cubes and the camera position, then renders the cubes. It
' checks to see if the escape key has been pressed and loops
' if it has not.

Sub MainLoop()
' the mathematical constant pi
Const PI = 3.1415
' the speed of animation
Const SPEED = 0.01
' matrices for animation and cameras
Dim matTranslation As D3DMATRIX, matRotation As D3DMATRIX, matScaling As D3DMATRIX, matView As D3DMATRIX, matProjection As D3DMATRIX, matTransform As D3DMATRIX
' camera position
Dim CameraPos As D3DVECTOR
On Error Resume Next
    Do
        ' let Windows messages be executed
        DoEvents
        ' get keyboard and mouse data
        Keyboard.GetDeviceStateKeyboard KeyboardState
        Mouse.GetDeviceStateMouse MouseState
        ' if escape was pressed, exit program
        If KeyboardState.Key(DIK_ESCAPE) Then Exit Do
        ' move camera with mouse
        CameraPos.y = CameraPos.y + MouseState.lY / 10
        CameraPos.z = -2
        ' set camera position, using mouse data
        D3DXMatrixLookAtLH matView, MakeVector(CameraPos.x, CameraPos.y, CameraPos.z), MakeVector(0, 0, 0), MakeVector(0, 1, 0)
        D3Ddevice.SetTransform D3DTS_VIEW, matView
        D3DXMatrixPerspectiveFovLH matProjection, PI / 3, 0.75, 0.1, 10000
        D3Ddevice.SetTransform D3DTS_PROJECTION, matProjection
        ' move the rotation angle
        Rotation = Rotation + SPEED
        If Rotation > 2 * PI Then
            Rotation = Rotation - 2 * PI
            ' once per rotation, play a sound
            Sound.Play DSBPLAY_DEFAULT
        End If
        ' clear the rendering device backbuffer and z-buffer
        D3Ddevice.Clear 0, ByVal 0, D3DCLEAR_TARGET Or D3DCLEAR_ZBUFFER, vbWhite, 1#, 0
        ' start rendering
        D3Ddevice.BeginScene
        ' create rotation matrix
        D3DXMatrixRotationYawPitchRoll matTransform, Rotation * 2, Rotation, Rotation
        ' set the world matrix to normal
        D3Ddevice.SetTransform D3DTS_WORLD, matTransform
        ' draw the medium cube
        DrawCube
        ' create movement, rotation and scale matrices
        D3DXMatrixTranslation matTranslation, 0, 0, 4
        D3DXMatrixRotationYawPitchRoll matRotation, 0, Rotation * 2, Rotation * 4
        D3DXMatrixScaling matScaling, 0.5, 0.5, 0.5
        ' combine them
        D3DXMatrixMultiply matTransform, matRotation, matTranslation
        D3DXMatrixMultiply matTransform, matTransform, matScaling
        ' transform the world matrix
        D3Ddevice.MultiplyTransform D3DTS_WORLD, matTransform
        ' draw the small cube
        DrawCube
        ' create movement, rotation and scale matrices
        D3DXMatrixTranslation matTranslation, -3, -3, -3
        D3DXMatrixRotationYawPitchRoll matRotation, Rotation * 8, 0, Rotation * 6
        D3DXMatrixScaling matScaling, 0.5, 0.5, 0.5
        ' combine them
        D3DXMatrixMultiply matTransform, matTranslation, matRotation
        D3DXMatrixMultiply matTransform, matTransform, matScaling
        ' transform the world matrix
        D3Ddevice.MultiplyTransform D3DTS_WORLD, matTransform
        ' draw the small cube
        DrawCube
        ' end rendering
        D3Ddevice.EndScene
        ' present the contents of the backbuffer by flipping it to the screen
        D3Ddevice.Present ByVal 0, ByVal 0, 0, ByVal 0
    Loop
End Sub





' DRAWCUBE

' Draws the cube

Sub DrawCube()
On Error Resume Next
    ' draw 12 triangles, in a cube shape, onto the backbuffer of the rendering device
    D3Ddevice.DrawIndexedPrimitive D3DPT_TRIANGLELIST, 0, 36, 0, 12
End Sub




' CLEANUP

' This unloads all the DirectX objects - we destroy objects we
' have created, an disassociate our pointers from objects
' create by DirectX, so then DirectX can destroy them. Failing
' to call this sub can cause memory to be lost.

Sub CleanUp()

On Error Resume Next

    Set Keyboard = Nothing
    Set Mouse = Nothing
    Set DI = Nothing

    Set Sound = Nothing
    Set DS = Nothing

    Set Texture = Nothing
    Set D3Ddevice = Nothing
    Set D3DX = Nothing
    Set D3D = Nothing

End Sub


---***---SOURCE CODE ENDS HERE---***---

Hey - does somebody have a HTML VB syntax color highlighter? As you can see, I got fed up and didn't color in the keywords!

What you have learnt

What you should do next

Future Tutorials

There's still lots more to learn and more advanced tutorials will come when I get the time. Some major topics include 3D sound, lighting, and loading model files. Give me some feedback on what you need to know.

What I'd like you to do now

Credits

There are lots of sources from where my information came from. Mainly Microsoft's DirectX SDK (as much as I hate them, DirectX rules!). Many tutorials on www.planet-source-code.com and www.gamedev.net , and also thanks to Richard Hayden for his example program.

Disclaimer

This tutorial might be totally wrong so it's not my fault if something goes wrong. You've been warned (right at the end, after you messed up your PC)!