home *** CD-ROM | disk | FTP | other *** search
/ Graphics Programming Black Book (Special Edition) / BlackBook.bin / disk1 / xsharp22 / lighting.c < prev    next >
Text File  |  1997-06-18  |  4KB  |  145 lines

  1. /* Lighting control functions. */
  2.  
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include "polygon.h"
  6.  
  7. /* Ambient lighting intensity */
  8. ModelIntensity AmbientIntensity;
  9.  
  10. /* 1 if ambient shading on, 0 if off */
  11. int AmbientOn;
  12.  
  13. /* Spotlight direction vectors in world and view coordinates. Spotlights are
  14.    defined in world coordinates, but used in view coordinates.  Spotlight
  15.    directions are reversed in view coordinates, to facilitate incident angle
  16.    calculations via the dot product */
  17. Point3 SpotDirectionWorld[MAX_SPOTS];
  18. Point3 SpotDirectionView[MAX_SPOTS];
  19.  
  20. /* Spotlight intensities */
  21. ModelIntensity SpotIntensity[MAX_SPOTS];
  22.  
  23. /* Spotlight on/off statuses, defaulting to off */
  24. int SpotOn[MAX_SPOTS] = {0, 0, 0};
  25.  
  26. /* Sets the ambient lighting level. */
  27. void SetAmbientIntensity(ModelIntensity * Intensity)
  28. {
  29.    AmbientIntensity = *Intensity;
  30. }
  31.  
  32. /* Returns the ambient lighting level. */
  33. ModelIntensity * GetAmbientIntensity()
  34. {
  35.    return(&AmbientIntensity);
  36. }
  37.  
  38. /* Turns ambient shading on */
  39. void TurnAmbientOn()
  40. {
  41.    AmbientOn = 1;
  42. }
  43.  
  44. /* Turns ambient shading off */
  45. void TurnAmbientOff()
  46. {
  47.    AmbientOn = 0;
  48. }
  49.  
  50. /* Returns the ambient on/off status (1=on, 0=off). */
  51. int GetAmbientState()
  52. {
  53.    return(AmbientOn);
  54. }
  55.  
  56. /* Sets the unit vector defining a spotlight's direction. Spotlights are
  57.    considered to be infinitely far away, so the light rays are parallel and
  58.    do not vary in angle anywhere in the scene. Vectors are reversed in view
  59.    space to facilitate angle calculations. The passed-in vector does not
  60.    have to be a unit vector. */
  61. void SetSpotDirection(int SpotNumber, Point3 * SpotVector)
  62. {
  63.    double Xlen, Ylen, Zlen, Length;
  64.  
  65.    if ((SpotNumber < 0) || (SpotNumber >= MAX_SPOTS))
  66.       return;  /* bad spot number */
  67.  
  68.    /* Convert the direction vector to a unit vector, so we can do fast
  69.       shading calculations. First, calculate the length of the vector */
  70.    Xlen = FIXED_TO_DOUBLE(SpotVector->X);
  71.    Ylen = FIXED_TO_DOUBLE(SpotVector->Y);
  72.    Zlen = FIXED_TO_DOUBLE(SpotVector->Z);
  73.    Length = sqrt(Xlen*Xlen + Ylen*Ylen + Zlen*Zlen);
  74.  
  75.    /* Scale it to a unit vector and offset it from the start point. Flip the
  76.       vector's direction for use in shading calculations */
  77.    SpotDirectionWorld[SpotNumber].X = DOUBLE_TO_FIXED(Xlen/Length);
  78.    SpotDirectionWorld[SpotNumber].Y = DOUBLE_TO_FIXED(Ylen/Length);
  79.    SpotDirectionWorld[SpotNumber].Z = DOUBLE_TO_FIXED(Zlen/Length);
  80.  
  81.    /* Finally, convert the vector into view space, where we'll actually apply
  82.       the shading */
  83.    XformVec(WorldViewXform, (Fixedpoint *) &SpotDirectionWorld[SpotNumber],
  84.          (Fixedpoint *) &SpotDirectionView[SpotNumber]);
  85.    /* Flip the spot direction vector in view space, for ease of shading
  86.       calculations */
  87.    SpotDirectionView[SpotNumber].X = -SpotDirectionView[SpotNumber].X;
  88.    SpotDirectionView[SpotNumber].Y = -SpotDirectionView[SpotNumber].Y;
  89.    SpotDirectionView[SpotNumber].Z = -SpotDirectionView[SpotNumber].Z;
  90. }
  91.  
  92. /* Sets the intensity of a spotlight. */
  93. void SetSpotIntensity(int SpotNumber, ModelIntensity * Intensity)
  94. {
  95.    ModelIntensity * SpotIntensityPtr;
  96.  
  97.    if ((SpotNumber < 0) || (SpotNumber >= MAX_SPOTS))
  98.       return;  /* bad spot number */
  99.  
  100.    SpotIntensity[SpotNumber] = *Intensity;
  101. }
  102.  
  103. /* Turns on the specified spotlight. */
  104. void TurnSpotOn(int SpotNumber)
  105. {
  106.    if ((SpotNumber < 0) || (SpotNumber >= MAX_SPOTS))
  107.       return;  /* bad spot number */
  108.  
  109.    SpotOn[SpotNumber] = 1;
  110. }
  111.  
  112. /* Turns off the specified spotlight. */
  113. void TurnSpotOff(int SpotNumber)
  114. {
  115.    if ((SpotNumber < 0) || (SpotNumber >= MAX_SPOTS))
  116.       return;  /* bad spot number */
  117.  
  118.    SpotOn[SpotNumber] = 0;
  119. }
  120.  
  121. /* Returns a spot's unit direction vector in world space. */
  122. Point3 * GetSpotDirection(int SpotNumber)
  123. {
  124.    if ((SpotNumber < 0) || (SpotNumber >= MAX_SPOTS))
  125.       return(NULL);  /* bad spot number */
  126.    return(&SpotDirectionWorld[SpotNumber]);
  127. }
  128.  
  129. /* Returns a spot's intensity. */
  130. ModelIntensity * GetSpotIntensity(int SpotNumber)
  131. {
  132.    if ((SpotNumber < 0) || (SpotNumber >= MAX_SPOTS))
  133.       return(NULL);  /* bad spot number */
  134.    return(&SpotIntensity[SpotNumber]);
  135. }
  136.  
  137. /* Returns a spot's on/off status (1=on, 0=off). */
  138. int GetSpotState(int SpotNumber)
  139. {
  140.    if ((SpotNumber < 0) || (SpotNumber >= MAX_SPOTS))
  141.       return(0);  /* bad spot number */
  142.    return(SpotOn[SpotNumber]);
  143. }
  144.  
  145.