1 // non fixed Opengl pipeline rendering
3 // Written by Harald JOHNSEN, started Jully 2005.
5 // Copyright (C) 2005 Harald JOHNSEN - hjohnsen@evc.net
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
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, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
28 #include <simgear/props/condition.hxx>
29 #include <simgear/props/props.hxx>
30 #include <simgear/screen/extensions.hxx>
32 #include <simgear/debug/logstream.hxx>
34 #include <simgear/screen/shader.h>
36 #include "animation.hxx"
40 <shader>fresnel</shader>
41 <object-name>...</object-name>
46 <shader>heat-haze</shader>
47 <object-name>...</object-name>
49 <speed-prop>...</speed-prop>
51 <factor-prop>...</factor-prop>
56 <shader>chrome</shader>
57 <texture>...</texture>
58 <object-name>...</object-name>
64 <object-name>...</object-name>
65 <depth-test>false</depth-test>
69 static Shader *shFresnel=NULL;
70 static GLuint texFresnel = 0;
72 static GLuint texBackground = 0;
73 static const int texBackgroundWidth = 1024, texBackgroundHeight = 1024;
74 static bool initDone = false;
75 static bool haveBackground = false;
77 static glActiveTextureProc glActiveTexturePtr = 0;
78 static double totalTime = 0.0;
79 static sgMat4 shadIdentMatrix;
82 static int null_shader_callback( ssgEntity *e ) {
84 ssgLeaf *leaf = (ssgLeaf *) e;
86 dlist = leaf->getDListIndex();
89 dlist = leaf->getDListIndex();
94 ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
98 SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
99 if( ! my_shader->_depth_test )
100 glDisable( GL_DEPTH_TEST );
101 glCallList ( dlist ) ;
103 if( ! my_shader->_depth_test )
104 glEnable( GL_DEPTH_TEST );
110 static int heat_haze_shader_callback( ssgEntity *e ) {
112 ssgLeaf *leaf = (ssgLeaf *) e;
113 #ifdef _SSG_USE_DLIST
114 dlist = leaf->getDListIndex();
117 dlist = leaf->getDListIndex();
122 if( ! haveBackground ) {
123 // store the backbuffer in a texture
124 if( ! texBackground ) {
125 // allocate our texture here so we don't waste memory if no model use that effect
126 glGenTextures(1, &texBackground);
127 glBindTexture(GL_TEXTURE_2D, texBackground);
128 // trying to match the backbuffer pixel format
129 GLint internalFormat = GL_RGB8;
130 GLint colorBits = 0, alphaBits = 0;
131 glGetIntegerv( GL_BLUE_BITS, &colorBits );
132 glGetIntegerv( GL_ALPHA_BITS, &alphaBits );
135 internalFormat = GL_RGB5;
137 internalFormat = GL_RGB5_A1;
140 internalFormat = GL_RGBA8;
142 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat,
143 texBackgroundWidth, texBackgroundHeight, 0, GL_RGB, GL_FLOAT, NULL);
145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
147 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
149 glBindTexture(GL_TEXTURE_2D, 0);
152 glGetIntegerv( GL_VIEWPORT, viewport );
153 const int screen_width = viewport[2];
154 const int screen_height = viewport[3];
155 glBindTexture(GL_TEXTURE_2D, texBackground);
156 // center of texture = center of screen
157 // obviously we don't have the whole screen if screen_width > texBackgroundWidth
158 glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0,
159 (screen_width - texBackgroundWidth) / 2,
160 (screen_height - texBackgroundHeight) / 2,
161 texBackgroundWidth, texBackgroundHeight );
162 haveBackground = true;
163 glBindTexture(GL_TEXTURE_2D, 0);
165 ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
169 SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
170 if( ! my_shader->_depth_test )
171 glDisable( GL_DEPTH_TEST );
172 glDepthMask( GL_FALSE );
173 glDisable( GL_LIGHTING );
175 // noise texture, tex coord from the model translated by a time factor
176 glActiveTexturePtr( GL_TEXTURE0_ARB );
177 glEnable(GL_TEXTURE_2D);
178 const float noiseDist = fmodf(- totalTime * my_shader->_factor * my_shader->_speed, 4.0f);
179 glMatrixMode(GL_TEXTURE);
181 glTranslatef( noiseDist, 0.0f, 0.0f );
182 glMatrixMode(GL_MODELVIEW);
184 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
186 // background texture
187 glActiveTexturePtr( GL_TEXTURE1_ARB );
188 glEnable(GL_TEXTURE_2D);
189 glBindTexture(GL_TEXTURE_2D, texBackground);
191 // automatic generation of texture coordinates
192 // map to screen space
193 sgMat4 CameraProjM, CameraViewM;
195 glGetIntegerv( GL_VIEWPORT, viewport );
196 const int screen_width = viewport[2];
197 const int screen_height = viewport[3];
198 glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat *) CameraProjM);
199 glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) CameraViewM);
200 const float dummy_scale = 1.0f; //0.95f;
201 const float deltaPos = 0.05f;
202 glMatrixMode(GL_TEXTURE);
204 glTranslatef( 0.5f, 0.5f, 0.0f );
205 glScalef( float( screen_width ) / float( texBackgroundWidth ) * 0.5f * dummy_scale,
206 float( screen_height ) / float( texBackgroundHeight ) * 0.5f * dummy_scale, 1.0f );
207 glMultMatrixf( (GLfloat *) CameraProjM );
208 glMultMatrixf( (GLfloat *) CameraViewM );
209 glTranslatef( deltaPos, deltaPos, deltaPos );
210 glMatrixMode(GL_MODELVIEW);
212 glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
213 glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
214 glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
215 glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
216 glTexGenfv( GL_S, GL_EYE_PLANE, shadIdentMatrix[0] );
217 glTexGenfv( GL_T, GL_EYE_PLANE, shadIdentMatrix[1] );
218 glTexGenfv( GL_R, GL_EYE_PLANE, shadIdentMatrix[2] );
219 glTexGenfv( GL_Q, GL_EYE_PLANE, shadIdentMatrix[3] );
220 glEnable( GL_TEXTURE_GEN_S );
221 glEnable( GL_TEXTURE_GEN_T );
222 glEnable( GL_TEXTURE_GEN_R );
223 glEnable( GL_TEXTURE_GEN_Q );
225 sgVec4 enviro = {1.00f, 1.00f, 1.00f, 0.85f};
227 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
228 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
229 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
230 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
231 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT_ARB );
232 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
233 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, enviro);
235 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
236 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE0_ARB);
237 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
238 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB );
239 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA );
241 glCallList ( dlist ) ;
242 glMatrixMode(GL_TEXTURE);
243 glTranslatef( - deltaPos*2.0f, -deltaPos*2.5f, -deltaPos*2.0f );
244 glMatrixMode(GL_MODELVIEW);
245 glCallList ( dlist ) ;
247 // alter colors only on last rendering
248 sgVec4 fLight = {0.93f, 0.93f, 1.00f, 0.85f};
249 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB );
250 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
252 glMatrixMode(GL_TEXTURE);
253 glTranslatef( deltaPos*0.7f, deltaPos*1.7f, deltaPos*0.7f );
254 glMatrixMode(GL_MODELVIEW);
255 glCallList ( dlist ) ;
258 glActiveTexturePtr( GL_TEXTURE1_ARB );
259 glDisable( GL_TEXTURE_GEN_S );
260 glDisable( GL_TEXTURE_GEN_T );
261 glDisable( GL_TEXTURE_GEN_R );
262 glDisable( GL_TEXTURE_GEN_Q );
263 glMatrixMode(GL_TEXTURE);
265 glMatrixMode(GL_MODELVIEW);
266 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
267 glDisable(GL_TEXTURE_2D);
268 glActiveTexturePtr( GL_TEXTURE0_ARB );
269 glMatrixMode(GL_TEXTURE);
271 glMatrixMode(GL_MODELVIEW);
272 glEnable(GL_TEXTURE_2D);
273 glBindTexture(GL_TEXTURE_2D, 0);
276 if( ! my_shader->_depth_test )
277 glEnable( GL_DEPTH_TEST );
279 glEnable( GL_LIGHTING );
280 glDepthMask( GL_TRUE );
288 static int fresnel_shader_callback( ssgEntity *e ) {
290 ssgLeaf *leaf = (ssgLeaf *) e;
291 #ifdef _SSG_USE_DLIST
292 dlist = leaf->getDListIndex();
295 dlist = leaf->getDListIndex();
300 ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
304 sgVec4 sunColor, ambientColor;
305 ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor );
306 ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor );
308 SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
310 glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
311 glEnable(GL_ALPHA_TEST);
312 glAlphaFunc(GL_GREATER, 0.0f);
315 // sgVec4 R = {0.5,0.0,0.0,0.0};
316 sgVec4 enviro = {1.0,0.0,0.0,1.0};
317 // sgCopyVec4( enviro, sunColor );
318 glActiveTexturePtr( GL_TEXTURE0_ARB );
319 glEnable(GL_TEXTURE_2D);
320 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
321 glActiveTexturePtr( GL_TEXTURE1_ARB );
322 glDisable(GL_TEXTURE_2D);
323 glEnable(GL_TEXTURE_1D);
324 glBindTexture(GL_TEXTURE_1D, texFresnel);
325 // c = a0 * a2 + a1 * (1-a2)
326 // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
327 // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
328 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
329 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB );
330 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_CONSTANT_ARB );
331 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
332 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB );
333 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
334 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE );
335 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR );
336 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, enviro);
339 glCallList ( dlist ) ;
340 shFresnel->disable();
341 glActiveTexturePtr( GL_TEXTURE1_ARB );
342 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
343 glDisable(GL_TEXTURE_1D);
344 glActiveTexturePtr( GL_TEXTURE0_ARB );
345 glDisable(GL_TEXTURE_1D);
346 glEnable(GL_TEXTURE_2D);
349 // glBindTexture(GL_TEXTURE_2D, 0);
350 // glDepthFunc(GL_LESS);
351 // glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
361 static int chrome_shader_callback( ssgEntity *e ) {
363 ssgLeaf *leaf = (ssgLeaf *) e;
364 #ifdef _SSG_USE_DLIST
365 dlist = leaf->getDListIndex();
368 dlist = leaf->getDListIndex();
373 ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
377 SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
378 if( ! my_shader->_depth_test )
379 glDisable( GL_DEPTH_TEST );
381 GLint maskTexComponent = 3;
382 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &maskTexComponent);
384 // The fake env chrome texture
385 glActiveTexturePtr( GL_TEXTURE1_ARB );
386 glEnable(GL_TEXTURE_2D);
388 // No lighting is computed in spherical mapping mode because the environment
389 // is supposed to be allready lighted. We must reshade our environment texture.
390 sgVec4 sunColor, ambientColor, envColor;
391 ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor );
392 ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor );
393 sgAddScaledVec3( envColor, ambientColor, sunColor, 0.4f);
394 glBindTexture(GL_TEXTURE_2D, my_shader->_effectTexture->getHandle());
397 sgSubVec3(delta_light, envColor, my_shader->_envColor);
398 if( (fabs(delta_light[0]) + fabs(delta_light[1]) + fabs(delta_light[2])) > 0.05f ) {
399 sgCopyVec3( my_shader->_envColor, envColor );
400 // reload the texture data and let the driver reshade it for us
401 glPixelTransferf( GL_RED_SCALE, envColor[0] );
402 glPixelTransferf( GL_GREEN_SCALE, envColor[1] );
403 glPixelTransferf( GL_BLUE_SCALE, envColor[2] );
404 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, my_shader->_texWidth, my_shader->_texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, my_shader->_textureData);
405 glPixelTransferf( GL_RED_SCALE, 1.0f );
406 glPixelTransferf( GL_GREEN_SCALE, 1.0f );
407 glPixelTransferf( GL_BLUE_SCALE, 1.0f );
410 if( maskTexComponent == 4 ) {
411 // c = lerp(model tex, chrome tex, model tex alpha)
412 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
413 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB );
414 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB );
415 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
416 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE );
417 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
418 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PREVIOUS_ARB );
419 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA );
421 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
422 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
423 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
426 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
427 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
428 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
430 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
431 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
432 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
434 // automatic generation of texture coordinates
437 glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
438 glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
439 glEnable( GL_TEXTURE_GEN_S );
440 glEnable( GL_TEXTURE_GEN_T );
442 glCallList ( dlist ) ;
444 glActiveTexturePtr( GL_TEXTURE1_ARB );
445 glDisable( GL_TEXTURE_GEN_S );
446 glDisable( GL_TEXTURE_GEN_T );
448 glMatrixMode(GL_TEXTURE);
450 glMatrixMode(GL_MODELVIEW);
452 glDisable(GL_TEXTURE_2D);
453 glBindTexture(GL_TEXTURE_2D, 0);
454 glActiveTexturePtr( GL_TEXTURE0_ARB );
457 if( ! my_shader->_depth_test )
458 glEnable( GL_DEPTH_TEST );
467 static void init_shaders(void) {
469 if( false && Shader::is_VP_supported() ) {
470 shFresnel = new Shader("/FlightGear/data/Textures/fresnel_vp.txt", "fresnel_vp");
471 // shFresnel->bindNames("somedata", 0);
473 glActiveTexturePtr = (glActiveTextureProc) SGLookupFunction("glActiveTextureARB");
474 const int fresnelSize = 512;
475 unsigned char imageFresnel[ fresnelSize * 3 ];
476 for(int i = 0; i < fresnelSize; i++) {
477 const float R0 = 0.2f;
478 float NdotV = float( i ) / float( fresnelSize );
479 float f = R0 + (1.0f-R0)*pow(1.0f - NdotV, 5);
480 unsigned char ff = (unsigned char) (f * 255.0);
481 imageFresnel[i*3+0] = imageFresnel[i*3+1] = imageFresnel[i*3+2] = ff;
483 glGenTextures( 1, &texFresnel );
484 glBindTexture(GL_TEXTURE_1D, texFresnel );
485 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
486 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
487 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
488 glTexParameteri(GL_TEXTURE_1D, GL_GENERATE_MIPMAP_SGIS, true);
489 glTexImage1D(GL_TEXTURE_1D, 0, 3, fresnelSize, 0, GL_RGB, GL_UNSIGNED_BYTE, imageFresnel);
490 glBindTexture(GL_TEXTURE_1D, 0 );
492 sgMakeIdentMat4( shadIdentMatrix );
497 ////////////////////////////////////////////////////////////////////////
498 // Implementation of SGShaderAnimation
499 ////////////////////////////////////////////////////////////////////////
501 SGShaderAnimation::SGShaderAnimation ( SGPropertyNode *prop_root,
502 SGPropertyNode_ptr props )
503 : SGAnimation(props, new ssgBranch),
505 _condition_value(true),
507 _param_1(props->getFloatValue("param", 1.0f)),
508 _depth_test(props->getBoolValue("depth-test", true)),
509 _factor(props->getFloatValue("factor", 1.0f)),
511 _speed(props->getFloatValue("speed", 1.0f)),
519 SGPropertyNode_ptr node = props->getChild("condition");
521 _condition = sgReadCondition(prop_root, node);
522 _condition_value = false;
524 node = props->getChild("factor-prop");
526 _factor_prop = prop_root->getNode(node->getStringValue(), true);
527 node = props->getChild("speed-prop");
529 _speed_prop = prop_root->getNode(node->getStringValue(), true);
531 sgSetVec4(_envColor, 0.0f, 0.0f, 0.0f, 1.0f);
532 node = props->getChild("texture");
534 _effectTexture = ssgGetCurrentOptions()->createTexture( (char *) node->getStringValue(), 0, 0, 0);
535 glBindTexture(GL_TEXTURE_2D, _effectTexture->getHandle() );
536 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &_texWidth);
537 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &_texHeight);
539 _textureData = new unsigned char[_texWidth * _texHeight * 3];
540 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, _textureData);
541 glBindTexture(GL_TEXTURE_2D, 0 );
543 string shader_name = props->getStringValue("shader");
544 if( shader_name == "fresnel" || shader_name == "reflection" )
546 else if( shader_name == "heat-haze" )
548 else if( shader_name == "chrome" && _effectTexture)
552 static void setCallBack(ssgBranch *branch, ssgBase *user_data, ssgCallback cb) {
553 for (int i = 0; i < branch->getNumKids(); i++) {
554 ssgEntity *e = branch->getKid(i);
555 if( e->isAKindOf( ssgTypeBranch() ) )
556 setCallBack( (ssgBranch *) e, user_data, cb);
557 else if( e->isAKindOf( ssgTypeVtxTable() ) ) {
558 e->setCallback( SSG_CALLBACK_PREDRAW, cb );
559 e->setUserData( user_data );
564 void SGShaderAnimation::init()
568 if( _shader_type == 1 && Shader::is_VP_supported() && shFresnel)
569 setCallBack( getBranch(), (ssgBase *) this, fresnel_shader_callback );
570 else if( _shader_type == 2 )
571 setCallBack( getBranch(), (ssgBase *) this, heat_haze_shader_callback );
572 else if( _shader_type == 3 )
573 setCallBack( getBranch(), (ssgBase *) this, chrome_shader_callback );
575 setCallBack( getBranch(), (ssgBase *) this, null_shader_callback );
578 SGShaderAnimation::~SGShaderAnimation()
581 delete _effectTexture;
586 SGShaderAnimation::update()
589 _condition_value = _condition->test();
591 _factor = _factor_prop->getFloatValue();
593 _speed = _speed_prop->getFloatValue();
597 void sgShaderFrameInit(double delta_time_sec) {
598 haveBackground = false;
599 totalTime += delta_time_sec;