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.cpp
Go to the documentation of this file.
1 /*
2  * Vega Strike
3  * Copyright (C) 2001-2002 Daniel Horn & Alan Shieh
4  *
5  * http://vegastrike.sourceforge.net/
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 #include "gfxlib.h"
22 
23 #include "gl_light.h"
24 #include <stack>
25 using std::stack;
26 #include <assert.h>
27 #include "vs_globals.h"
28 #include "config_xml.h"
29 
30 GLint GFX_MAX_LIGHTS = 8;
33 
35 vector< vector< gfx_light > >_local_lights_dat;
36 vector< GFXColor > _ambient_light;
37 vector< gfx_light > *_llights = NULL;
38 
39 //currently stored GL lights!
40 OpenGLLights *GLLights = NULL; //{-1,-1,-1,-1,-1,-1,-1,-1};
41 static stack< bool* > GlobalEffects;
42 static stack< bool* > GlobalEffectsFreelist;
43 static stack< GFXColor >GlobalEffectsAmbient;
44 
45 void /*GFXDRVAPI*/ GFXPushGlobalEffects()
46 {
47  bool *tmp;
48  if (GlobalEffectsFreelist.empty()) {
49  tmp = new bool[GFX_MAX_LIGHTS];
50  } else {
51  tmp = GlobalEffectsFreelist.top();
53  }
54 
55  unpicklights(); //costly but necessary to get rid of pesky local enables that shoudln't be tagged to get reenabled
56  for (int i = 0; i < GFX_MAX_LIGHTS; i++) {
57  tmp[i] = ( 0 != (GLLights[i].options&OpenGLL::GL_ENABLED) );
58  if (GLLights[i].options&OpenGLL::GL_ENABLED)
59  glDisable( GL_LIGHT0+i );
60  }
61  //VSFileSystem::Fprintf (stderr,"PUSH %d",GlobalEffects.size());
62  GlobalEffects.push( tmp );
64  GFXLightContextAmbient( GFXColor( 0, 0, 0, 1 ) );
65 }
66 
68 {
69  if ( GlobalEffects.empty() )
70  return false;
71  //VSFileSystem::Fprintf (stderr,"GES %d",GlobalEffects.size());
72  for (int i = 0; i < GFX_MAX_LIGHTS; i++)
73  if (GlobalEffects.top()[i])
74  glEnable( GL_LIGHT0+i );
75 
76  if (GlobalEffectsFreelist.size() >= 10)
77  delete[] GlobalEffects.top();
78  else
80  GlobalEffects.pop();
81 
84  return true;
85 }
86 
87 GFXLight::GFXLight( const bool enabled,
88  const GFXColor &vect,
89  const GFXColor &diffuse,
90  const GFXColor &specular,
91  const GFXColor &ambient,
92  const GFXColor &attenuate,
93  const GFXColor &direction,
94  float exp,
95  float cutoff,
96  float size )
97 {
98  target = -1;
99  options = 0;
100  memcpy( this->vect, &vect, sizeof (float)*3 );
101  memcpy( this->diffuse, &diffuse, sizeof (float)*4 );
102  memcpy( this->specular, &specular, sizeof (float)*4 );
103  memcpy( this->ambient, &ambient, sizeof (float)*4 );
104  memcpy( this->attenuate, &attenuate, sizeof (float)*3 );
105  memcpy( this->direction, &direction, sizeof (this->direction) );
106  this->exp = exp;
107  this->cutoff = cutoff;
108  this->size = size;
110  if (enabled)
111  this->enable();
112  else
113  this->disable();
114 }
115 
117 {
119 }
120 
122 {
124 }
125 
127 {
128  return (attenuate[0] != 1) || (attenuate[1] != 0) || (attenuate[2] != 0);
129 }
130 
131 void GFXLight::apply_attenuate( bool attenuated )
132 {
133  options = attenuated
135  : ( options&(~GFX_ATTENUATED) );
136 }
137 
138 void /*GFXDRVAPI*/ GFXLight::SetProperties( enum LIGHT_TARGET lighttarg, const GFXColor &color )
139 {
140  switch (lighttarg)
141  {
142  case DIFFUSE:
143  diffuse[0] = color.r;
144  diffuse[1] = color.g;
145  diffuse[2] = color.b;
146  diffuse[3] = color.a;
147  break;
148  case SPECULAR:
149  specular[0] = color.r;
150  specular[1] = color.g;
151  specular[2] = color.b;
152  specular[3] = color.a;
153  break;
154  case AMBIENT:
155  ambient[0] = color.r;
156  ambient[1] = color.g;
157  ambient[2] = color.b;
158  ambient[3] = color.a;
159  break;
160  case POSITION:
161  vect[0] = color.r;
162  vect[1] = color.g;
163  vect[2] = color.b;
164  break;
165  case ATTENUATE:
166  attenuate[0] = color.r;
167  attenuate[1] = color.g;
168  attenuate[2] = color.b;
169  break;
170  case EMISSION:
171  default:
172  break;
173  }
175 }
176 
177 GFXColor /*GFXDRVAPI*/ GFXLight::GetProperties( enum LIGHT_TARGET lighttarg ) const
178 {
179  switch (lighttarg)
180  {
181  case SPECULAR:
182  return GFXColor( specular[0],
183  specular[1],
184  specular[2],
185  specular[3] );
186 
187  case AMBIENT:
188  return GFXColor( ambient[0],
189  ambient[1],
190  ambient[2],
191  ambient[3] );
192 
193  case POSITION:
194  return GFXColor( vect[0],
195  vect[1],
196  vect[2] );
197 
198  break;
199  case ATTENUATE:
200  return GFXColor(
201  attenuate[0],
202  attenuate[1],
203  attenuate[2] );
204 
205  case DIFFUSE:
206  default: //just for kicks
207  return GFXColor( diffuse[0],
208  diffuse[1],
209  diffuse[2],
210  diffuse[3] );
211  }
212 }
213 
214 GFXBOOL /*GFXDRVAPI*/ GFXSetCutoff( const float ttcutoff )
215 {
216  if (ttcutoff < 0)
217  return GFXFALSE;
218  intensity_cutoff = ttcutoff;
219  return GFXTRUE;
220 }
221 
222 void /*GFXDRVAPI*/ GFXSetOptimalIntensity( const float intensity, const float saturate )
223 {
224  optintense = intensity;
225  optsat = saturate;
226 }
227 
228 GFXBOOL /*GFXDRVAPI*/ GFXSetOptimalNumLights( const int numLights )
229 {
230  if (numLights > GFX_MAX_LIGHTS || numLights < 0)
231  return GFXFALSE;
232  GFX_OPTIMAL_LIGHTS = numLights;
233  return GFXTRUE;
234 }
235 
236 GFXBOOL /*GFXDRVAPI*/ GFXSetSeparateSpecularColor( const GFXBOOL spec )
237 {
238 #if !defined (_WIN32) && !defined (__CYGWIN__)
239  if (spec) {
240  glLightModeli( GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR );
241  } else {
242  glLightModeli( GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR );
243  return GFXFALSE;
244  }
245 #else
246  return GFXFALSE;
247 #endif
248  return GFXTRUE;
249 }
250 
251 GFXBOOL /*GFXDRVAPI*/ GFXLightContextAmbient( const GFXColor &amb )
252 {
253  if ( _currentContext >= static_cast<int>(_ambient_light.size()) )
254  return GFXFALSE;
256  //(_ambient_light[_currentContext])[1]=amb.g;
257  //(_ambient_light[_currentContext])[2]=amb.b;
258  //(_ambient_light[_currentContext])[3]=amb.a;
259  float tmp[4] = {amb.r, amb.g, amb.b, amb.a};
260  glLightModelfv( GL_LIGHT_MODEL_AMBIENT, tmp );
261  return GFXTRUE;
262 }
263 
265 {
266  if ( _currentContext >= static_cast<int>(_ambient_light.size()) )
267  return GFXFALSE;
269  return GFXTRUE;
270 }
271 
272 GFXBOOL /*GFXDRVAPI*/ GFXCreateLight( int &light, const GFXLight &templatecopy, const bool global )
273 {
274  for (light = 0; light < static_cast<int>(_llights->size()); light++)
275  if ( (*_llights)[light].Target() == -2 )
276  break;
277  if ( light == static_cast<int>(_llights->size()) )
278  _llights->push_back( gfx_light() );
279  return (*_llights)[light].Create( templatecopy, global );
280 }
281 
282 void /*GFXDRVAPI*/ GFXDeleteLight( const int light )
283 {
284  (*_llights)[light].Kill();
285 }
286 
287 GFXBOOL /*GFXDRVAPI*/ GFXSetLight( const int light, const enum LIGHT_TARGET lt, const GFXColor &color )
288 {
289  if ( (*_llights)[light].Target() == -2 )
290  return GFXFALSE;
291  (*_llights)[light].ResetProperties( lt, color );
292 
293  return GFXTRUE;
294 }
295 
296 GFXBOOL /*GFXDRVAPI*/ GFXEnableLight( int light )
297 {
298  assert( light >= 0 && light <= static_cast<int>(_llights->size()) );
299  //return FALSE;
300  if ( (*_llights)[light].Target() == -2 )
301  return GFXFALSE;
302  (*_llights)[light].Enable();
303  return GFXTRUE;
304 }
305 
306 GFXBOOL /*GFXDRVAPI*/ GFXDisableLight( int light )
307 {
308  assert( light >= 0 && light <= static_cast<int>(_llights->size()) );
309  if ( (*_llights)[light].Target() == -2 )
310  return GFXFALSE;
311  (*_llights)[light].Disable();
312  return GFXTRUE;
313 }
314 
315 static void SetupGLLightGlobals();
316 
317 void /*GFXDRVAPI*/ GFXCreateLightContext( int &con_number )
318 {
319  static GFXBOOL LightInit = GFXFALSE;
320  if (!LightInit) {
321  LightInit = GFXTRUE;
323  }
324  con_number = _local_lights_dat.size();
325  _currentContext = con_number;
326  _ambient_light.push_back( GFXColor( 0, 0, 0, 1 ) );
327  _local_lights_dat.push_back( vector< gfx_light > () );
328  GFXSetLightContext( con_number );
329 }
330 
331 void /*GFXDRVAPI*/ GFXDeleteLightContext( int con_number )
332 {
333  _local_lights_dat[con_number] = vector< gfx_light > ();
334 }
335 
336 void /*GFXDRVAPI*/ GFXSetLightContext( const int con_number )
337 {
338  unpicklights();
339  int GLLindex = 0;
340  unsigned int i;
341  lighttable.Clear();
342  _currentContext = con_number;
343  _llights = &_local_lights_dat[con_number];
344  glLightModelfv( GL_LIGHT_MODEL_AMBIENT, (GLfloat*) &(_ambient_light[con_number]) );
345  //reset all lights so they arean't in GLLights
346  for (i = 0; i < _llights->size(); i++)
347  (*_llights)[i].Target() = -1;
348  for (i = 0; i < _llights->size() && GLLindex < GFX_MAX_LIGHTS; i++)
349  if ( (*_llights)[i].enabled() ) {
350  if ( (*_llights)[i].LocalLight() ) {
351  (*_llights)[i].AddToTable();
352  } else {
353  GLLights[GLLindex].index = -1; //make it clobber completley! no trace of old light.
354  (*_llights)[i].ClobberGLLight( GLLindex );
355  GLLindex++;
356  }
357  }
358  for (; GLLindex < GFX_MAX_LIGHTS; GLLindex++) {
359  GLLights[GLLindex].index = -1;
360  GLLights[GLLindex].options = OpenGLL::GLL_OFF;
361  glDisable( GL_LIGHT0+GLLindex );
362  }
363 }
364 
366 {
367  lighttable.Clear();
368  if (GLLights)
369  free( GLLights );
370 }
371 
372 static void SetupGLLightGlobals()
373 {
374  int i;
375  glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, 1 ); //don't want lighting coming from infinity....we have to take the hit due to sphere mapping matrix tweaking
376  //
377  glGetIntegerv( GL_MAX_LIGHTS, &GFX_MAX_LIGHTS );
378  if (!GLLights) {
379  GLLights = (OpenGLLights*) malloc( sizeof (OpenGLLights)*GFX_MAX_LIGHTS );
380  for (i = 0; i < GFX_MAX_LIGHTS; i++)
381  GLLights[i].index = -1;
382  }
383  static float lightcutoff = XMLSupport::parse_float( vs_config->getVariable( "graphics", "lightcutoff", ".06" ) );
384  static float lightoptimalintensity =
385  XMLSupport::parse_float( vs_config->getVariable( "graphics", "lightoptimalintensity", ".06" ) );
386  static float lightsaturation = XMLSupport::parse_float( vs_config->getVariable( "graphics", "lightsaturation", ".95" ) );
387  static int numlights = XMLSupport::parse_int( vs_config->getVariable( "graphics", "numlights", "4" ) );
388  static bool separatespecularcolor =
389  XMLSupport::parse_bool( vs_config->getVariable( "graphics", "separatespecularcolor", "false" ) );
390 
391  GFXSetCutoff( lightcutoff );
392  GFXSetOptimalIntensity( lightoptimalintensity, lightsaturation );
393  GFXSetOptimalNumLights( numlights );
394  GFXSetSeparateSpecularColor( separatespecularcolor ? GFXTRUE : GFXFALSE );
395 }
396