1 // non fixed Opengl pipeline rendering
3 // Written by Harald JOHNSEN, started Jully 2005.
5 // Copyright (C) 2005 Harald JOHNSEN
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 int texBackgroundWidth = 1024, texBackgroundHeight = 1024;
74 static GLenum texBackgroundTarget = GL_TEXTURE_2D;
75 static bool isRectangleTextureSupported = false;
76 static bool istexBackgroundRectangle = false;
77 static bool initDone = false;
78 static bool haveBackground = false;
80 static glActiveTextureProc glActiveTexturePtr = 0;
81 static double totalTime = 0.0;
82 static sgMat4 shadIdentMatrix;
85 static int null_shader_callback( ssgEntity *e ) {
87 ssgLeaf *leaf = (ssgLeaf *) e;
89 dlist = leaf->getDListIndex();
92 dlist = leaf->getDListIndex();
97 ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
101 SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
102 if( ! my_shader->_depth_test )
103 glDisable( GL_DEPTH_TEST );
104 glCallList ( dlist ) ;
106 if( ! my_shader->_depth_test )
107 glEnable( GL_DEPTH_TEST );
113 static int heat_haze_shader_callback( ssgEntity *e ) {
115 ssgLeaf *leaf = (ssgLeaf *) e;
116 #ifdef _SSG_USE_DLIST
117 dlist = leaf->getDListIndex();
120 dlist = leaf->getDListIndex();
127 glGetIntegerv( GL_VIEWPORT, viewport );
128 const int screen_width = viewport[2];
129 const int screen_height = viewport[3];
130 if( ! haveBackground ) {
131 // store the backbuffer in a texture
132 if( ! texBackground ) {
133 // allocate our texture here so we don't waste memory if no model use that effect
134 // check if we need a rectangle texture and if the card support it
135 if( (screen_width > 1024 || screen_height > 1024) && isRectangleTextureSupported ) {
136 // Note that the 3 (same) extensions use the same enumerants
137 texBackgroundTarget = GL_TEXTURE_RECTANGLE_NV;
138 istexBackgroundRectangle = true;
139 texBackgroundWidth = screen_width;
140 texBackgroundHeight = screen_height;
142 glGenTextures(1, &texBackground);
143 glEnable(texBackgroundTarget);
144 glBindTexture(texBackgroundTarget, texBackground);
145 // trying to match the backbuffer pixel format
146 GLint internalFormat = GL_RGB8;
147 GLint colorBits = 0, alphaBits = 0;
148 glGetIntegerv( GL_BLUE_BITS, &colorBits );
149 glGetIntegerv( GL_ALPHA_BITS, &alphaBits );
152 internalFormat = GL_RGB5;
154 internalFormat = GL_RGB5_A1;
157 internalFormat = GL_RGBA8;
159 glTexImage2D(texBackgroundTarget, 0, internalFormat,
160 texBackgroundWidth, texBackgroundHeight, 0, GL_RGB, GL_FLOAT, NULL);
162 glTexParameteri(texBackgroundTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
163 glTexParameteri(texBackgroundTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
164 glTexParameteri(texBackgroundTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
165 glTexParameteri(texBackgroundTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
167 glEnable(texBackgroundTarget);
168 glBindTexture(texBackgroundTarget, texBackground);
169 // center of texture = center of screen
170 // obviously we don't have the whole screen if screen_width > texBackgroundWidth
171 // if rectangle textures are not supported, this give some artifacts on the borders
172 if( istexBackgroundRectangle ) {
173 glCopyTexSubImage2D( texBackgroundTarget, 0, 0, 0,
174 0, 0, texBackgroundWidth, texBackgroundHeight );
176 glCopyTexSubImage2D( texBackgroundTarget, 0, 0, 0,
177 (screen_width - texBackgroundWidth) / 2,
178 (screen_height - texBackgroundHeight) / 2,
179 texBackgroundWidth, texBackgroundHeight );
181 haveBackground = true;
182 glBindTexture(texBackgroundTarget, 0);
183 glDisable(texBackgroundTarget);
185 ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
189 SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
190 if( ! my_shader->_depth_test )
191 glDisable( GL_DEPTH_TEST );
192 glDepthMask( GL_FALSE );
193 glDisable( GL_LIGHTING );
195 // noise texture, tex coord from the model translated by a time factor
196 glActiveTexturePtr( GL_TEXTURE0_ARB );
197 glEnable(GL_TEXTURE_2D);
198 const float noiseDist = fmod(- totalTime * my_shader->_factor * my_shader->_speed, 4.0);
199 glMatrixMode(GL_TEXTURE);
201 glTranslatef( noiseDist, 0.0f, 0.0f );
202 glMatrixMode(GL_MODELVIEW);
204 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
206 // background texture
207 glActiveTexturePtr( GL_TEXTURE1_ARB );
208 glEnable(texBackgroundTarget);
209 glBindTexture(texBackgroundTarget, texBackground);
211 // automatic generation of texture coordinates
212 // map to screen space
213 sgMat4 CameraProjM, CameraViewM;
214 glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat *) CameraProjM);
215 glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) CameraViewM);
216 // const float dummy_scale = 1.0f; //0.95f;
217 const float deltaPos = 0.05f;
218 glMatrixMode(GL_TEXTURE);
220 if( istexBackgroundRectangle ) {
221 // coords go from 0.0 to n, not from 0.0 to 1.0
222 glTranslatef( texBackgroundWidth * 0.5f, texBackgroundHeight * 0.5f, 0.0f );
223 glScalef( texBackgroundWidth * 0.5f,
224 texBackgroundHeight * 0.5f, 1.0f );
226 glTranslatef( 0.5f, 0.5f, 0.0f );
227 glScalef( float( screen_width ) / float( texBackgroundWidth ) * 0.5f,
228 float( screen_height ) / float( texBackgroundHeight ) * 0.5f, 1.0f );
230 glMultMatrixf( (GLfloat *) CameraProjM );
231 glMultMatrixf( (GLfloat *) CameraViewM );
232 glTranslatef( deltaPos, deltaPos, deltaPos );
233 glMatrixMode(GL_MODELVIEW);
235 glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
236 glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
237 glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
238 glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
239 glTexGenfv( GL_S, GL_EYE_PLANE, shadIdentMatrix[0] );
240 glTexGenfv( GL_T, GL_EYE_PLANE, shadIdentMatrix[1] );
241 glTexGenfv( GL_R, GL_EYE_PLANE, shadIdentMatrix[2] );
242 glTexGenfv( GL_Q, GL_EYE_PLANE, shadIdentMatrix[3] );
243 glEnable( GL_TEXTURE_GEN_S );
244 glEnable( GL_TEXTURE_GEN_T );
245 glEnable( GL_TEXTURE_GEN_R );
246 glEnable( GL_TEXTURE_GEN_Q );
248 sgVec4 enviro = {1.00f, 1.00f, 1.00f, 0.85f};
250 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
251 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
252 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
253 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
254 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT_ARB );
255 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
256 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, enviro);
258 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
259 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE0_ARB);
260 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
261 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB );
262 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA );
264 glCallList ( dlist ) ;
265 glMatrixMode(GL_TEXTURE);
266 glTranslatef( - deltaPos*2.0f, -deltaPos*2.5f, -deltaPos*2.0f );
267 glMatrixMode(GL_MODELVIEW);
268 glCallList ( dlist ) ;
270 // alter colors only on last rendering
271 // sgVec4 fLight = {0.93f, 0.93f, 1.00f, 0.85f};
272 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB );
273 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
275 glMatrixMode(GL_TEXTURE);
276 glTranslatef( deltaPos*0.7f, deltaPos*1.7f, deltaPos*0.7f );
277 glMatrixMode(GL_MODELVIEW);
278 glCallList ( dlist ) ;
281 glActiveTexturePtr( GL_TEXTURE1_ARB );
282 glDisable( GL_TEXTURE_GEN_S );
283 glDisable( GL_TEXTURE_GEN_T );
284 glDisable( GL_TEXTURE_GEN_R );
285 glDisable( GL_TEXTURE_GEN_Q );
286 glMatrixMode(GL_TEXTURE);
288 glMatrixMode(GL_MODELVIEW);
289 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
290 glDisable(texBackgroundTarget);
291 glActiveTexturePtr( GL_TEXTURE0_ARB );
292 glMatrixMode(GL_TEXTURE);
294 glMatrixMode(GL_MODELVIEW);
295 glEnable(GL_TEXTURE_2D);
296 glBindTexture(GL_TEXTURE_2D, 0);
299 if( ! my_shader->_depth_test )
300 glEnable( GL_DEPTH_TEST );
302 glEnable( GL_LIGHTING );
303 glDepthMask( GL_TRUE );
311 static int fresnel_shader_callback( ssgEntity *e ) {
313 ssgLeaf *leaf = (ssgLeaf *) e;
314 #ifdef _SSG_USE_DLIST
315 dlist = leaf->getDListIndex();
318 dlist = leaf->getDListIndex();
323 ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
327 sgVec4 sunColor, ambientColor;
328 ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor );
329 ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor );
331 // SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
333 glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
334 glEnable(GL_ALPHA_TEST);
335 glAlphaFunc(GL_GREATER, 0.0f);
338 // sgVec4 R = {0.5,0.0,0.0,0.0};
339 sgVec4 enviro = {1.0,0.0,0.0,1.0};
340 // sgCopyVec4( enviro, sunColor );
341 glActiveTexturePtr( GL_TEXTURE0_ARB );
342 glEnable(GL_TEXTURE_2D);
343 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
344 glActiveTexturePtr( GL_TEXTURE1_ARB );
345 glDisable(GL_TEXTURE_2D);
346 glEnable(GL_TEXTURE_1D);
347 glBindTexture(GL_TEXTURE_1D, texFresnel);
348 // c = a0 * a2 + a1 * (1-a2)
349 // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
350 // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
351 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
352 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB );
353 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_CONSTANT_ARB );
354 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
355 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB );
356 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
357 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE );
358 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR );
359 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, enviro);
362 glCallList ( dlist ) ;
363 shFresnel->disable();
364 glActiveTexturePtr( GL_TEXTURE1_ARB );
365 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
366 glDisable(GL_TEXTURE_1D);
367 glActiveTexturePtr( GL_TEXTURE0_ARB );
368 glDisable(GL_TEXTURE_1D);
369 glEnable(GL_TEXTURE_2D);
372 // glBindTexture(GL_TEXTURE_2D, 0);
373 // glDepthFunc(GL_LESS);
374 // glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
384 static int chrome_shader_callback( ssgEntity *e ) {
386 ssgLeaf *leaf = (ssgLeaf *) e;
387 #ifdef _SSG_USE_DLIST
388 dlist = leaf->getDListIndex();
391 dlist = leaf->getDListIndex();
396 ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
400 SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
401 if( ! my_shader->_depth_test )
402 glDisable( GL_DEPTH_TEST );
404 GLint maskTexComponent = 3;
405 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &maskTexComponent);
407 // The fake env chrome texture
408 glActiveTexturePtr( GL_TEXTURE1_ARB );
409 glEnable(GL_TEXTURE_2D);
411 // No lighting is computed in spherical mapping mode because the environment
412 // is supposed to be allready lighted. We must reshade our environment texture.
413 sgVec4 sunColor, ambientColor, envColor;
414 ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor );
415 ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor );
416 sgAddScaledVec3( envColor, ambientColor, sunColor, 0.4f);
417 glBindTexture(GL_TEXTURE_2D, my_shader->_effectTexture->getHandle());
420 sgSubVec3(delta_light, envColor, my_shader->_envColor);
421 if( (fabs(delta_light[0]) + fabs(delta_light[1]) + fabs(delta_light[2])) > 0.05f ) {
422 sgCopyVec3( my_shader->_envColor, envColor );
423 // reload the texture data and let the driver reshade it for us
424 glPixelTransferf( GL_RED_SCALE, envColor[0] );
425 glPixelTransferf( GL_GREEN_SCALE, envColor[1] );
426 glPixelTransferf( GL_BLUE_SCALE, envColor[2] );
427 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, my_shader->_texWidth, my_shader->_texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, my_shader->_textureData);
428 glPixelTransferf( GL_RED_SCALE, 1.0f );
429 glPixelTransferf( GL_GREEN_SCALE, 1.0f );
430 glPixelTransferf( GL_BLUE_SCALE, 1.0f );
433 if( maskTexComponent == 4 ) {
434 // c = lerp(model tex, chrome tex, model tex alpha)
435 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
436 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB );
437 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB );
438 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
439 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE );
440 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
441 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PREVIOUS_ARB );
442 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA );
444 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
445 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
446 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
449 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
450 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
451 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
453 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
454 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
455 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
457 // automatic generation of texture coordinates
460 glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
461 glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
462 glEnable( GL_TEXTURE_GEN_S );
463 glEnable( GL_TEXTURE_GEN_T );
465 glCallList ( dlist ) ;
467 glActiveTexturePtr( GL_TEXTURE1_ARB );
468 glDisable( GL_TEXTURE_GEN_S );
469 glDisable( GL_TEXTURE_GEN_T );
471 glMatrixMode(GL_TEXTURE);
473 glMatrixMode(GL_MODELVIEW);
475 glDisable(GL_TEXTURE_2D);
476 glBindTexture(GL_TEXTURE_2D, 0);
477 glActiveTexturePtr( GL_TEXTURE0_ARB );
480 if( ! my_shader->_depth_test )
481 glEnable( GL_DEPTH_TEST );
490 static void init_shaders(void) {
492 if( false && Shader::is_VP_supported() ) {
493 shFresnel = new Shader("/FlightGear/data/Textures/fresnel_vp.txt", "fresnel_vp");
494 // shFresnel->bindNames("somedata", 0);
496 glActiveTexturePtr = (glActiveTextureProc) SGLookupFunction("glActiveTextureARB");
497 const int fresnelSize = 512;
498 unsigned char imageFresnel[ fresnelSize * 3 ];
499 for(int i = 0; i < fresnelSize; i++) {
500 const float R0 = 0.2f;
501 float NdotV = float( i ) / float( fresnelSize );
502 float f = R0 + (1.0f-R0)*pow(1.0f - NdotV, 5);
503 unsigned char ff = (unsigned char) (f * 255.0);
504 imageFresnel[i*3+0] = imageFresnel[i*3+1] = imageFresnel[i*3+2] = ff;
506 glGenTextures( 1, &texFresnel );
507 glBindTexture(GL_TEXTURE_1D, texFresnel );
508 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
509 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
510 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
511 glTexParameteri(GL_TEXTURE_1D, GL_GENERATE_MIPMAP_SGIS, true);
512 glTexImage1D(GL_TEXTURE_1D, 0, 3, fresnelSize, 0, GL_RGB, GL_UNSIGNED_BYTE, imageFresnel);
513 glBindTexture(GL_TEXTURE_1D, 0 );
515 sgMakeIdentMat4( shadIdentMatrix );
520 ////////////////////////////////////////////////////////////////////////
521 // Implementation of SGShaderAnimation
522 ////////////////////////////////////////////////////////////////////////
524 SGShaderAnimation::SGShaderAnimation ( SGPropertyNode *prop_root,
525 SGPropertyNode_ptr props )
526 : SGAnimation(props, new ssgBranch),
528 _condition_value(true),
530 _param_1(props->getFloatValue("param", 1.0f)),
531 _depth_test(props->getBoolValue("depth-test", true)),
532 _factor(props->getFloatValue("factor", 1.0f)),
534 _speed(props->getFloatValue("speed", 1.0f)),
542 SGPropertyNode_ptr node = props->getChild("condition");
544 _condition = sgReadCondition(prop_root, node);
545 _condition_value = false;
547 node = props->getChild("factor-prop");
549 _factor_prop = prop_root->getNode(node->getStringValue(), true);
550 node = props->getChild("speed-prop");
552 _speed_prop = prop_root->getNode(node->getStringValue(), true);
554 sgSetVec4(_envColor, 0.0f, 0.0f, 0.0f, 1.0f);
555 node = props->getChild("texture");
557 _effectTexture = ssgGetCurrentOptions()->createTexture( (char *) node->getStringValue(), 0, 0, 0);
558 glBindTexture(GL_TEXTURE_2D, _effectTexture->getHandle() );
559 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &_texWidth);
560 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &_texHeight);
562 _textureData = new unsigned char[_texWidth * _texHeight * 3];
563 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, _textureData);
564 glBindTexture(GL_TEXTURE_2D, 0 );
566 string shader_name = props->getStringValue("shader");
567 if( shader_name == "fresnel" || shader_name == "reflection" )
569 else if( shader_name == "heat-haze" )
571 else if( shader_name == "chrome" && _effectTexture)
575 static void setCallBack(ssgBranch *branch, ssgBase *user_data, ssgCallback cb) {
576 for (int i = 0; i < branch->getNumKids(); i++) {
577 ssgEntity *e = branch->getKid(i);
578 if( e->isAKindOf( ssgTypeBranch() ) )
579 setCallBack( (ssgBranch *) e, user_data, cb);
580 else if( e->isAKindOf( ssgTypeVtxTable() ) ) {
581 e->setCallback( SSG_CALLBACK_PREDRAW, cb );
582 e->setUserData( user_data );
587 void SGShaderAnimation::init()
591 if( _shader_type == 1 && Shader::is_VP_supported() && shFresnel)
592 setCallBack( getBranch(), (ssgBase *) this, fresnel_shader_callback );
593 else if( _shader_type == 2 ) {
594 // this is the same extension with different names
595 isRectangleTextureSupported = SGIsOpenGLExtensionSupported("GL_EXT_texture_rectangle") ||
596 SGIsOpenGLExtensionSupported("GL_ARB_texture_rectangle") ||
597 SGIsOpenGLExtensionSupported("GL_NV_texture_rectangle");
598 setCallBack( getBranch(), (ssgBase *) this, heat_haze_shader_callback );
600 else if( _shader_type == 3 )
601 setCallBack( getBranch(), (ssgBase *) this, chrome_shader_callback );
603 setCallBack( getBranch(), (ssgBase *) this, null_shader_callback );
606 SGShaderAnimation::~SGShaderAnimation()
609 delete _effectTexture;
614 SGShaderAnimation::update()
617 _condition_value = _condition->test();
619 _factor = _factor_prop->getFloatValue();
621 _speed = _speed_prop->getFloatValue();
625 void sgShaderFrameInit(double delta_time_sec) {
626 haveBackground = false;
627 totalTime += delta_time_sec;