TEAMFLY
9.0
Frank D. Luna
Technical review by Rod Lopez
Wordware Publishing, Inc.
Library of Congress Cataloging-in-Publication Data
Luna, Frank D.
Introduction to 3D game programming with DirectX 9.0 / by Frank D. Luna.
p. cm.
ISBN 1-55622-913-5 (pbk.)
1. Computer games Programming. 2. DirectX. I. Title.
QA76.76.C672L83 2003
794.8'15268 dc21 2003005834
CIP
© 2003, Wordware Publishing, Inc.
All Rights Reserved
2320 Los Rios Boulevard
Plano, Texas 75074
No part of this book may be reproduced in any form or by any means
without permission in writing from Wordware Publishing, Inc.
Printed in the United States of America
ISBN 1-55622-913-5
10987654321
0305
DirectX is a registered trademark of Microsoft Corporation in the United States and/or other
countries.
All brand names and product names mentioned in this book are trademarks or service marks
of their respective companies. Any omission or misuse (of any kind) of service marks or
trademarks should not be regarded as intent to infringe on the property of others. The
publisher recognizes and respects all marks used by companies, manufacturers, and
developers as a means to distinguish their products.
Combining Transformations 23
Some Functions to Transform Vectors 25
Planes (Optional) 25
D3DXPLANE 26
Point and Plane Spatial Relation 27
Construction 27
Normalizing a Plane 28
Transforming a Plane 29
Nearest Point on a Plane to a Particular Point 29
Rays (Optional) 30
Rays 30
Ray/Plane Intersection 31
Summary 32
v
Part II Direct3D Fundamentals. . . 33
Chapter 1 Direct3D Initialization . . . 35
1.1 Direct3D Overview 35
1.1.1 The REF Device 36
1.1.2 D3DDEVTYPE 37
1.2 COM 37
1.3 Some Preliminaries 37
1.3.1 Surfaces 38
1.3.2 Multisampling 39
1.3.3 Pixel Formats 40
1.3.4 Memory Pools 41
1.3.5 The Swap Chain and Page Flipping 42
1.3.6 Depth Buffers 43
1.3.7 Vertex Processing 44
1.3.8 Device Capabilities 44
1.4 Initializing Direct3D 45
3.1.1 Creating a Vertex and Index Buffer 76
3.1.2 Accessing a Buffer’s Memory 78
3.1.3 Retrieving Information about a Vertex and
Index Buffer 79
3.2 Render States 80
3.3 Drawing Preparations 81
3.4 Drawing with Vertex/Index Buffers 82
3.4.1 IDirect3DDevice9::DrawPrimitive 82
3.4.2 IDirect3DDevice9::DrawIndexedPrimitive 82
3.4.3 Begin/End Scene 84
3.5 D3DX Geometric Objects 84
3.6 Sample Applications: Triangle, Cube, Teapot,
D3DXCreate* 85
3.7 Summary 89
Chapter 4 Color 91
4.1 Color Representation 91
4.2 Vertex Colors 94
4.3 Shading 94
4.4 Sample Application: Colored Triangle 95
4.5 Summary 97
Chapter 5 Lighting 98
5.1 Light Components 98
5.2 Materials 99
5.3 Vertex Normals 101
5.4 Light Sources 104
5.5 Sample Application: Lighting 107
5.6 Additional Samples 109
5.7 Summary 110
Chapter 6 Texturing. . . 111
6.1 Texture Coordinates 112
8.2 Sample Application: Mirrors 137
8.2.1 The Mathematics of Reflection 137
8.2.2 Mirror Implementation Overview 139
8.2.3 Code and Explanation 140
8.2.3.1 PartI 141
8.2.3.2 PartII 141
8.2.3.3 PartIII 142
8.2.3.4 PartIV 143
8.2.3.5 PartV 143
8.3 Sample Application: Planar Shadows 144
8.3.1 Parallel Light Shadows 145
8.3.2 Point Light Shadows 146
8.3.3 The Shadow Matrix 146
8.3.4 Using the Stencil Buffer to Prevent Double
Blending 147
8.3.5 Code and Explanation 148
8.4 Summary 150
Part III Applied Direct3D . . . 151
Chapter 9 Fonts 153
9.1 ID3DXFont 153
9.1.1 Creating an ID3DXFont 153
viii Contents
9.1.2 Drawing Text 154
9.1.3 Computing the Frames Rendered Per Second 155
9.2 CD3DFont 155
9.2.1 Constructing a CD3DFont 156
9.2.2 Drawing Text 156
9.2.3 Cleanup 157
9.3 D3DXCreateText 157
9.4 Summary 159
12.2 Implementation Details 201
12.2.1 Computing the View Matrix 201
12.2.1.1 Part 1: Translation 202
12.2.1.2 Part 2: Rotation 203
Contents ix
12.2.1.3 Combining Both Parts 204
12.2.2 Rotation about an Arbitrary Axis 205
12.2.3 Pitch, Yaw, and Roll 205
12.2.4 Walking, Strafing, and Flying 207
12.3 Sample Application: Camera 209
12.4 Summary 211
Chapter 13 Basic Terrain Rendering. . . 212
13.1 Heightmaps 213
13.1.1 Creating a Heightmap 214
13.1.2 Loading a RAW File 215
13.1.3 Accessing and Modifying the Heightmap 215
13.2 Generating the Terrain Geometry 216
13.2.1 Computing the Vertices 217
13.2.2 Computing the Indices—Defining the Triangles . . 220
13.3 Texturing 221
13.3.1 A Procedural Approach 222
13.4 Lighting 224
13.4.1 Overview 224
13.4.2 Computing the Shade of a Quad 225
13.4.3 Shading the Terrain 227
13.5 “Walking” on the Terrain 228
13.6 Sample Application: Terrain 231
13.7 Some Improvements 233
13.8 Summary 234
Chapter 14 Particle Systems 235
16.2.2 Compiling an HLSL Shader 278
16.3 Variable Types 280
16.3.1 Scalar Types 280
16.3.2 Vector Types 281
16.3.3 Matrix Types 282
16.3.4 Arrays 283
16.3.5 Structures 283
16.3.6 The typedef Keyword 284
16.3.7 Variable Prefixes 284
16.4 Keywords, Statements, and Casting 285
16.4.1 Keywords 285
16.4.2 Basic Program Flow 285
16.4.3 Casting 286
16.5 Operators 287
16.6 User-Defined Functions 288
16.7 Built-in Functions 290
16.8 Summary 292
Chapter 17 Introduction to Vertex Shaders 293
17.1 Vertex Declarations 294
17.1.1 Describing a Vertex Declaration 295
17.1.2 Creating a Vertex Declaration 297
17.1.3 Enabling a Vertex Declaration 297
17.2 Vertex Data Usages 298
17.3 Steps to Using a Vertex Shader 300
17.3.1 Writing and Compiling a Vertex Shader 300
17.3.2 Creating a Vertex Shader 300
17.3.3 Setting a Vertex Shader 301
Contents xi
17.3.4 Destroying a Vertex Shader 301
17.4 Sample Application: Diffuse Lighting 301
19.3 Device States in an Effect File 340
19.4 Creating an Effect 341
19.5 Setting Constants 342
19.6 Using an Effect 344
19.6.1 Obtaining a Handle to an Effect 345
19.6.2 Activating an Effect 345
19.6.3 Beginning an Effect 345
19.6.4 Setting the Current Rendering Pass 346
19.6.5 Ending an Effect 346
19.6.6 Example 346
xii Contents
19.7 Sample Application: Lighting and Texturing in
an Effect File 347
19.8 Sample Application: Fog Effect 352
19.9 Sample Application: Cartoon Effect 355
19.10 EffectEdit 356
19.11 Summary 356
Appendix An Introduction to Windows Programming . . . . . 359
Overview 360
Resources 360
Events, the Message Queue, Messages, and the
Message Loop 360
GUI 362
Hello World Windows Application 363
Explaining Hello World 366
Includes, Global Variables, and Prototypes 366
WinMain 367
WNDCLASS and Registration 368
Creating and Displaying the Window 370
The Message Loop 372
applications on the Windows platform. In this book we are concerned
with a particular DirectX subset, namely Direct3D. As the name
implies, Direct3D is the API used for developing 3D applications.
This book is divided into four main parts. Part I explains the mathe-
matical tools that will be used throughout this book. Part II covers
elementary 3D techniques, such as lighting, texturing, alpha blending,
and stenciling. Part III is largely about using Direct3D to implement a
variety of interesting techniques and applications, such as picking, ter-
rain rendering, particle systems, a flexible virtual camera, and loading
and rendering 3D models (XFiles). The theme of Part IV is vertex and
pixel shaders, including the effects framework and the new (to DirectX
9.0) High-Level Shading Language. The present and future of 3D game
programming is the use of shaders, and by dedicating an entire part of
the book to shaders, we have an up-to-date and relevant book on mod
-
ern graphics programming.
For the beginner, this book is best read front to back. The chapters
have been organized so that the difficulty increases progressively with
each chapter. In this way, there are no sudden jumps in complexity,
leaving the reader lost. In general, for a particular chapter we will use
the techniques and concepts previously developed. Therefore, it is
important that you have mastered the material of a chapter before con
-
tinuing. Experienced readers can pick the chapters of interest.
Finally, you may wonder what kinds of games you can develop after
reading this book. The answer to that question is best obtained by
skimming through this book and seeing the types of applications that
are developed. From that you should be able to visualize the types of
games that can be developed based on the techniques taught in this
book and some of your own ingenuity.
for(int cnt = 0; cnt < 10; cnt++)
{
std::cout << "hello" << std::endl;
}
return 0;
}
However, in VC++ 6.0 this will not compile. It gives the error message
error C2374: 'cnt' : redefinition; multiple initialization because in VC++
6.0 the variable
cnt is not treated as being local to the for loop.
Therefore, when porting to VC++ 6.0, you may need to make some
minor changes to get it to compile due to this difference.
xviii Introduction
Recommended Hardware
The following hardware recommendations are if you wish to be able to
run the sample programs at an acceptable frame rate; all the samples
can be run using the REF device, which emulates Direct3D functional
-
ity in software. Because things are being emulated in software, they
run very slow. We discuss the REF more in Chapter 1.
The sample programs in Part II of this book are fairly basic and
should run on low-end cards, such as the Riva TNT or an equivalent
graphics card. The sample programs in Part III push more geometry
and use some newer features, such as point sprites. For these samples
we recommend a graphics card at the level of a GeForce2. The sample
programs in Part IV use vertex and pixel shaders; therefore, to run
these programs in real time, you will need a graphics card that supports
shaders such as the GeForce3.
Intended Audience
This book was designed with the following three audiences in mind:
so for shipping applications, use the retail version.
Setting Up the Development Environment
The types of projects that you will want to create for writing DirectX
applications are Win32 Application projects. In VC++ 6.0 and 7.0 you
will also want to specify the directory paths at which the DirectX
header files and library files are located, so VC++ can find these files.
The DirectX header files and library files are located at the paths
D:\DXSDK\Include and D:\DXSDK\Lib, respectively.
xx Introduction
Figure I.2: The
debug spew
resulting from
not releasing a
Direct3D
resource
Figure I.1: For developing
DirectX applications, it is best
to select the debug option so
that you can debug your
DirectX applications easier.
TEAMFLY
Team-Fly
®
Note: The location of the DirectX directory DXSDK on your computer
may differ; it depends on the location that you specified during
installation.
Typically, the DirectX SDK installation will add these paths to VC++
for you. However, in case it doesn’t, you can do it manually as follows:
In VC++ 6.0 go to the menu and select Tools>Options>Direc
-
tories and enter the DirectX header file and library paths, as Figure I.3
shows.
In VC++ 7.0 go to the menu and select Tools>Options>Projects
Folder>VC++ Directories and enter the DirectX header and library
paths, as Figure I.4 shows.
Then, in order to build the sample programs, you will need to link the
-
ifying the library
files to link into
the project in
VC++ 7.0
We use the D3DX library throughout this book because it allows us
to focus on more interesting material. For instance, we’d rather not
spend pages explaining how to load various image formats (e.g., .bmp,
.jpeg) into a Direct3D texture interface when we can do it in a single
call to the D3DX function
D3DXCreateTextureFromFile. In other
words, D3DX makes us more productive and lets us focus more on
actual content rather than spending time reinventing the wheel.
Other reasons to use D3DX:
n
D3DX is general and can be used with a wide range of different
types of 3D applications.
n
D3DX is fast (at least as fast as general functionality can be).
n
Other developers use D3DX. Therefore, you will most likely
encounter code that uses D3DX. Consequently, whether you
choose to use D3DX or not, you should become familiar with it so
that you can read code that uses it.
n
D3DX already exists and has been thoroughly tested. Furthermore,
it becomes more improved and feature rich with each iteration of
DirectX.
Using the DirectX SDK
Documentation and SDK Samples
nations and alternative examples.
We would also like to point out the available Direct3D sample pro
-
grams that ship with DirectX SDK. The C++ Direct3D samples are
located in the \DXSDK\Samples\C++\Direct3D directory. Each sample
illustrates how to implement a particular effect in Direct3D. These
samples are fairly advanced for a beginning graphics programmer, but
by the end of this book you should be ready to study them. Examination
of the samples is a good “next step” after finishing this book.
Code Conventions
The coding conventions for the sample code are fairly clear-cut. The
only two things worth mentioning are that we prefix member variables
with an underscore. For example:
xxiv Introduction
Figure I.7: A screen
shot of the C++ SDK
documentation viewer