Some additional operators are defined in bSphere3.h, and plane-sphere
classification code is in plane3.h as well. See the downloadable files for
more detail.
Lighting your scenes is a prerequisite if you want them to look realistic.
Lighting is a fairly slow and complex system, especially when modeling
light correctly (this doesn’t happen too often). Later in the book I’ll discuss
some advanced lighting schemes, including radiosity. I’ll discuss two points
in this section: how to acquire the amount of light hitting a point in 3D,
and how to shade a triangle with those three points. We’ll look at much
more advanced lighting using HLSL later also.
Representing Color
Before you can go about giving color to anything in a scene, you need to
know how to represent color! Usually you use the same red, green, and
blue channels discussed in Chapter 2, but for lighting purposes there will
also be a fourth component called alpha. The alpha component stores
transparency information about a texture. It’s discussed more in detail in
Chapter 9, but for right now let’s plan ahead. There will be two structures
to ease the color duties: color3 and color4. They both use floating-point
values for their components; color3 has red, green, and blue, while color4
has the additional fourth component of alpha.
Colors aren’t like points—they have a fixed range. Each component
can be anything from 0.0 to 1.0 (zero contribution of the channel or com-
plete contribution). If performing operations on colors, such as adding
them together, the components may rise above 1.0 or below 0.0. Before
trying to use a color, for example feeding it to Direct3D, it needs to be sat
urated. That is what the Sat() function does. The conversions to unsigned
longs will be used in Chapter 7, when the colors start to get plugged into
The code for color4 follows. I’ve left out a few routine bits to keep the
listing focused.
struct color4
union {
float r, g, b, a; // Red, Green, Blue, and Alpha color data
float c[4];
178 n Chapter 4: 3D Math Foundations
color4( float inR, float inG, float inB, float inA ) :
r( inR ), g( inG ), b( inB ), a( inA )
color4( const color3& in, float alpha = 1.f )
r = in.r;
g = in.g;
b = in.b;
a = alpha;
color4( unsigned long color )
b = (float)(color&255) / 255.f;
color >>= 8;
g = (float)(color&255) / 255.f;
color >>= 8;
r = (float)(color&255) / 255.f;
color >>= 8;
a = (float)(color&255) / 255.f;
void Assign( float inR, float inG, float inB, float inA )
r = inR;
g = inG;
b = inB;
a = inA;
unsigned long MakeDWord()
unsigned long iA = (int)(a * 255.f ) << 24;
unsigned long iR = (int)(r * 255.f ) << 16;
unsigned long iG = (int)(g * 255.f ) << 8;
unsigned long iB = (int)(b * 255.f );
return iA | iR | iG | iB;
unsigned long MakeDWordSafe()
color4 temp = *this;
return temp.MakeDWord();
// if any of the values are >1, cap them.
void Sat()
Chapter 4: 3D Math Foundations n 179

Get Advanced 3D Game Programming with DirectX 10.0 now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.