Advanced 3-D Game Pro gramming using DirectX 7.0 - By Adrian Perez, with Dan Royer

Page created by Nelson Sherman
 
CONTINUE READING
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