home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Programming Black Book (Special Edition)
/
BlackBook.bin
/
disk1
/
xsharp22
/
lighting.c
< prev
next >
Wrap
Text File
|
1997-06-18
|
4KB
|
145 lines
/* Lighting control functions. */
#include <stdlib.h>
#include <math.h>
#include "polygon.h"
/* Ambient lighting intensity */
ModelIntensity AmbientIntensity;
/* 1 if ambient shading on, 0 if off */
int AmbientOn;
/* Spotlight direction vectors in world and view coordinates. Spotlights are
defined in world coordinates, but used in view coordinates. Spotlight
directions are reversed in view coordinates, to facilitate incident angle
calculations via the dot product */
Point3 SpotDirectionWorld[MAX_SPOTS];
Point3 SpotDirectionView[MAX_SPOTS];
/* Spotlight intensities */
ModelIntensity SpotIntensity[MAX_SPOTS];
/* Spotlight on/off statuses, defaulting to off */
int SpotOn[MAX_SPOTS] = {0, 0, 0};
/* Sets the ambient lighting level. */
void SetAmbientIntensity(ModelIntensity * Intensity)
{
AmbientIntensity = *Intensity;
}
/* Returns the ambient lighting level. */
ModelIntensity * GetAmbientIntensity()
{
return(&AmbientIntensity);
}
/* Turns ambient shading on */
void TurnAmbientOn()
{
AmbientOn = 1;
}
/* Turns ambient shading off */
void TurnAmbientOff()
{
AmbientOn = 0;
}
/* Returns the ambient on/off status (1=on, 0=off). */
int GetAmbientState()
{
return(AmbientOn);
}
/* Sets the unit vector defining a spotlight's direction. Spotlights are
considered to be infinitely far away, so the light rays are parallel and
do not vary in angle anywhere in the scene. Vectors are reversed in view
space to facilitate angle calculations. The passed-in vector does not
have to be a unit vector. */
void SetSpotDirection(int SpotNumber, Point3 * SpotVector)
{
double Xlen, Ylen, Zlen, Length;
if ((SpotNumber < 0) || (SpotNumber >= MAX_SPOTS))
return; /* bad spot number */
/* Convert the direction vector to a unit vector, so we can do fast
shading calculations. First, calculate the length of the vector */
Xlen = FIXED_TO_DOUBLE(SpotVector->X);
Ylen = FIXED_TO_DOUBLE(SpotVector->Y);
Zlen = FIXED_TO_DOUBLE(SpotVector->Z);
Length = sqrt(Xlen*Xlen + Ylen*Ylen + Zlen*Zlen);
/* Scale it to a unit vector and offset it from the start point. Flip the
vector's direction for use in shading calculations */
SpotDirectionWorld[SpotNumber].X = DOUBLE_TO_FIXED(Xlen/Length);
SpotDirectionWorld[SpotNumber].Y = DOUBLE_TO_FIXED(Ylen/Length);
SpotDirectionWorld[SpotNumber].Z = DOUBLE_TO_FIXED(Zlen/Length);
/* Finally, convert the vector into view space, where we'll actually apply
the shading */
XformVec(WorldViewXform, (Fixedpoint *) &SpotDirectionWorld[SpotNumber],
(Fixedpoint *) &SpotDirectionView[SpotNumber]);
/* Flip the spot direction vector in view space, for ease of shading
calculations */
SpotDirectionView[SpotNumber].X = -SpotDirectionView[SpotNumber].X;
SpotDirectionView[SpotNumber].Y = -SpotDirectionView[SpotNumber].Y;
SpotDirectionView[SpotNumber].Z = -SpotDirectionView[SpotNumber].Z;
}
/* Sets the intensity of a spotlight. */
void SetSpotIntensity(int SpotNumber, ModelIntensity * Intensity)
{
ModelIntensity * SpotIntensityPtr;
if ((SpotNumber < 0) || (SpotNumber >= MAX_SPOTS))
return; /* bad spot number */
SpotIntensity[SpotNumber] = *Intensity;
}
/* Turns on the specified spotlight. */
void TurnSpotOn(int SpotNumber)
{
if ((SpotNumber < 0) || (SpotNumber >= MAX_SPOTS))
return; /* bad spot number */
SpotOn[SpotNumber] = 1;
}
/* Turns off the specified spotlight. */
void TurnSpotOff(int SpotNumber)
{
if ((SpotNumber < 0) || (SpotNumber >= MAX_SPOTS))
return; /* bad spot number */
SpotOn[SpotNumber] = 0;
}
/* Returns a spot's unit direction vector in world space. */
Point3 * GetSpotDirection(int SpotNumber)
{
if ((SpotNumber < 0) || (SpotNumber >= MAX_SPOTS))
return(NULL); /* bad spot number */
return(&SpotDirectionWorld[SpotNumber]);
}
/* Returns a spot's intensity. */
ModelIntensity * GetSpotIntensity(int SpotNumber)
{
if ((SpotNumber < 0) || (SpotNumber >= MAX_SPOTS))
return(NULL); /* bad spot number */
return(&SpotIntensity[SpotNumber]);
}
/* Returns a spot's on/off status (1=on, 0=off). */
int GetSpotState(int SpotNumber)
{
if ((SpotNumber < 0) || (SpotNumber >= MAX_SPOTS))
return(0); /* bad spot number */
return(SpotOn[SpotNumber]);
}