DXTUT4 - Introduction to Direct3D!
Posted: 2002-06-01
By: ArchiveBot
Viewed: 111
Filed Under:
Title | Uploaded | Size |
---|---|---|
CODE_UPLOAD111851112000.zip | 9/3/2020 3:45:00 PM | 12,445 |
This tutorial WILL teach you how to get started with using Direct3D Immediate Mode from Visual
Basic. It includes background knowledge, definitions, explanations, a sample program to download, and exercises for you to practice on. I have spent hours, wrong, days planning, writing, testing and re-reading this so that it's almost a work of art. Seriously though, you will learn alot. I recommend a very basic
knowledge of DirectDraw, but this is not required, and a fairly good general programming ability, since only DirectX terms will be explained in detail.
If you think that this has helped you, interested you, or changed your whole
life (OK maybe not), please vote and/or give feedback
because I value your opinions. Especially if you think this was a bad
tutorial, please tell me why and I will try to fix it.
Original Author: Simon Price
Code
This tutorial will consist of the following steps : Explanation of what Direct3D does and how you can use it Definitions of all the objects, types and enumerations you Example source code with heavy commenting Summary of what you have learnt Exercises to make you remember it all Direct3D is a part of DirectX. This tutorial is specific to Direct3D has a job - to give programmers a common interface for It's time to start Visual Basic! Create a new project and called Here are the declarations you will need for the tutorial DirectX7 - this is the great big daddy of them all! DirectDraw7 - this is the base of all the graphics DirectDrawSurface7 - this is an object created by DirectDrawClipper - this is used to clip areas, Direct3D7 - this is based upon DirectDraw. It Direct3DDevice7 - this is the rendering device. You RECT - this describes a rectangle, and DirectDraw D3DRECT - this is similar to the RECT type used with DDSURFACEDESC2 - this describes a DirectDrawSurface, D3DVIEWPORT7 - this describes the way in which D3DVERTEX - this type holds all the information we need to D3DMATRIX - this holds 16 values which are used for You will also need to declare two other variables: Now we have declared all the objects we need, we need to call We will create a function that creates the DirectDraw object, Now we need to initialize all our Direct3D objects. In this The world matrix - all objects in world space are The view matrix - sets the position of the camera The projection matrix - defines how Direct3D projects the 3D If you're still alert and haven't become totally confused yet, We need to supply triangles for Direct3D to render. Therefore we This procedure takes the already declare vertices and forms them OK that's enough loading and initializing to last me a lifetime! If you run your program now, nowt will happen at all. This is There is one more thing to do - end the program! The main loop Run the program. If you've typed it correctly (or just used my In this tutorial, we have : There are many bad points to the program you have created, although I have You can only learn something if you actually practice doing it. So here I I hope I've set you along the exciting journey towards creating Direct3D Tutorial by Simon Price, you can email me at Si@VBgames.co.ukAn Introduction To Direct3D
By Simon Price
Tutorial Breakdown
from Visual Basic
will need to know to get started
Direct3D Overview
Direct3D 7, so you will need DirectX 7.0 or higher if you are planning to use
what you learn here. DirectX has a component called DirectDraw, which is used to
perform graphics functions at a lower level that Windows GDI. If you have never
used DirectDraw before, I suggest you look at my tutorial "An Introduction
To DirectDraw", available on this site, or my
website. Direct3D (D3D) has two main parts - Immediate Mode and Retained
Mode. This tutorial deals with Immediate Mode only. Immediate Mode (IM) is built
on top of DirectDraw. That means it uses DirectDraw to place graphics on the
screen, or in memory. D3D Retained Mode (RM) is built on top of D3D IM.
Therefore, D3D RM is not as efficient as D3D IM. This is why I have chosen to
learn D3D IM. However, I do not claim that one is better than the other, just
that IM is faster and RM is easier to learn and create applications very quickly
with. If you learn IM, heavy vector mathematics and slow development is involved
but you will be rewarded with more power and control. The choice is yours. If
you still want to learn IM, then read on.
all 3D devices. In English - no matter what computer your application runs on,
whether it has a Voodoo Mega Wicked 10000 3D accelerator or a Omega Budget 256
Color Economy VGA card, you still use the same objects to program with. It means
that you don't have to learn about how every graphics card works for your
application to work on every computer. Direct3D also provides software
emulation. This means that if half your users have hardware acceleration, and
half don't, you can use hardware if available and then fall back to using
Direct3D software emulation if the hardware is not available. Of course software
emulation is alot slower.
it something imaginative like "D3Dintro.vbp". Next, click Project -> References
and a dialog box will show a list of references your project uses. If you have
installed the DirectX7 For Visual Basic type library, scroll down to it and
check the check box next to it. Click OK to add the reference. Now Visual Basic
knows every single class, type and enumeration you need to use DirectX7. If you
do not have the DirectX 7 For Visual Basic Type Library, you can download it
from www.microsoft.com .Get on with the programming!
programs, with a short explanation as to what they are all about. First the
objects followed by the types.
It is from the DirectX7 object that you will create all the other objects,
including DirectDraw and Direct3D. Note the use of the New keyword, meaning
that your application puts aside the memory to create a new instance of this
object.
Dim DX As New DirectX7
functionality that DirectX provides, including Direct3D7. Note the omission
of the New keyword, since you do not create this object, but DirectX does.
Dim DDRAW As DirectDraw7
DirectDraw to represent a piece of memory. You will need a primary and
backbuffer surface. The primary surface represents the actual graphics on
the screen, the backbuffer is a surface to draw our whole image onto before
we copy it to the primary surface.
Dim Primary As DirectDrawSurface7
Dim Backbuffer As DirectDrawSurface7
meaning that if you try draw outside the clipping boundaries, nothing will
be drawn. This is useful in Windows so that you don't make a mess all over
bits of screen that don't belong to your application.
Dim Clipper As DirectDrawClipper
provides all the 3D functionality you will need.
Dim D3D As Direct3D7
use it to control the states and parameters of Direct3D, and to send drawing
commands to draw (usually) triangles.
Dim D3Ddevice As Direct3DDevice7
uses it to copy rectangular pieces of pictures around. Here we need two,
they are just cached for regular use in the program.
Dim SrcRect As RECT
Dim DestRect As RECT
DirectDraw. We will use it in clearing operations. You will always need to
declare it as an array, even if you only need one of them.
Dim Viewport(0) As D3DRECT
so we can ask DirectDraw to create a surface with the properties we need.
Dim SurfDesc as DDSURFACEDESC2
Direct3D transforms a 3D scene to represent it on a 2D surface.
Dim VPdesc As D3DVIEWPORT7
create a vertex. We are going to create a triangle so we need an array
of 3.
Dim Vertex(0 to 2) as D3DVERTEX
any and every translation in 3D. With a matrix, you can translate, rotate
and scale. We will need four in this tutorial, the world, view, projection
and spin matrices.
Dim matWorld As D3DMATRIX
Dim matView As D3DMATRIX
Dim matProj As D3DMATRIX
Dim matSpin As D3DMATRIX
' this tells the program when to end
Dim EndNow As Boolean
' this is used to rotate the triangle
Dim Counter As LongInitiation of DirectDraw and Direct3D
some of their methods to make them do something. We will also use the variables
to send information to DirectX. Since Direct3D is built upon DirectDraw, we will
need to initialize the DirectDraw objects before Direct3D.The DirectDrawInit Function
sets the cooperative level, sets up the primary and backbuffer surfaces for
our graphics functions to work on, and finally creates a clipper to restrict
drawing to just the application window. Note then when we create the backbuffer
surface, we pass the DDSCAPS_3DDEVICE flag to tell DirectDraw that we are going
to use it as a 3D rendering target.
Function DirectDrawInit() As Long
' create the directdraw object
Set DDRAW = DX.DirectDrawCreate("")
' set the cooperative level, we only need normal
DDRAW.SetCooperativeLevel hWnd, DDSCL_NORMAL
' set the properties of the primary surface
SurfDesc.lFlags = DDSD_CAPS
SurfDesc.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE
' create the primary surface
Set Primary = DDRAW.CreateSurface(SurfDesc)
' set up the backbuffer surface (which will be where we render the 3D view)
SurfDesc.lFlags = DDSD_HEIGHT Or DDSD_WIDTH Or DDSD_CAPS
SurfDesc.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN Or DDSCAPS_3DDEVICE
' use the size of the form to determine the size of the render target
' and viewport rectangle
DX.GetWindowRect hWnd, DestRect
' set the dimensions of the surface description
SurfDesc.lWidth = DestRect.Right - DestRect.Left
SurfDesc.lHeight = DestRect.Bottom - DestRect.Top
' create the backbuffer surface
Set Backbuffer = DDRAW.CreateSurface(SurfDesc)
' cache the size of the render target for later use
With SrcRect
.Left = 0: .Top = 0
.Bottom = SurfDesc.lHeight
.Right = SurfDesc.lWidth
End With
' create a DirectDrawClipper and attach it to the primary surface.
Set Clipper = DDRAW.CreateClipper(0)
Clipper.SetHWnd hWnd
Primary.SetClipper Clipper
' report any errors
DirectDrawInit = Err.Number
End Function
The Direct3DInit Function
function, we need to create Direct3D, a rendering device (something that does
the drawing for us), a material (defines the appearance of polygons), and
several matrices. The rendering device can be some hardware device like a 3D
accelerator card, or software emulation. For this tutorial, we will use
software emulation for simplicity. The matrices are :
transformed by this matrix
scene onto the 2D surface
Function Direct3DInit() As Long
' create the direct3d object
Set D3D = DDRAW.GetDirect3D
' create the rendering device - we are using software emulation only
Set D3Ddevice = D3D.CreateDevice("IID_IDirect3DRGBDevice", Backbuffer)
' set the viewport rectangle.
VPdesc.lWidth = DestRect.Right - DestRect.Left
VPdesc.lHeight = DestRect.Bottom - DestRect.Top
VPdesc.minz = 0
VPdesc.maxz = 1
D3Ddevice.SetViewport VPdesc
' cache the viewport rectangle for later use
With Viewport(0)
.X1 = 0: .Y1 = 0
.X2 = VPdesc.lWidth
.Y2 = VPdesc.lHeight
End With
' enable ambient lighting
D3Ddevice.SetRenderState D3DRENDERSTATE_AMBIENT, DX.CreateColorRGBA(1, 1, 1, 1)
' disable culling
D3Ddevice.SetRenderState D3DRENDERSTATE_CULLMODE, D3DCULL_NONE
' set the material to a red color
Material.Ambient.r = 1
Material.Ambient.g = 0
Material.Ambient.b = 0
D3Ddevice.SetMaterial Material
' the world matrix - all polygons in world space are transformed by this matrix
DX.IdentityMatrix matWorld
D3Ddevice.SetTransform D3DTRANSFORMSTATE_WORLD, matWorld
' the view matrix - basically the camera position is at -3
' (although it's really just making the whole world at +3)
DX.IdentityMatrix matView
DX.ViewMatrix matView, MakeVector(0, 0, -3), MakeVector(0, 0, 0), MakeVector(0, 1, 0), 0
D3Ddevice.SetTransform D3DTRANSFORMSTATE_VIEW, matView
' the projection matrix - decides how the 3D scene is projected onto the 2D surface
DX.IdentityMatrix matProj
DX.ProjectionMatrix matProj, 1, 1000, 3.14 / 2
D3Ddevice.SetTransform D3DTRANSFORMSTATE_PROJECTION, matProj
' report errors
Direct3DInit = Err.Number
End FunctionThe MakeVector Function
you will be saying "hey Simon, you called a MakeVector function - what's
that all about? The MakeVector function is very similar to the
DX.CreateD3DVertex (see later) function - it just saves us alot of typing by
copying values into the D3DVECTOR type. So we need to create the MakeVector
function for the Direct3DInit function to work.
Function MakeVector(x As Single, y As Single, z As Single) As D3DVECTOR
' copy x, y and z into the return value
With MakeVector
.x = x
.y = y
.z = z
End With
End FunctionCreating The Scene
should declare some vertices to make the triangle from. For simplicity, we will
render just one triangle which means we need only 3 vertices (one for each
corner). We could fill in the data separately for each field of the type
D3DVERTEX, but it's much shorter to use a function of the DirectX object that
does this for you in one line of code.The CreateTriangle Sub
into a triangle shape. In a D3DVERTEX, there are three pieces of data - the
position (x,y,z), the normal (nx,ny,nz) and the texture coordinates (tu,tv). We
only need to use the position in this tutorial. The normal of a triangle is
concerned with lighting, which we aren't using. The texture coordinates are for,
well, textures - which we aren't using either.
Sub CreateTriangle()
' fill in the vertex positions - we don't need to worry about the normals
' or texture coordinates for this tutorial
DX.CreateD3DVertex -1, 0, 0, 0, 0, 0, 0, 0, Vertex(0)
DX.CreateD3DVertex 0, 2, 0, 0, 0, 0, 0, 0, Vertex(1)
DX.CreateD3DVertex 1, 0, 0, 0, 0, 0, 0, 0, Vertex(2)
End SubThe Main Program Loop
But once you've learnt it, it will get easier and you can always reuse your
code. Now we move onto the main program loop. This is a loop where we clear the
backbuffer, draw the polygon, copy the backbuffer to the screen and then move
the polygon before we draw the next frame. Don't be surprised if this loop runs
at over 100 frames per second - after all, it's just one polygon. In a real
world application, you may want to render thousands per frame. On with the show:
Sub MainLoop()
Do While EndNow = False
' increase the counter
Counter = Counter + 1
' clear the viewport with a green color
D3Ddevice.Clear 1, Viewport(), D3DCLEAR_TARGET, vbGreen, 0, 0
' begin the scene, render the triangle, then end the scene
D3Ddevice.BeginScene
D3Ddevice.DrawPrimitive D3DPT_TRIANGLELIST, D3DFVF_VERTEX, Vertex(0), 3, D3DDP_DEFAULT
D3Ddevice.EndScene
' rotate the matrix
DX.RotateYMatrix matSpin, Counter / 360
' set the new world transform matrix
D3Ddevice.SetTransform D3DTRANSFORMSTATE_WORLD, matSpin
' copy the backbuffer to the screen
DX.GetWindowRect hWnd, DestRect
Primary.Blt DestRect, Backbuffer, SrcRect, DDBLT_WAIT
' look for window messages - we need to know when the escape key is pressed
DoEvents
Loop
End SubGetting It Together
because you have created a load of procedures but you haven't called them from
anywhere. This is when you will need to put some code into the Form_Load event,
to do initiation and then the main loop. We will check the return values of the
initiation functions, and if they report errors we will end the program.The Form_Load Event
Private Sub Form_Load()
' show the form
Show
' call the DirectDrawInit function and exit if it fails
If DirectDrawInit() <> DD_OK Then Unload Me
' call the Direct3DInit function and exit if it fails
If Direct3DInit() <> DD_OK Then Unload Me
' create the triangle
CreateTriangle
' call the main rendering loop
MainLoop
' end the program
Unload Me
End SubThe Form_Unload and Form_KeyDown Events
is exited if the EndNow variable is set to true - so that's all we need to do.
We can also end the program if the escape key is pressed, by putting the same
code in the Form_KeyDown event.
Private Sub Form_Unload(Cancel As Integer)
EndNow = True
End Sub
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
' end program if escape is pressed
If KeyCode = vbKeyEscape Then EndNow = True
End SubRun The Program
example code), you will see the form has a spinning triangle painted on it. You
can even resize the form and the picture will resize to the form size. When you
close the form or press escape, the program ends.Summary
made the program in this way to make it as simple as possible.
to each variable as much as possible. I made them all global for this
tutorial so I could explain each one at the beginning
the cause of the error, attempt to fix it, and if that's not possible we
would tell the user why, rather than ending immediately.
of hardware the user has, and make our program adapt to either make maximum
use of the hardware, or fall back onto just software if no hardware is
available.
Exercises
have some features which you can add to the program yourself. Come on, be a
little creative and start making your own 3D graphics!
another shape - a cube, a pyramid, a sphere if you're smart enough -
whatever you like!
bet it goes at over 100 FPS!
program. I don't want here any complaints that this tutorial was boring -
it's up to you to make it interesting!
graphics from Visual Basic. This tutorial has taken me ALOT of time and
effort - I had to write code, make comments, write a tutorial, get it as
accurate as possible. I would appreciate in return:
good or bad, I want to know about it.
score that you did.
to visit my website to see more of my programs and tutorials. The URL is www.VBgames.co.uk
Comments on this post
No comments have been added for this post.
You must be logged in to make a comment.