Advanced 3-D Game Pro gramming using DirectX 7.0 - By Adrian Perez, with Dan Royer
←
→
Page content transcription
If your browser does not render page correctly, please read the page content below
Advanced 3-D Game Programming using DirectX 7.0 By Adrian Perez, with Dan Royer Wordware Publishing, Inc.
Library of Congress Cataloging-in-Publication Data Perez, Adrian. Advanced 3-D game programming using DirectX 7.0 / by Adrian Perez, with Dan Royer. p. cm. ISBN 1-55622-721-3 (pbk.) 1. Computer games—Programming. 2. DirectX. I. Royer, Dan. II. Title. QA76.76.C672 P47 2000 794.8'15265--dc21 00-032086 CIP © 2000, 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-721-3 10 9 8 7 6 5 4 3 2 1 0005 DirectX is a registered trademark of Microsoft Corp. Other product names mentioned are used for identification purposes only and may be trademarks of their respective companies. All inquiries for volume purchases of this book should be addressed to Wordware Publishing, Inc., at the above address. Telephone inquiries may be made by calling: (972) 423-0090
To my parents, Manny and Maria. Adrian The woman who wouldn’t love me back, The head bully, My parents: Well look who’s laughing now! Dan iii
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiv Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv Chapter 1 Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 A Word About Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Hungarian Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 General Windows Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Message Handling in Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Explaining Message Processing . . . . . . . . . . . . . . . . . . . . . . . . 5 Hello World—Windows Style . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Explaining the Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Registering Our Application . . . . . . . . . . . . . . . . . . . . . . 11 Initializing Our Window . . . . . . . . . . . . . . . . . . . . . . . . 11 WndProc—The Message Pump . . . . . . . . . . . . . . . . . . . . 14 Manipulating Window Geometry . . . . . . . . . . . . . . . . . . . . . . . . . 15 Important Window Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 MFC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Class Encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 COM: The Component Object Model . . . . . . . . . . . . . . . . . . . . . . 30 References. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 For Further Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Chapter 2 DirectX—The Basic Components . . . . . . . . . . . . . . . . . . . . . 35 What is DirectX? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 Setting up VC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 DirectDraw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 2-D Graphics—A Primer . . . . . . . . . . . . . . . . . . . . . . . . . . 39 Surfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 Complex Surfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 Describing Surfaces . . . . . . . . . . . . . . . . . . . . . . . . . . 45 The IDirectDrawSurface7 Interface. . . . . . . . . . . . . . . . . . 50 Surface Operations . . . . . . . . . . . . . . . . . . . . . . . . . . 51 Surfaces and Memory . . . . . . . . . . . . . . . . . . . . . . . . . 53 Modifying the Contents of Surfaces . . . . . . . . . . . . . . . . . . 53 Drawing on Surfaces with GDI . . . . . . . . . . . . . . . . . . . . 54 v
Contents The DirectDraw Object . . . . . . . . . . . . . . . . . . . . . . . . . . 55 Windowed vs. Full-screen . . . . . . . . . . . . . . . . . . . . . . . 56 The DirectDraw Interface . . . . . . . . . . . . . . . . . . . . . . . . . 57 Creating DirectDraw Surfaces . . . . . . . . . . . . . . . . . . . . 58 DirectDraw Device Capabilities. . . . . . . . . . . . . . . . . . . . 58 Implementing DirectDraw with cGraphicsLayer . . . . . . . . . . . . . . 59 Creating the Graphics Layer . . . . . . . . . . . . . . . . . . . . . 66 Enumerating DirectDraw Devices . . . . . . . . . . . . . . . . . . 67 Full-screen Initialization . . . . . . . . . . . . . . . . . . . . . . . . 69 Windowed Initialization . . . . . . . . . . . . . . . . . . . . . . . . 75 Shutting Down DirectDraw . . . . . . . . . . . . . . . . . . . . . . 81 Changes to cApplication. . . . . . . . . . . . . . . . . . . . . . . . 81 Application: DirectDraw Sample . . . . . . . . . . . . . . . . . . . . . . 85 DirectInput . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 Why Should We Use DirectInput? . . . . . . . . . . . . . . . . . . . . . 88 Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 Receiving Device States . . . . . . . . . . . . . . . . . . . . . . . . 90 Cooperative Levels . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Application Focus and Devices . . . . . . . . . . . . . . . . . . . . 94 The DirectInput Object . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 Implementing DirectInput with cInputLayer . . . . . . . . . . . . . . . . 95 Additions to cApplication . . . . . . . . . . . . . . . . . . . . . . 110 DirectSound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 The Essentials of Sound . . . . . . . . . . . . . . . . . . . . . . . . . . 111 DirectSound Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . 113 DirectSound Buffers . . . . . . . . . . . . . . . . . . . . . . . . . 113 Operations on Sound Buffers . . . . . . . . . . . . . . . . . . . . . . . 116 Loading WAV Files . . . . . . . . . . . . . . . . . . . . . . . . . . 120 Implementing DirectSound with cSoundLayer . . . . . . . . . . . . . . 121 Creating the DirectSound Object . . . . . . . . . . . . . . . . . . 121 Setting the Cooperative Level . . . . . . . . . . . . . . . . . . . . 122 Grabbing the Primary Buffer . . . . . . . . . . . . . . . . . . . . . 123 The cSound Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 Additions to cApplication . . . . . . . . . . . . . . . . . . . . . . 133 Application: DirectSound Sample . . . . . . . . . . . . . . . . . . . . . 133 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 For Further Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 Chapter 3 3-D Math Foundations . . . . . . . . . . . . . . . . . . . . . . . . . . 139 Points. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 The point3 Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Basic point3 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 Assign. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 Mag and MagSquared . . . . . . . . . . . . . . . . . . . . . . . . 145 Normalize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 vi
Contents Dist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 point3 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 Addition/Subtraction . . . . . . . . . . . . . . . . . . . . . . . . . 146 Vector-scalar Multiplication/Division. . . . . . . . . . . . . . . . . 148 Vector Equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 Dot Product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 Cross Product . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Polygons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 Triangles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 Strips and Fans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 Planes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 Defining Locality with Relation to a Plane. . . . . . . . . . . . . . . . . 163 Back-face Culling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 Clipping Lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 Clipping Polygons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 Object Representations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 The matrix4 Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 Translation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Basic Rotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Axis-Angle Rotation . . . . . . . . . . . . . . . . . . . . . . . . . 191 The LookAt Matrix. . . . . . . . . . . . . . . . . . . . . . . . . . 193 Perspective Projection Matrix . . . . . . . . . . . . . . . . . . . . 195 Inverse of a Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . 196 Collision Detection with Bounding Spheres. . . . . . . . . . . . . . . . . . . 197 Lighting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 Representing Color . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 Lighting Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 Specular Reflection . . . . . . . . . . . . . . . . . . . . . . . . . . 204 Light Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 Parallel Lights (or Directional Lights) . . . . . . . . . . . . . . . . 205 Point Lights . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 Spot Lights . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 Shading Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 Lambert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 Gourad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 Phong. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 BSP Trees. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 BSP Tree Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 BSP Tree Construction . . . . . . . . . . . . . . . . . . . . . . . . . . 213 BSP Tree Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 Sorted Polygon Ordering . . . . . . . . . . . . . . . . . . . . . . 218 Testing Locality of a Point . . . . . . . . . . . . . . . . . . . . . . 219 Testing Line Segments . . . . . . . . . . . . . . . . . . . . . . . . 220 vii
Contents BSP Tree Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 Wrapping It Up. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 For Further Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 Chapter 4 Artificial Intelligence . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 Starting Point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 Locomotion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 Steering—Basic Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 Chasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 Evading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 Pattern-based AI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 Steering—Advanced Algorithms. . . . . . . . . . . . . . . . . . . . . . . . . 237 Potential Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 The Good . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 The Bad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 Application: potentialFunc . . . . . . . . . . . . . . . . . . . . . . 241 Path Following . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 Groundwork . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 Graph Theory Done Really, Really Quickly . . . . . . . . . . . . . 246 Using Graphs to Find Shortest Paths. . . . . . . . . . . . . . . . . 249 Application: Path Planner . . . . . . . . . . . . . . . . . . . . . . 251 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 Non-Deterministic Finite Automata (NFAs) . . . . . . . . . . . . . . . 255 Genetic Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 Rule-Based AI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 Neural Networks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 A Basic Neuron . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 Simple Neural Networks . . . . . . . . . . . . . . . . . . . . . . 263 Training Neural Networks . . . . . . . . . . . . . . . . . . . . . . 265 Using Neural Networks in Games . . . . . . . . . . . . . . . . . . 266 Application: NeuralNet . . . . . . . . . . . . . . . . . . . . . . . 266 Some Closing Thoughts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275 Works Cited . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276 For Further Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276 Chapter 5 UDP Networking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 Endianness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 Network Models. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 Protocols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 Packets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 The Right Tool for the Job (aka “DirectPlay and why we’re not using it”) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 Implementation 1: MTUDP . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 viii
Contents Design Considerations. . . . . . . . . . . . . . . . . . . . . . . . . . . 282 Things that go “aurgh, my kidney!” in the night. . . . . . . . . . . . . . 282 Mutexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 Threads, Monitor, and the Problem of the try/throw/catch Construction . . . . . . . . . . . . . . . . . . . . . . . 286 MTUDP: The Early Years . . . . . . . . . . . . . . . . . . . . . . . . . 286 MTUDP::Startup() and MTUDP::Cleanup() . . . . . . . . . . . . . 287 MTUDP::MTUDP() and MTUDP::~MTUDP() . . . . . . . . . . . 288 MTUDP::StartListening(). . . . . . . . . . . . . . . . . . . . . . . 289 MTUDP::StartSending() . . . . . . . . . . . . . . . . . . . . . . . 290 MTUDP::ThreadProc(). . . . . . . . . . . . . . . . . . . . . . . . 290 MTUDP::ProcessIncomingData() . . . . . . . . . . . . . . . . . . 292 MTUPD::GetReliableData() . . . . . . . . . . . . . . . . . . . . . 293 MTUDP::ReliableSendTo().. . . . . . . . . . . . . . . . . . . . . . 293 cDataPacket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 cQueueIn. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294 cHost . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 MTUDP::ReliableSendTo() . . . . . . . . . . . . . . . . . . . . . . 300 cUnreliableQueueIn . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 cUnreliableQueueOut . . . . . . . . . . . . . . . . . . . . . . . . . . . 308 cHost::AddACKMessage() / cHost::ProcessIncomingACKs() . . . . 308 cNetClock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313 Implementation 2: Smooth Network Play . . . . . . . . . . . . . . . . . . . 316 Geographic and Temporal Independence . . . . . . . . . . . . . . . . . 316 Timing is Everything . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 Pick and Choose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 Prediction and Extrapolation . . . . . . . . . . . . . . . . . . . . . . . 319 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 Chapter 6 Beginning Direct3D—Immediate Mode . . . . . . . . . . . . . . . . . 323 Introduction to D3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 The Direct3D7 Object. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324 The Direct3DDevice7 Object . . . . . . . . . . . . . . . . . . . . . . . . . . 325 Device Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 Device Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 HAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 TnLHal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327 RGB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 RefRast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 Ramp (and Other Legacy Devices). . . . . . . . . . . . . . . . . . 329 Determining Device Capabilities . . . . . . . . . . . . . . . . . . . . . 329 The D3DPRIMCAPS Structure . . . . . . . . . . . . . . . . . . . 332 Setting Device Render States . . . . . . . . . . . . . . . . . . . . . . . 334 Fundamental Direct3D Structures . . . . . . . . . . . . . . . . . . . . . . . 341 D3DCOLOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341 ix
Contents D3DCOLORVALUE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342 D3DVECTOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343 D3DMATRIX. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343 The Depth Problem (and How Direct3D Solves It) . . . . . . . . . . . . . . 343 W-Buffering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 Enumerating Z-buffer Formats . . . . . . . . . . . . . . . . . . . . . . 347 Stencil Buffers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 Vertex Buffers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 Texture Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 Materials and Lights . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 Using Lights . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 D3D Lighting Semantics . . . . . . . . . . . . . . . . . . . . . . . 356 The sLight Helper Class . . . . . . . . . . . . . . . . . . . . . . . 357 Using Materials. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358 D3D Material Semantics . . . . . . . . . . . . . . . . . . . . . . . 359 The sMaterial Helper Class . . . . . . . . . . . . . . . . . . . . . 360 The Geometry Pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360 Clipping and Viewports . . . . . . . . . . . . . . . . . . . . . . . . . . 362 Fog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363 Vertex-based Fog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 Pixel-based Fog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 Using Fog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365 Drawing with the Device . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366 Direct3D Vertex Structures . . . . . . . . . . . . . . . . . . . . . . . . 367 D3DVERTEX. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367 D3DLVERTEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368 D3DTLVERTEX . . . . . . . . . . . . . . . . . . . . . . . . . . . 369 Flexible Vertex Format Flags . . . . . . . . . . . . . . . . . . . . . 370 Strided Vertex Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373 Primitive Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374 The DrawPrimitive Functions . . . . . . . . . . . . . . . . . . . . . . . 375 DrawPrimitive . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 DrawPrimitiveStrided . . . . . . . . . . . . . . . . . . . . . . . . 375 DrawPrimitiveVB. . . . . . . . . . . . . . . . . . . . . . . . . . . 376 DrawIndexedPrimitive . . . . . . . . . . . . . . . . . . . . . . . . 376 DrawIndexedPrimitiveStrided . . . . . . . . . . . . . . . . . . . . 377 DrawIndexedPrimitiveVB . . . . . . . . . . . . . . . . . . . . . . 378 Adding Direct3D to the Graphics Layer . . . . . . . . . . . . . . . . . . . . 379 Direct3D Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 Acquire an IDirect3D7 Interface from Our IDirectDraw7 Interface . . . . . . . . . . . . . . . . . . . . . 380 Enumerate and Confirm Devices . . . . . . . . . . . . . . . . . . 380 Enumerate Z-buffer Formats and Build the Z-buffer . . . . . . . . 384 Create a Device and Attach It to the Back Buffer . . . . . . . . . . 388 Create a Viewport and Projection Matrix . . . . . . . . . . . . . . 388 x
Contents Putting It All Together . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 Resizing Worries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392 Further Additions to the GameLib . . . . . . . . . . . . . . . . . . . . . . . 393 The D3DX Library. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394 Application: D3D View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395 The .o3d Format. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395 The cModel Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396 Chapter 7 Advanced 3-D Programming . . . . . . . . . . . . . . . . . . . . . . . 407 Animation using Hierarchical Objects . . . . . . . . . . . . . . . . . . . . . . 407 Forward Kinematics . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409 Inverse Kinematics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411 Application: InvKim . . . . . . . . . . . . . . . . . . . . . . . . . 414 Parametric Curves and Surfaces . . . . . . . . . . . . . . . . . . . . . . . . . 417 Bezier Curves and Surfaces . . . . . . . . . . . . . . . . . . . . . . . . 417 Bezier Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . 417 The Math . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420 Finding the Basis Matrix . . . . . . . . . . . . . . . . . . . . . . . 422 Calculating Bezier Curves . . . . . . . . . . . . . . . . . . . . . . 423 Forward Differencing . . . . . . . . . . . . . . . . . . . . . . . . 425 Drawing Curves . . . . . . . . . . . . . . . . . . . . . . . . . . . 429 Drawing Surfaces. . . . . . . . . . . . . . . . . . . . . . . . . . . 430 Application: Teapot. . . . . . . . . . . . . . . . . . . . . . . . . . 431 B-Spline Curves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436 Application: BSpline . . . . . . . . . . . . . . . . . . . . . . . . . 438 Subdivision Surfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439 Subdivision Essentials . . . . . . . . . . . . . . . . . . . . . . . . . . . 440 Triangles vs. Quads . . . . . . . . . . . . . . . . . . . . . . . . . . 442 Interpolating vs. Approximating . . . . . . . . . . . . . . . . . . . 442 Uniform vs. Non-Uniform . . . . . . . . . . . . . . . . . . . . . . 442 Stationary vs. Non-Stationary . . . . . . . . . . . . . . . . . . . . 443 Modified Butterfly Method Subdivision Surfaces . . . . . . . . . . . . . 443 Application: SubDiv . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446 Progressive Meshes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459 Progressive Mesh Basics . . . . . . . . . . . . . . . . . . . . . . . . . . 460 Choosing Our Edges . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461 Stan Melax’s Edge Selection Algorithm . . . . . . . . . . . . . . . 462 Quadric Error Metrics . . . . . . . . . . . . . . . . . . . . . . . . 462 Implementing a Progressive Mesh Renderer . . . . . . . . . . . . . . . 464 Radiosity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466 Radiosity Foundations . . . . . . . . . . . . . . . . . . . . . . . . . . . 467 Progressive Radiosity . . . . . . . . . . . . . . . . . . . . . . . . . . . 470 The Form Factor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470 Application: Radiosity . . . . . . . . . . . . . . . . . . . . . . . . . . . 472 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476 xi
Contents For Further Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477 Chapter 8 Advanced Direct3D. . . . . . . . . . . . . . . . . . . . . . . . . . . . 479 Alpha Blending . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479 The Alpha Blending Equation . . . . . . . . . . . . . . . . . . . . . . . 480 A Note on Depth Ordering . . . . . . . . . . . . . . . . . . . . . . . . 481 Enabling Alpha Blending . . . . . . . . . . . . . . . . . . . . . . . . . . 481 Blending Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481 Texture Mapping 101 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483 Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484 Affine Versus Perspective Mapping . . . . . . . . . . . . . . . . . . . . 486 Texture Addressing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487 Wrap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487 Mirror . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488 Clamp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488 Border Color . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489 Texture Wrapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490 Texture Aliasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490 MIP Maps. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492 Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493 Point Sampling . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493 Bilinear Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . 494 Trilinear Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . 495 Anisotropic Filtering . . . . . . . . . . . . . . . . . . . . . . . . . 496 Textures in Direct3D . . . . . . . . . . . . . . . . . . . . . . . . . . . 497 Texture Management. . . . . . . . . . . . . . . . . . . . . . . . . 497 Texture Loading . . . . . . . . . . . . . . . . . . . . . . . . . . . 499 DDS Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499 The cTexture Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499 Activating Textures . . . . . . . . . . . . . . . . . . . . . . . . . . 508 Texture Mapping 202 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508 Multiple Textures Per Primitive . . . . . . . . . . . . . . . . . . . . . . 509 Texture Transforms. . . . . . . . . . . . . . . . . . . . . . . . . . 518 Effects Using Multiple Textures . . . . . . . . . . . . . . . . . . . 519 Light Maps (a.k.a. Dark Maps) . . . . . . . . . . . . . . . . . . . . 520 Environment Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522 Spherical Environment Maps . . . . . . . . . . . . . . . . . . . . . 522 Cubic Environment Maps . . . . . . . . . . . . . . . . . . . . . . 525 Specular Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529 Detail Maps. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530 Application: Detail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535 Glow Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536 Gloss Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538 Other Effects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 540 Application: MultiTex . . . . . . . . . . . . . . . . . . . . . . . . . . . 540 xii
Contents Pass 1: Base Map . . . . . . . . . . . . . . . . . . . . . . . . . . . 540 Pass 2: Detail Map . . . . . . . . . . . . . . . . . . . . . . . . . . 542 Pass 3: Glow Map . . . . . . . . . . . . . . . . . . . . . . . . . . 544 Pass 4: Environment Map . . . . . . . . . . . . . . . . . . . . . . 547 Pass 5: Gloss Map . . . . . . . . . . . . . . . . . . . . . . . . . . 550 Pass 6: Cloud Map . . . . . . . . . . . . . . . . . . . . . . . . . . 554 Putting Them All Together . . . . . . . . . . . . . . . . . . . . . . 556 A General Purpose Shader Library . . . . . . . . . . . . . . . . . . . . 558 Using the Stencil Buffer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560 Overdraw Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . 562 Dissolves and Wipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563 Stencil Shadows and Stencil Mirrors . . . . . . . . . . . . . . . . . . . 564 Validating Device Capabilities with ValidateDevice() . . . . . . . . . . . . . . 564 For Further Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566 Chapter 9 Scene Management. . . . . . . . . . . . . . . . . . . . . . . . . . . . 567 The Scene Management Problem . . . . . . . . . . . . . . . . . . . . . . . . 567 Solutions to the Scene Management Problem . . . . . . . . . . . . . . . . . 568 Quadtrees/Octrees . . . . . . . . . . . . . . . . . . . . . . . . . . . . 569 Portal Rendering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570 Portal Rendering Concepts . . . . . . . . . . . . . . . . . . . . . 571 Exact Portal Rendering . . . . . . . . . . . . . . . . . . . . . . . . 578 Approximative Portal Rendering . . . . . . . . . . . . . . . . . . . 580 Portal Effects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580 Mirrors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580 Translocators and Non-Euclidean Movement . . . . . . . . . . . . 583 Portal Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585 Precalculated Portal Rendering (PVS) . . . . . . . . . . . . . . . . . . . 586 Advantages/Disadvantages . . . . . . . . . . . . . . . . . . . . . . 587 Implementation Details . . . . . . . . . . . . . . . . . . . . . . . 587 Application: Mobots Attack! . . . . . . . . . . . . . . . . . . . . . . . . . . . 588 Interobject Communication . . . . . . . . . . . . . . . . . . . . . . . . 588 Network Communication . . . . . . . . . . . . . . . . . . . . . . . . . 592 Code Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595 For Further Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595 Closing Thoughts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595 Appendix A An STL Primer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597 Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597 Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598 Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600 Functors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 602 STL Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 602 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603 xiii
This book couldn’t have been completed without the help and guidance of a whole lot of people. I’ll try to remember them all here. First, thanks go to Wes Beckwith and Jim Hill at Wordware Publishing. They were extremely forgiving of my hectic schedule, and they helped guide me to finishing this book. I also must thank Alex Dunne for letting me write an article in 1998 for Game Devel- oper magazine. If I hadn’t written that article, I never would have written this book. Everything I know about the topics in this book I learned from other people. Some of these people were mentors, others were bosses, still others were profes- sors and teachers. Some were just cool people who took the time to sit and talk with me. I can’t thank them enough. Paul Heckbert, Tom Funkhouser, Eric Petajan, Charles Boyd, Mike Toelle, Kent Griffin, David Baraff, Randy Pausch, Howie Choset, Michael Abrash, Hugues Hoppe, and Mark Stehlik: You guys rock, thank you. Thanks to Microsoft, ATI, nVidia, id Software, and Lydia Choy for helping me with some of the images used in the text. A lot of people helped assure the technical correctness and general sanity of this text. Ian Parberry and his class at University of North Texas were immensely helpful: Thanks, guys. Michael Krause was an indispensable help in assuring the correctness of the DirectX chapters. Bob Gaines, Mikey Wetzel, and Jason Sandlin from the DirectX team at Microsoft helped make sure Chapters 2, 6, and 8 were ship-shape: Mad props to them. David Black was kind enough to look over Chapter 9 and help remove some errors and clarify a few points. Finally I need to thank all of the people who helped me get this thing done. I know I won’t be able to remember all of them, but here’s a short list: Manual and Maria Perez, Katherin Peperzak, Lydia Choy (again), Mike Schuresko, Mike Breen (and the rest of the Originals), Vick Mukherjee, Patrick Nelson, Brian Sharp, and Marcin Krieger. xiv
A wise man somewhere, somehow, at some point in history, may have said the best way to start a book is with an anecdote. Never to question the words of a wise man who may or may not have existed, here we go. When I was a freshman in high school back in 1993, I took the required biology class most kids of my age end up having to take. It involved experi- ments, lab reports, dissecting of various animals, and the like. One of my lab partners was a fellow named Chris V. We were both interested in computers, and quickly became friends, to the point where talking about biology in class was second to techno-babble. One night, in the middle of December, Chris called me up. The lab report that was due the next day required results from the experiment we had done together in class, and he had lost his copy of our experiment results. He wanted to know if I could copy mine and bring them over to his place so he could finish writing up the lab. Of course, this was in those heinous pre-car days, so driving to his house required talking my parents into it, finding his address, and various other hardships. While I was willing to do him the favor, I wasn’t willing to do it for free. So I asked him what he could do to reciprocate my kind gesture. “Well,” he said, “I guess I can give you a copy of this game I just got.” “Really? What’s it called?” said I. “Doom. By the Wolf 3-D guys.” “It’s called Doom? What kind of name is that??” After getting the results to his house and the game to mine, I fired the pro- gram up on my creaky old 386 DX-20 clone, burning rubber with a whopping 4 MB of RAM. As my space marine took his first tenuous steps down the corridors infested with hellspawn, my life changed. I had done some programming before in school (Logo and Basic), but after I finished playing the first time, I had a clear picture in my head of what I wanted to do with my life: I wanted to write games, write something like Doom. I popped onto a few local BBoards and asked two questions: what language was the game written in, and what com- piler was used. Within a day or so I purchased Watcom C 10.0 and got my first book on C programming. My first C program was “Hello, World.” My second was a slow, crash-happy, non-robust, wireframe spinning cube. xv
Introduction I tip my hat to John Carmack, John Romero, and the rest of the team behind Doom: My love for creating games was fully realized via their masterpiece. It’s because of them that I learned everything that I have about this exceedingly interesting and dynamic area of computer acquired programming. The knowl- edge I have is what I hope to fill these pages with, so that other people can get into graphics and game programming. I’ve found that the best way to get a lot of useful information down in a short amount of space is to use the tried-and-true FAQ (frequently asked ques- tions) format. I figured if people needed answers to some questions about this book as they stood in their local bookstore trying to decide whether or not to buy it, these would be them. I’ll be the first to say it: I am not a professional game programmer. I hope to be one eventually, but for right now I am but a simple college student. A few years ago I wrote an article for Game Developer that led to the initial discussion with Wordware to write this book. Besides that, I’ve spent summers working at Lucent (in their Graphics department) and at Microsoft (on the Direct3D, Imme- diate Mode team). I’m not claiming to be a “game programming guru,” but I’ve read all I can on a lot of topics and have a lot of practical experience in graphics programming. It wasn’t too long ago that I was learning the ropes, so I’m hoping that explaining some of the pitfalls that I’ve gone through can help other people aspiring to write games. Another thing that I am not is a professional author, nor do I ever plan to be. So I beg that you be quick to forgive any technical and grammatical errors; I assure you that I took every possible means to eliminate both. It seems to be almost a cliché for game programming books to be written by non-game pro- grammers, but I hope I can buck the status quo and create a book that teaches you a lot. I’ve learned from a lot of amazingly brilliant people, covered a lot of difficult ground, and asked a lot of dumb questions. One thing that I’ve found is that the game development industry is all about sharing. If everyone shares, everyone knows more neat stuff and the net knowledge of the industry increases. This is a good thing, because then we all get to play better games. No one person could discover all the principles behind computer graphics and game programming themselves; no one can learn in a vacuum. People took the time to share what xvi
Introduction they learned with me, and now I’m taking the time to share what I’ve learned with you. This book was intended specifically for people who know how to program already, but have taken only rudimentary stabs at graphics/game programming, or have never taken any stab at all. You may be a programmer in another field or a college student looking to embark on some side projects. This book was not designed for beginners. I’m not trying to sound aloof or any- thing; I’m sure if a beginner picks up this book they’ll be able to trudge through it if they feel up to it. However, since I’m so constrained for space, oftentimes I need to breeze past certain concepts (such as inheritance in C++). If you’ve never programmed before, you’ll have an exceedingly difficult time with this book. On the other hand, this book isn’t really designed for professionals either. I’m sure that most people who have pushed games out the door will only find one or two chapters in this book have any material they haven’t seen before. The code was written in C++, using Microsoft Visual C++ 6.0. The .DSPs and .DSWs are provided on the CD; the .DSPs will work with versions previous to 6.0, and the .DSWs will work with 6.0 and up. If you choose to use a different compiler, getting the source code to work should be a fairly trivial task. I specifi- cally wrote this code to use as little non-standard C++ as possible (as far as I know, the only non-standard C++ I use is nameless structures within unions). I chose Win32 as the API environment to use because 90% of computer users currently work on Windows. Win32 is not an easy API to understand, especially after using DOS coding conventions. It isn’t terribly elegant either, but I suppose it could be worse. We could choose other platforms to work on, but doing so reduces our target audience by a factor of 9 or more. If you’ve never heard of Linux, Linux is an open source operating system. This means anyone can download the source to see how the system works, and xvii
Introduction anyone can join teams that work on future versions and make contributions to the operating system. The Linux community has a lot of pride for what it does, and as a result Linux is an incredibly small, fast, and stable operating system. There are a variety of window managers available for download, some that emulate other WMs like Windows or MacOS, some that take new directions (like the ultra-simplistic Blackbox and the uber-complicated Enlightenment). Check out www.linux.org. For those of you who have never used it, OpenGL is another graphics API. Sili- con Graphics designed it in the early ’90s for use on their high-end graphics workstations. It has been ported to countless platforms and operating systems. Outside of the games industry, in areas like simulation and academic research, OpenGL is the de facto standard for doing computer graphics. It is a simple, ele- gant, and fast API. Check out www.opengl.org for more information. But it isn’t perfect. First of all, OpenGL has a large amount of functionality in it. Making the interface so simple requires that the implementation take care of a lot of ugly details to make sure everything works correctly. Because of the way drivers are implemented, each company that makes a 3-D card has to sup- port the entire OpenGL feature set in order to have a fully compliant OpenGL driver. These drivers are extremely difficult to implement correctly, and the per- formance on equal hardware can vary wildly based on driver quality. In addition, DirectX has the added advantage of being able to move quicker to accommodate new hardware features. DirectX is controlled by Microsoft (which can be a good or bad thing, depending on your view of it) while OpenGL extensions need to be deliberated by committees. My initial hope was to have two versions of the source code, one for Win- dows and Direct3D, the other for Linux and OpenGL. This ended up not being possible, so I had to choose one or the other; I chose Direct3D. I had a few other language choices I was kicking around when planning this book. Although there are acolytes out there for Delphi, VB, and even ML, the only languages I seriously considered were C++, Java, and C. Java is designed by Sun Microsystems and is an inherently object-oriented language, with some high-level language features like garbage collection. C is about as low level as programming gets without dipping into assembly. It has very few if any high-level constructs and doesn’t abstract anything away from the programmer. xviii
Introduction C++ is an interesting language because it essentially sits directly between the functionality of the other two languages. C++ supports COM better than C does (this will be more thoroughly discussed in Chapter 1). Also, class systems and operator overloading generally make code easier to read (although of course any good thing can and will be abused). Java, although very cool, is an interpreted language. Every year this seems to be less important: JIT compila- tion gets faster and more grunt work is handed off to the APIs. However, I felt C++ would be a better fit for the book. Java is still a very young language and is still going through a lot of change. That depends. Technically no, you can get by without any accelerator at all, just using Direct3D’s software rasterizer. However, it’s extremely slow, far from real time for anything but trivially simple scenes. It’s almost impossible to buy a computer these days without some sort of 3-D acceleration, and an accelerator capable of handling all the code in this book can be purchased for under $100. Some people see C++ as a divine blade to smite the wicked. They take control of template classes the likes of which you have never seen. They overload the iostream operators for all of their classes. They see multiple inheritance as a hellspawn of satan himself. I see C++ as a tool. The more esoteric features of the language (such as the iostream library), I don’t use at all. Less esoteric fea- tures (like multiple inheritance), I use when it makes sense. To a large degree I’m still a learner. My coding style still leaves a great deal to be desired, but I did everything in my power to make the code clean and easy to read. Having a coding style you stick to is invaluable. The code for this book was written over an eleven-month period, but I can pick up the code I wrote at the beginning and still grok it, because I commented and used some good conventions. If I can understand it, hopefully you can too. One of the greatest books I’ve ever read on programming was Code Complete (Microsoft Press). It’s a handbook on how to program well, not just how to pro- gram. Nuances like the length of variable names, design of subroutines, and length of files are covered in detail in this book; I strongly encourage anyone who wants to become a great programmer to pick it up. You may notice some of the conventions I use in this book are similar to the conventions described in xix
Introduction Code Complete: some of them are borrowed from the great game programmers like John Carmack, and some of them are borrowed from source in DirectX, MFC, and Win32. I’ve tried really hard to make the code in this book accessible to everyone. I comment anything I think is unclear, I strive for good choice in variable names, and I try to make my code look clean while still trying to be fast. Of course, I won’t please everyone. Assuredly, there are some C++ coding standards I’m probably not following correctly. There are some pieces of code that would get much faster with a little obfuscation. If you’ve never used C++ before, or are new to programming, this book is going to be extremely hard to digest. A good discussion on programming essen- tials and the C++ language is C++ Primer (Lippman et al; Addison-Wesley Publishing). Class/structure names MFC names its classes with a prefixed C. As an example, a class that represents the functionality of a button is called CButton. I like this fine, but due to namespace clashing, I instead prefix my own classes with a lowercase c for classes, a lowercase s for structs, a lowercase i for interfaces, and a lowercase e for enumerations (cButton or sButton). There is one notable exception. While most classes are intended to hide functionality away and act as components, there are a few classes/structures that are intended to be instantiated as basic primitives. So for basic mathematic primitives like points and matrices, I have no prefix, and I postfix with the dimension of the primitive (2-D points are point2, 3-D points are point3, etc.). This is to allow them to have the same look and feel as their closest conceptual neighbor, float. For the same reason, all of the mathematic primitives have a lot of overloaded operators to simplify math-laden code. Variable names Semi-long variable names are a good thing. They make your code self-comment itself. One needs to be careful though: make them too long, and they distract from both the code itself and the process of writing it. I use short variables very sporadically; int i, j, k pop up a lot in my code for loops and whatnot, but besides that I strive to give meaningful names to the variables I use. Usually, this means that they have more than one word in them. The system I use specifies lowercase for the first word and initial cap for each word after that, with no underscores (an example would be int numObjects). If the last letter of a word is a capital letter, an underscore is placed to separate it from the next word (example, class cD3D_App). A popular nomenclature for variables is Hungarian notation, which we’ll touch on in Chapter 1. I’m not hardcore about it, but generally my floats are xx
Introduction prefixed with f, my ints with i, and my pointers with p (examples: float fTimer; int iStringSize; char* pBuffer). Note that the prefix counts as the first word, making all words after it caps. (I find pBuffer much more readable than pbuffer.) I also use prefixes to define special qualities of variables. Global variables are preceded with a “g_” (an example would be int g_hInstance); static vari- ables are preceeded with an “s_” (static float s_fTimer); member variables of classes are preceeded with an “m_” (int m_iNumElements). xxi
You can also read