Learning Modern 3D Graphics Programming

Jason L. McKesson

Learning Modern 3D Graphics Programming

Jason L. McKesson
Copyright © 2012 Jason L. McKesson

iii

Table of Contents

About  this  Book  ....................................................................................................................................................................   iv

Why  Read  This  Book?  ...................................................................................................................................................   iv
What  You  Need  .............................................................................................................................................................   v
Organization  of  This  Book  
...............................................................................................................................................   v
Conventions  used  in  This  Book  .......................................................................................................................................   vi

Building  the  Tutorials  .............................................................................................................................................................   1
I.  The  Basics  .........................................................................................................................................................................   3

Introduction  ...................................................................................................................................................................   4
1.  Hello,  Triangle!  ........................................................................................................................................................   21
2.  Playing  with  Colors  ...................................................................................................................................................   34

II.  Positioning  ......................................................................................................................................................................   43

3.  OpenGL's  Moving  Triangle  ........................................................................................................................................   44
4.  Objects  at  Rest  .........................................................................................................................................................   54
5.  Objects  in  Depth  .......................................................................................................................................................   74
6.  Objects  in  Motion  .....................................................................................................................................................   97
7.  World  in  Motion  .....................................................................................................................................................   121
8.  Getting  Oriented  ......................................................................................................................................................  142

III.  Illumination  ..................................................................................................................................................................   158

9.  Lights  On  ...............................................................................................................................................................  159
10.  Plane  Lights  ..........................................................................................................................................................  185
11.  Shinies  .................................................................................................................................................................   208
12.  Dynamic  Range  .....................................................................................................................................................   229
13.  Lies  and  Impostors  .................................................................................................................................................  247

IV.  Texturing  .....................................................................................................................................................................   266

14.  Textures  are  not  Pictures  .........................................................................................................................................   267
15.  Many  Images  ........................................................................................................................................................   289
16.  Gamma  and  Textures  .............................................................................................................................................   311
17.  Spotlight  on  Textures  .............................................................................................................................................   320

V.  Framebuffer  ...................................................................................................................................................................   339
VI.  Advanced  Lighting  ........................................................................................................................................................   340
A.  Further  Study  .................................................................................................................................................................   341

Topics  of  Interest  ........................................................................................................................................................   341

B.  History  of  PC  Graphics  Hardware  .....................................................................................................................................   343

Voodoo  Magic  ............................................................................................................................................................   343
Dynamite  Combiners
  ...................................................................................................................................................   343
Vertices  and  Registers  .................................................................................................................................................   345
Programming  at  Last  ...................................................................................................................................................   346
Dependency  ...............................................................................................................................................................   348
Modern  Unification  .....................................................................................................................................................   349

C.  Getting  Started  with  OpenGL  ............................................................................................................................................  352

Manual  Usage  ............................................................................................................................................................   352

iv

About this Book

Three dimensional graphics hardware is fast becoming, not merely a staple of computer systems, but an indispensable component. Many operating
systems directly use and even require some degree of 3D rendering hardware. Even in the increasingly important mobile computing space, 3D
graphics hardware is a standard feature of all but the lowest power devices.

Understanding how to make the most of that hardware is a difficult challenge, particularly for someone new to graphics and rendering.

Why Read This Book?

There are many physical books for teaching graphics. There are many more online repositories of knowledge, in the form of wikis, blogs, tutorials,
and forums. So what does this book offer that others do not?

Programmability. Virtually all of the aforementioned sources instruct beginners using something called “fixed functionality.” This represents
configurations in older graphics processors that define how a particular rendering operation will proceed. It is generally considered easiest to
teach neophyte graphics programmers using the fixed function pipeline.

This is considered true because it is easy to get something to happen with fixed functionality. It's simpler to make pictures that look like something
real. The fixed function pipeline is like training wheels for a bicycle.

There are downsides to this approach. First, much of what is learned with this approach must be inevitably abandoned when the user encounters a
graphics problem that must be solved with programmability. Programmability wipes out almost all of the fixed function pipeline, so the knowledge
does not easily transfer.

A more insidious problem is that the fixed function pipeline can give the illusion of knowledge. A user can think they understand what they
are doing, but they're really just copy-and-pasting code around. Programming thus becomes akin to magical rituals: you put certain bits of code
before other bits, and everything seems to work.

This makes debugging nightmarish. Because the user never really understood what the code does, the user is unable to diagnose what a particular
problem could possibly mean. And without that ability, debugging becomes a series of random guesses as to what the problem is.

By contrast, you cannot use a programmable system successfully without first understanding it. Confronting programmable graphics hardware
means confronting issues that fixed function materials often gloss over. This may mean a slower start overall, but when you finally get to the
end, you truly know how everything works.

Another problem is that, even if you truly understand the fixed function pipeline, it limits how you think about solving problems. Because of
its inflexibility, it focuses your mind along certain problem solving possibilities and away from others. It encourages you to think of textures as
pictures; vertex data as texture coordinates, colors, or positions; and the like. By its very nature, it limits creativity and problem solving.

Lastly, even on mobile systems, fixed functionality is generally not available in the graphics hardware. Programmability is the order of the day
for most graphics hardware, and this will only become more true in the future.

What this book offers is beginner-level instruction on what many consider to be an advanced concept. It teaches programmable rendering for
beginning graphics programmers, from the ground up.

This book also covers some important material that is often neglected or otherwise relegated to “advanced” concepts. These concepts are not truly
advanced, but they are often ignored by most introductory material because they do not work with the fixed function pipeline.

This book is first and foremost about learning how to be a graphics programmer. Therefore, whenever it is possible and practical, this book will
present material in a way that encourages the reader to examine what graphics hardware can do in new and interesting ways. A good graphics
programmer sees the graphics hardware as a set of tools to fulfill their needs, and this book tries to encourage this kind of thinking.

One thing this book is not, however, is a book on graphics APIs. While it does use OpenGL and out of necessity teach rendering concepts in
terms of OpenGL, it is not truly a book that is about OpenGL. It is not the purpose of this book to teach you all of the ins and outs of the OpenGL
API.There will be parts of OpenGL functionality that are not dealt with because they are not relevant to any of the lessons that this book teaches.
If you already know graphics and are in need of a book that teaches modern OpenGL programming, this is not it. It may be useful to you in that
capacity, but that is not this book's main thrust.

About this Book

v

This book is intended to teach you how to be a graphics programmer. It is not aimed at any particular graphics field; it is designed to cover most
of the basics of 3D rendering. So if you want to be a game developer, a CAD program designer, do some computer visualization, or any number
of things, this book can still be an asset for you.

This does not mean that it covers everything there is about 3D graphics. Hardly. It tries to provide a sound foundation for your further exploration
in whatever field of 3D graphics you are interested in.

One  topic  this  book  does  not  cover  in  depth  is  optimization.  The  reason  for  this  is  simply  that  serious  optimization  is  an  advanced  topic.
Optimizations can often be platform-specific, different for different kinds of hardware. They can also be API-specific, as some APIs have different
optimization needs. Optimizations may be mentioned here and there, but it is simply too complex of a subject for a beginning graphics programmer.
There is a chapter in the appendix covering optimization opportunities, but it only provides a fairly high-level look.

What You Need

This is a book for beginning graphics programmers; it can also serve as a book for those familiar with fixed functionality who want to understand
programmable rendering better. But this is not a book for beginning programmers.

You are expected to be able to read C and reasonable C++ code. If “Hello, world!” is the extent of your C/C++ knowledge, then perhaps you should
write some more substantial code before proceeding with trying to render images. 3D graphics rendering is simply not a beginner programming
task; this is just as true for traditional graphics learning as for modern graphics learning.

These tutorials should be transferable to other languages as well. If you can read C/C++, that is enough to understand what the code is doing. The
text descriptions that explain what the code does are also sufficient to get information out of these tutorials.

Any  substantial  discussion  of  3D  rendering  requires  a  discussion  of  mathematics,  which  are  at  the  foundation  of  all  3D  graphics.  This  book
expects you to know basic geometry and algebra.

The tutorials will present the more advanced math needed for graphics as it becomes necessary, but you should have at least a working knowledge
of geometry and algebra. Linear algebra is not required, though it would be helpful.

The code tutorials in this book use OpenGL as their rendering API. You do not need to know OpenGL, but to execute the code, you must have a
programming environment that allows OpenGL. Specifically, you will need hardware capable of running OpenGL version 3.3. This means any
GeForce 8xxx or better, or any Radeon HD-class card. These are also called “Direct3D 10” cards, but you do not need Windows Vista or 7 to
use their advanced features through OpenGL.

Organization of This Book

This book is broken down into a number of general subjects. Each subject contains several numbered chapters called tutorials. Each tutorial
describes several related concepts. In virtually every case, each concept is demonstrated by a companion set of code.

Each tutorial begins with an overview of the concepts that will be discussed and demonstrated. At the end of each tutorial is a review section
and a glossary of all terms introduced in that tutorial. The review section will explain the concepts presented in the tutorial. It will also contain
suggestions for playing with the source code itself; these are intended to further your understanding of these concepts. If the tutorial introduced
new OpenGL functions or functions for the OpenGL shading language, they will be reviewed here as well.

This  is  a  book  for  beginning  graphics  programmers.  Graphics  is  a  huge  topic,  and  this  book  will  not  cover  every  possible  effect,  feature,  or
technique. This book will also not cover every technique in full detail. Sometimes techniques will be revisited in later materials, but there simply
isn't  enough  space  to  say  everything  about  everything.  Therefore,  when  certain  techniques  are  introduced,  there  will  be  a  section  at  the  end
providing some cursory examination of more advanced techniques. This will help you further your own research into graphics programming, as
you will know what to search for online or in other books.

Each tutorial ends with a glossary of all of the terms defined in that tutorial.

Browser Note

This website and these tutorials make extensive use of SVG images. Basic SVG support is in all major browsers except all Internet
Explorer versions before version 9. If you are content with these versions of Internet Explorer (or unable to upgrade), consider installing
the Google Chrome Frame add-on for IE8. This will allow you to see the images correctly.

About this Book

vi

Conventions used in This Book

Text in this book is styled along certain conventions. The text styling denotes what the marked-up text represents.

• defined term: This term will have a definition in the glossary at the end of each tutorial.

FunctionNames

: These can be in C, C++, or the OpenGL Shading Language.

nameOfVariable

: These can be in C, C++, or the OpenGL Shading Language.

GL_ENUMERATORS

Names/Of/Paths/And/Files

• K: The keyboard key “K,” which is not the same as the capital letter “K”. The latter is what you get by pressing Shift+K.

1

Building the Tutorials

These tutorials require a number of external libraries in order to function. The specific version of these libraries that the tutorials use are distributed
with the tutorials. The tutorial source distribution [http://bitbucket.org/alfonse/gltut/downloads] can be found online. This section will describe
each of the external libraries, how to build them, and how to build the tutorials themselves. Windows and Linux builds are supported.

You will need minimal familiarity with using the command line in order to build these tutorials. Also, any mention of directories is always relative
to where you unzipped this distribution.

File Structure

The layout of the files in the tutorial directory is quite simple. The 

framework

 directory and all directories of the form 

Tut*

 contain all of the

source code for the tutorials themselves. Each 

Tut*

 directory has the code for the various tutorials. The 

framework

 directory simply contains

utility code that is commonly used by each tutorial.

Each tutorial contains one or more projects; each project is referenced in the text for that tutorial.

The 

Documents

 directory contains the source for the text documentation explaining how these tutorials work. This source is in xml files using

the DocBook 5.0 format.

Every other directory contains the code and build files for a library that the tutorials require.

Necessary Utilities

In order to build everything, you will need to download the Premake 4 [http://industriousone.com/premake] utility for your platform of choice.

Premake is a utility like CMake [http://www.cmake.org/]: it generates build files for a specific platform. Unlike CMake, Premake is strictly a
command-line utility. Premake's build scripts are written in the Lua language [http://www.lua.org/home.html], unlike CMake's build scripts that
use their own language.

Note that Premake only generates build files; once the build files are created, you can use them as normal. It can generate project files for Visual
Studio, Code::Blocks [http://www.codeblocks.org/], and XCode, as well as GNU Makefiles. And unless you want to modify one of the tutorials,
you only need to run Premake once for each tutorial.

The Premake download comes as a pre-built executable for all platforms of interest, including Linux.

Unofficial OpenGL SDK

The Unofficial OpenGL SDK [http://glsdk.sourceforge.net/docs/html/index.html] is an aggregation of libraries, unifying a number of tools for
developing OpenGL applications, all bound together with a unified build system. A modified SDK distribution is bundled with these tutorials;
this distro does not contain the documentation or GLFW that comes with the regular SDK.

The SDK his library uses Premake to generate its build files. So, with premake4.exe in your path, go to the 

glsdk

 directory. Type 

premake4

plat

, where 

plat

 is the name of the platform of choice. For Visual Studio 2008, this would be “vs2008”; for VS2010, this would be “vs2010.”

This will generate Visual Studio projects and solution files for that particular version.

For GNU and makefile-based builds, this is “gmake”. This will generate a makefile. To build for debug, use 

make config=debug

; similarly,

to build for release, use 

make config=release

.

Using the generated build files, compile for both debug and release. You should build the entire solution; the tutorials use all of the libraries
provided.

Note that there is no execution of 

make  install

 or similar constructs. The SDK is designed to be used where it is; it does not install itself

to any system directories on your machine. Incidentally, neither do these tutorials.

Building the Tutorials

2

Tutorial Building

Each tutorial directory has a 

premake4.lua

 file; this file is used by Premake to generate the build files for that tutorial. Therefore, to build

any tutorial, you need only go to that directory and type 

premake4 plat

, then use those build files to build the tutorial.

Each tutorial will generally have more than one source file and generate multiple executables. Each executable represents a different section of
the tutorial, as explained in that tutorial's documentation.

If you want to build all of the tutorials at once, go to the root directory of the distribution and use Premake on the 

premake4.lua

 file in that

directory. It will put all of the tutorials into one giant project that you can build.

If you look at any of the tutorial source files, you will not find the 

main

 function defined anywhere. This function is defined in 

framework/

framework.cpp

; it and all of the other source files in the 

framework

 directory is shared by every tutorial. It does the basic boilerplate work:

creating a FreeGLUT window, etc. This allows the tutorial source files to focus on the useful OpenGL-specific code.

Part I. The Basics

Graphics programming can be a daunting task when starting out. The rendering pipeline involves a large number of steps, each dealing with a
variety of math operations. It has stages that run actual programs to compute results for the next. Mastering this pipeline, being able to use it as
a tool to achieve a visual effect, is the essence of being a graphics programmer.

This section of the book will introduce the basic math necessary for 3D graphics. It will introduce the rendering pipeline as defined by OpenGL.
And it will demonstrate how data flows through the graphics pipeline.

4

Introduction

Unlike most sections of this text, there is no source code or project associated with this section. Here, we will be discussing vector math, graphical
rendering theory, and OpenGL. This serves as a primer to the rest of the book.

Vector Math

This book assumes that you are familiar with algebra and geometry, but not necessarily with vector math. Later material will bring you up to
speed on more complex subjects, but this will introduce the basics of vector math.

vector can have many meanings, depending on whether we are talking geometrically or numerically. In either case, vectors have dimensionality;
this represents the number of dimensions that the vector has. A two-dimensional vector is restricted to a single plane, while a three-dimensional
vector can point in any physical space. Vectors can have higher dimensions, but generally we only deal with dimensions between 2 and 4.

Technically, a vector can have only one dimension. Such a vector is called a scalar.

In terms of geometry, a vector can represent one of two concepts: a position or a direction within a particular space. A vector position represents
a specific location in space. For example, on this graph, we have a vector position A:

Figure 1. Position Vectors

A

B

C

A vector can also represent a direction. Direction vectors do not have an origin; they simply specify a direction in space. These are all direction
vectors, but the vectors B and D are the same, even though they are drawn in different locations: