Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gl_light_state.cpp File Reference
#include <assert.h>
#include <cstring>
#include "gl_globals.h"
#include "hashtable_3d.h"
#include "gl_light.h"
#include <math.h>
#include "gfx/matrix.h"

Go to the source code of this file.

Macros

#define M_PI   3.14159265358979323846264338328
 
#define GFX_HARDWARE_LIGHTING
 

Functions

void GFXUploadLightState (int max_light_location, int active_light_array, int apparent_light_size_array, bool shader, vector< int >::const_iterator begin, vector< int >::const_iterator end)
 
int findLocalClobberable ()
 Finds the local lights that are clobberable for new lights (permanent perhaps) More...
 
static int findGlobalClobberable ()
 
void light_rekey_frame ()
 Rekeys a frame, remembering trashing old lights activated last frame. More...
 

Variables

const float atten0scale = 1
 
const float atten1scale = 1./GFX_SCALE
 
const float atten2scale = 1./(GFX_SCALE*GFX_SCALE)
 
int _GLLightsEnabled = 0
 How many lights are enabled (for fast picking) More...
 
Hashtable3d< LineCollideStar,
20, CTACC, lighthuge
lighttable
 table to store local lights, numerical pointers to _llights (eg indices) More...
 

Macro Definition Documentation

#define GFX_HARDWARE_LIGHTING

Definition at line 139 of file gl_light_state.cpp.

#define M_PI   3.14159265358979323846264338328

Definition at line 11 of file gl_light_state.cpp.

Referenced by GFXUploadLightState().

Function Documentation

static int findGlobalClobberable ( )
static

Definition at line 173 of file gl_light_state.cpp.

References GFX_MAX_LIGHTS, OpenGLL::GLL_LOCAL, OpenGLL::GLL_ON, GLLights, i, and index.

Referenced by gfx_light::Create(), and gfx_light::Enable().

174 {
175  //searches through the GLlights and sees which one is clobberable. Returns -1 if not.
176  int clobberdisabled = -1;
177  int clobberlocal = -1;
178  for (int i = 0; i < GFX_MAX_LIGHTS; i++) {
179  if (GLLights[i].index == -1)
180  return i;
181  if (GLLights[i].options&OpenGLL::GLL_LOCAL)
182  clobberlocal = i;
183  if ( !(GLLights[i].options&OpenGLL::GLL_ON) )
184  if (clobberlocal == i || clobberdisabled == -1)
185  clobberdisabled = i;
186  }
187  return (clobberdisabled == -1) ? clobberlocal : clobberdisabled;
188 }
int findLocalClobberable ( )

Finds the local lights that are clobberable for new lights (permanent perhaps)

Definition at line 161 of file gl_light_state.cpp.

References GFX_MAX_LIGHTS, OpenGLL::GLL_ON, GLLights, i, and index.

Referenced by gfx_light::Create(), and gfx_light::dopickenables().

162 {
163  int clobberdisabled = -1;
164  for (int i = 0; i < GFX_MAX_LIGHTS; i++) {
165  if (GLLights[i].index == -1)
166  return i;
167  if ( !(GLLights[i].options&OpenGLL::GLL_ON) )
168  clobberdisabled = i;
169  }
170  return clobberdisabled;
171 }
void GFXUploadLightState ( int  max_light_location,
int  active_light_array,
int  apparent_light_size_array,
bool  shader,
vector< int >::const_iterator  begin,
vector< int >::const_iterator  end 
)

Definition at line 14 of file gl_light_state.cpp.

References gfx_light::ContextSwitchClobberLight(), gfx_light::enabled(), float, GFXLight::getPosition(), GFXLight::getSize(), GFX_MAX_LIGHTS, GFXGetMatrixModel(), GFXLoadIdentity(), GFXLoadMatrixModel(), GFXShaderConstant4v(), GFXShaderConstanti(), GFXShaderConstantv(), i, M_PI, MODEL, Matrix::p, QVector, and UniverseUtil::sqrt().

15 {
16  // FIXME: (klauss) Very bad thing: static variables initialized with heap-allocated arrays...
17  static GLint *lightData = new GLint[GFX_MAX_LIGHTS];
18  static float *lightSizes = new float[GFX_MAX_LIGHTS*4];
19 
20  Matrix modelview;
21 
22  // if we're using shaders, we'll need the modelview matrix
23  // to properly compute light-model apparent light sizes
24  GFXGetMatrixModel(modelview);
25 
26  size_t maxval = 0;
27  size_t i = 0;
28 
29  for (vector<int>::const_iterator lightit = begin; lightit != end; ++i, ++lightit) {
30  const gfx_light &light = (*_llights)[*lightit];
31  if (light.enabled()) {
32  lightData[i] = 1;
33  maxval = i;
34 
35  // Only bother with apparent light size if there is a shader
36  if (shader) {
37  // We'll compute apparent light size by transforming the origin
38  // position by the modelview matrix, and computing the apparent
39  // size of a lightsource to that center and the proper size
40  // as entered in _gllights.
41  //
42  // This assumes the modelview matrix will be already set to
43  // the proper value when the light is enabled. It should.
44  //
45  // NOTE: We explicitly ignore rotation and scaling parts of the
46  // matrix. For one, rotation is meaningless for this calculation.
47  // For two, scaling would be nullified when scaling both distance
48  // and light size, so it would only waste time.
49 
50  QVector lightPos = light.getPosition() - modelview.p;
51 
52  double lightDistance = lightPos.Magnitude();
53  double lightSize = light.getSize() * 0.5;
54  double lightCosAngle;
55  double lightSolidAngle;
56  if (lightSize <= 0.0) {
57  // Point light always has zero solid angle
58  lightCosAngle = 1.0;
59  lightSolidAngle = 0.0;
60  } else {
61  // NOTE: assuming lightSize > 0, the following condition
62  // assures a nonzero distance to light, which would produce
63  // NaNs in the following math.
64  if (lightDistance > lightSize) {
65  // Light cos angle is:
66  // Vector(1, 0, 0) . Vector(lightDistance, lightSize, 0).Normalize()
67  // Which happens to resolve to:
68  //lightCosAngle = float(lightDistance / (lightDistance + lightSize));
69  lightCosAngle = lightDistance / sqrt( lightDistance*lightDistance + lightSize*lightSize );
70  lightSolidAngle = 2.0 * M_PI * ( 1.0 - lightCosAngle );
71  // Light steradians is:
72  // Steradians = Fractional Area * 4 * Pi
73  // Fractional Area = Apparent light area / Sky area at light distance
74  // Apparent light area = Pi * lightSize^2
75  // Sky area = 4 * Pi * lightDistance^2
76  // Do the math...
77  /*lightSolidAngle = float(M_PI
78  * ( lightSize / lightDistance )
79  * ( lightSize / lightDistance ));*/
80  } else {
81  // nil distance, avoid infinites that kill shaders
82  // NOTE: the constants aren't capricious, they're the right
83  // constants for a light coming from all around.
84  lightCosAngle = 0.0;
85  lightSolidAngle = 2.0 * M_PI;
86  }
87  }
88  lightSizes[i*4+0] = float(lightSize);
89  lightSizes[i*4+1] = float(lightCosAngle);
90  lightSizes[i*4+2] = float(lightSolidAngle);
91  lightSizes[i*4+3] = 0.f;
92  }
93  }
94  else {
95  lightData[i] = 0;
96  lightSizes[i*4+0] = 0.f;
97  lightSizes[i*4+1] = 0.f;
98  lightSizes[i*4+2] = 0.f;
99  lightSizes[i*4+3] = 0.f;
100  }
101  }
102 
103  for (; i < (size_t)GFX_MAX_LIGHTS; ++i) {
104  lightData[i] = 0;
105  lightSizes[i*4+0] = 0.f;
106  lightSizes[i*4+1] = 0.f;
107  lightSizes[i*4+2] = 0.f;
108  lightSizes[i*4+3] = 0.f;
109  }
110 
111  if (!shader) {
112  //only bother with actual GL state in the event of lack of shaders
113  for (size_t i = 0; i < (size_t) GFX_MAX_LIGHTS; ++i) {
114  int isenabled = glIsEnabled( GL_LIGHT0+i );
115  if (isenabled && !lightData[i])
116  glDisable( GL_LIGHT0+i );
117  else if (lightData[i] && !isenabled)
118  glEnable( GL_LIGHT0+i );
119  }
120  } else {
121  //only bother with shader constants it there is a shader
123  for (size_t i = 0; i <= maxval; ++i) {
124  if (lightData[i]) {
125  const gfx_light &light = (*_llights)[*(begin+i)];
126  light.ContextSwitchClobberLight(GL_LIGHT0+i, -1);
127  }
128  }
129  GFXLoadMatrixModel( modelview );
130  if (active_light_array >= 0)
131  GFXShaderConstantv( active_light_array, GFX_MAX_LIGHTS, (int*) lightData );
132  if (max_light_location >= 0)
133  GFXShaderConstanti( max_light_location, maxval );
134  if (apparent_light_size_array >= 0)
135  GFXShaderConstant4v( apparent_light_size_array, GFX_MAX_LIGHTS, (float*)lightSizes );
136  }
137 }
void light_rekey_frame ( )

Rekeys a frame, remembering trashing old lights activated last frame.

Definition at line 498 of file gl_light_state.cpp.

References _llights, GFX_MAX_LIGHTS, OpenGLL::GL_ENABLED, GLLights, i, OpenGLLights::index, index, OpenGLLights::options, and unpicklights().

Referenced by GFXBeginScene().

499 {
500  unpicklights(); //picks doubtless changed position
501  for (int i = 0; i < GFX_MAX_LIGHTS; i++) {
502  if (GLLights[i].options&OpenGLL::GL_ENABLED) {
503  if (GLLights[i].index >= 0) {
504  if ( (*_llights)[GLLights[i].index].Target() == i ) {
505  (*_llights)[GLLights[i].index].SendGLPosition( GL_LIGHT0+i ); //send position transformed by current cam matrix
506  } else {
507  unsigned int li = GLLights[i].index;
508  if ( (*_llights)[li].enabled() && ( (*_llights)[li].Target() == -1 ) ) {
509  (*_llights)[li].ClobberGLLight( i );
510  } else {
511  glDisable( GL_LIGHT0+i );
512  GLLights[i].index = -1;
513  }
514  }
515  } else {
516  glDisable( GL_LIGHT0+i );
517  GLLights[i].options &= (~OpenGLL::GL_ENABLED);
518  }
519  }
520  }
521 }

Variable Documentation

int _GLLightsEnabled = 0

How many lights are enabled (for fast picking)

Definition at line 144 of file gl_light_state.cpp.

Referenced by gfx_light::Create(), gfx_light::Disable(), gfx_light::Enable(), and GFXPickLights().

table to store local lights, numerical pointers to _llights (eg indices)

Definition at line 145 of file gl_light_state.cpp.

Referenced by GFXDestroyAllLights(), GFXPickLights(), and GFXSetLightContext().