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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 # include <simgear_config.h>
31 #include <simgear/props/condition.hxx>
32 #include <simgear/props/props.hxx>
33 #include <simgear/screen/extensions.hxx>
35 #include <simgear/debug/logstream.hxx>
37 #include <simgear/screen/shader.h>
39 #include "animation.hxx"
43 <shader>fresnel</shader>
44 <object-name>...</object-name>
49 <shader>heat-haze</shader>
50 <object-name>...</object-name>
52 <speed-prop>...</speed-prop>
54 <factor-prop>...</factor-prop>
59 <shader>chrome</shader>
60 <texture>...</texture>
61 <object-name>...</object-name>
67 <object-name>...</object-name>
68 <depth-test>false</depth-test>
72 static Shader *shFresnel=NULL;
73 static GLuint texFresnel = 0;
75 static GLuint texBackground = 0;
76 static int texBackgroundWidth = 1024, texBackgroundHeight = 1024;
77 static GLenum texBackgroundTarget = GL_TEXTURE_2D;
78 static bool isRectangleTextureSupported = false;
79 static bool istexBackgroundRectangle = false;
80 static bool initDone = false;
81 static bool haveBackground = false;
83 static glActiveTextureProc glActiveTexturePtr = 0;
84 static double totalTime = 0.0;
85 static sgMat4 shadIdentMatrix;
88 static int null_shader_callback( ssgEntity *e ) {
90 ssgLeaf *leaf = (ssgLeaf *) e;
92 dlist = leaf->getDListIndex();
95 dlist = leaf->getDListIndex();
100 ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
104 SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
105 if( ! my_shader->_depth_test )
106 glDisable( GL_DEPTH_TEST );
107 glCallList ( dlist ) ;
109 if( ! my_shader->_depth_test )
110 glEnable( GL_DEPTH_TEST );
116 static int heat_haze_shader_callback( ssgEntity *e ) {
117 if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() )
121 ssgLeaf *leaf = (ssgLeaf *) e;
122 #ifdef _SSG_USE_DLIST
123 dlist = leaf->getDListIndex();
126 dlist = leaf->getDListIndex();
133 glGetIntegerv( GL_VIEWPORT, viewport );
134 const int screen_width = viewport[2];
135 const int screen_height = viewport[3];
136 if( ! haveBackground ) {
137 // store the backbuffer in a texture
138 if( ! texBackground ) {
139 // allocate our texture here so we don't waste memory if no model use that effect
140 // check if we need a rectangle texture and if the card support it
141 if( (screen_width > 1024 || screen_height > 1024) && isRectangleTextureSupported ) {
142 // Note that the 3 (same) extensions use the same enumerants
143 texBackgroundTarget = GL_TEXTURE_RECTANGLE_NV;
144 istexBackgroundRectangle = true;
145 texBackgroundWidth = screen_width;
146 texBackgroundHeight = screen_height;
148 glGenTextures(1, &texBackground);
149 glEnable(texBackgroundTarget);
150 glBindTexture(texBackgroundTarget, texBackground);
151 // trying to match the backbuffer pixel format
152 GLint internalFormat = GL_RGB8;
153 GLint colorBits = 0, alphaBits = 0;
154 glGetIntegerv( GL_BLUE_BITS, &colorBits );
155 glGetIntegerv( GL_ALPHA_BITS, &alphaBits );
158 internalFormat = GL_RGB5;
160 internalFormat = GL_RGB5_A1;
163 internalFormat = GL_RGBA8;
165 glTexImage2D(texBackgroundTarget, 0, internalFormat,
166 texBackgroundWidth, texBackgroundHeight, 0, GL_RGB, GL_FLOAT, NULL);
168 glTexParameteri(texBackgroundTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
169 glTexParameteri(texBackgroundTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
170 glTexParameteri(texBackgroundTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
171 glTexParameteri(texBackgroundTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
173 glEnable(texBackgroundTarget);
174 glBindTexture(texBackgroundTarget, texBackground);
175 // center of texture = center of screen
176 // obviously we don't have the whole screen if screen_width > texBackgroundWidth
177 // if rectangle textures are not supported, this give some artifacts on the borders
178 if( istexBackgroundRectangle ) {
179 glCopyTexSubImage2D( texBackgroundTarget, 0, 0, 0,
180 0, 0, texBackgroundWidth, texBackgroundHeight );
182 glCopyTexSubImage2D( texBackgroundTarget, 0, 0, 0,
183 (screen_width - texBackgroundWidth) / 2,
184 (screen_height - texBackgroundHeight) / 2,
185 texBackgroundWidth, texBackgroundHeight );
187 haveBackground = true;
188 glBindTexture(texBackgroundTarget, 0);
189 glDisable(texBackgroundTarget);
191 ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
195 SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
196 if( ! my_shader->_depth_test )
197 glDisable( GL_DEPTH_TEST );
198 glDepthMask( GL_FALSE );
199 glDisable( GL_LIGHTING );
201 // noise texture, tex coord from the model translated by a time factor
202 glActiveTexturePtr( GL_TEXTURE0_ARB );
203 glEnable(GL_TEXTURE_2D);
204 const float noiseDist = fmod(- totalTime * my_shader->_factor * my_shader->_speed, 4.0);
205 glMatrixMode(GL_TEXTURE);
207 glTranslatef( noiseDist, 0.0f, 0.0f );
208 glMatrixMode(GL_MODELVIEW);
210 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
212 // background texture
213 glActiveTexturePtr( GL_TEXTURE1_ARB );
214 glEnable(texBackgroundTarget);
215 glBindTexture(texBackgroundTarget, texBackground);
217 // automatic generation of texture coordinates
218 // map to screen space
219 sgMat4 CameraProjM, CameraViewM;
220 glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat *) CameraProjM);
221 glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) CameraViewM);
222 // const float dummy_scale = 1.0f; //0.95f;
223 const float deltaPos = 0.05f;
224 glMatrixMode(GL_TEXTURE);
226 if( istexBackgroundRectangle ) {
227 // coords go from 0.0 to n, not from 0.0 to 1.0
228 glTranslatef( texBackgroundWidth * 0.5f, texBackgroundHeight * 0.5f, 0.0f );
229 glScalef( texBackgroundWidth * 0.5f,
230 texBackgroundHeight * 0.5f, 1.0f );
232 glTranslatef( 0.5f, 0.5f, 0.0f );
233 glScalef( float( screen_width ) / float( texBackgroundWidth ) * 0.5f,
234 float( screen_height ) / float( texBackgroundHeight ) * 0.5f, 1.0f );
236 glMultMatrixf( (GLfloat *) CameraProjM );
237 glMultMatrixf( (GLfloat *) CameraViewM );
238 glTranslatef( deltaPos, deltaPos, deltaPos );
239 glMatrixMode(GL_MODELVIEW);
241 glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
242 glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
243 glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
244 glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
245 glTexGenfv( GL_S, GL_EYE_PLANE, shadIdentMatrix[0] );
246 glTexGenfv( GL_T, GL_EYE_PLANE, shadIdentMatrix[1] );
247 glTexGenfv( GL_R, GL_EYE_PLANE, shadIdentMatrix[2] );
248 glTexGenfv( GL_Q, GL_EYE_PLANE, shadIdentMatrix[3] );
249 glEnable( GL_TEXTURE_GEN_S );
250 glEnable( GL_TEXTURE_GEN_T );
251 glEnable( GL_TEXTURE_GEN_R );
252 glEnable( GL_TEXTURE_GEN_Q );
254 sgVec4 enviro = {1.00f, 1.00f, 1.00f, 0.85f};
256 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
257 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
258 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
259 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
260 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT_ARB );
261 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
262 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, enviro);
264 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
265 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE0_ARB);
266 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
267 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB );
268 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA );
270 glCallList ( dlist ) ;
271 glMatrixMode(GL_TEXTURE);
272 glTranslatef( - deltaPos*2.0f, -deltaPos*2.5f, -deltaPos*2.0f );
273 glMatrixMode(GL_MODELVIEW);
274 glCallList ( dlist ) ;
276 // alter colors only on last rendering
277 // sgVec4 fLight = {0.93f, 0.93f, 1.00f, 0.85f};
278 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB );
279 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
281 glMatrixMode(GL_TEXTURE);
282 glTranslatef( deltaPos*0.7f, deltaPos*1.7f, deltaPos*0.7f );
283 glMatrixMode(GL_MODELVIEW);
284 glCallList ( dlist ) ;
287 glActiveTexturePtr( GL_TEXTURE1_ARB );
288 glDisable( GL_TEXTURE_GEN_S );
289 glDisable( GL_TEXTURE_GEN_T );
290 glDisable( GL_TEXTURE_GEN_R );
291 glDisable( GL_TEXTURE_GEN_Q );
292 glMatrixMode(GL_TEXTURE);
294 glMatrixMode(GL_MODELVIEW);
295 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
296 glDisable(texBackgroundTarget);
297 glActiveTexturePtr( GL_TEXTURE0_ARB );
298 glMatrixMode(GL_TEXTURE);
300 glMatrixMode(GL_MODELVIEW);
301 glEnable(GL_TEXTURE_2D);
302 glBindTexture(GL_TEXTURE_2D, 0);
305 if( ! my_shader->_depth_test )
306 glEnable( GL_DEPTH_TEST );
308 glEnable( GL_LIGHTING );
309 glDepthMask( GL_TRUE );
317 static int fresnel_shader_callback( ssgEntity *e ) {
318 if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() )
322 ssgLeaf *leaf = (ssgLeaf *) e;
323 #ifdef _SSG_USE_DLIST
324 dlist = leaf->getDListIndex();
327 dlist = leaf->getDListIndex();
332 ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
336 sgVec4 sunColor, ambientColor;
337 ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor );
338 ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor );
340 // SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
342 glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
343 glEnable(GL_ALPHA_TEST);
344 glAlphaFunc(GL_GREATER, 0.0f);
347 // sgVec4 R = {0.5,0.0,0.0,0.0};
348 sgVec4 enviro = {1.0,0.0,0.0,1.0};
349 // sgCopyVec4( enviro, sunColor );
350 glActiveTexturePtr( GL_TEXTURE0_ARB );
351 glEnable(GL_TEXTURE_2D);
352 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
353 glActiveTexturePtr( GL_TEXTURE1_ARB );
354 glDisable(GL_TEXTURE_2D);
355 glEnable(GL_TEXTURE_1D);
356 glBindTexture(GL_TEXTURE_1D, texFresnel);
357 // c = a0 * a2 + a1 * (1-a2)
358 // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
359 // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
360 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
361 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB );
362 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_CONSTANT_ARB );
363 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
364 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB );
365 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
366 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE );
367 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR );
368 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, enviro);
371 glCallList ( dlist ) ;
372 shFresnel->disable();
373 glActiveTexturePtr( GL_TEXTURE1_ARB );
374 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
375 glDisable(GL_TEXTURE_1D);
376 glActiveTexturePtr( GL_TEXTURE0_ARB );
377 glDisable(GL_TEXTURE_1D);
378 glEnable(GL_TEXTURE_2D);
381 // glBindTexture(GL_TEXTURE_2D, 0);
382 // glDepthFunc(GL_LESS);
383 // glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
393 static int chrome_shader_callback( ssgEntity *e ) {
394 if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() )
398 ssgLeaf *leaf = (ssgLeaf *) e;
399 #ifdef _SSG_USE_DLIST
400 dlist = leaf->getDListIndex();
403 dlist = leaf->getDListIndex();
408 ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
412 SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
413 if( ! my_shader->_depth_test )
414 glDisable( GL_DEPTH_TEST );
416 GLint maskTexComponent = 3;
417 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &maskTexComponent);
419 // The fake env chrome texture
420 glActiveTexturePtr( GL_TEXTURE1_ARB );
421 glEnable(GL_TEXTURE_2D);
423 // No lighting is computed in spherical mapping mode because the environment
424 // is supposed to be allready lighted. We must reshade our environment texture.
425 sgVec4 sunColor, ambientColor, envColor;
426 ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor );
427 ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor );
428 sgAddScaledVec3( envColor, ambientColor, sunColor, 0.4f);
429 glBindTexture(GL_TEXTURE_2D, my_shader->_effectTexture->getHandle());
432 sgSubVec3(delta_light, envColor, my_shader->_envColor);
433 if( (fabs(delta_light[0]) + fabs(delta_light[1]) + fabs(delta_light[2])) > 0.05f ) {
434 sgCopyVec3( my_shader->_envColor, envColor );
435 // reload the texture data and let the driver reshade it for us
436 glPixelTransferf( GL_RED_SCALE, envColor[0] );
437 glPixelTransferf( GL_GREEN_SCALE, envColor[1] );
438 glPixelTransferf( GL_BLUE_SCALE, envColor[2] );
439 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, my_shader->_texWidth, my_shader->_texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, my_shader->_textureData);
440 glPixelTransferf( GL_RED_SCALE, 1.0f );
441 glPixelTransferf( GL_GREEN_SCALE, 1.0f );
442 glPixelTransferf( GL_BLUE_SCALE, 1.0f );
445 if( maskTexComponent == 4 ) {
446 // c = lerp(model tex, chrome tex, model tex alpha)
447 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
448 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB );
449 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB );
450 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
451 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE );
452 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
453 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PREVIOUS_ARB );
454 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA );
456 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
457 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
458 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
461 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
462 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
463 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
465 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
466 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
467 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
469 // automatic generation of texture coordinates
472 glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
473 glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
474 glEnable( GL_TEXTURE_GEN_S );
475 glEnable( GL_TEXTURE_GEN_T );
477 glCallList ( dlist ) ;
479 glActiveTexturePtr( GL_TEXTURE1_ARB );
480 glDisable( GL_TEXTURE_GEN_S );
481 glDisable( GL_TEXTURE_GEN_T );
483 glMatrixMode(GL_TEXTURE);
485 glMatrixMode(GL_MODELVIEW);
487 glDisable(GL_TEXTURE_2D);
488 glBindTexture(GL_TEXTURE_2D, 0);
489 glActiveTexturePtr( GL_TEXTURE0_ARB );
492 if( ! my_shader->_depth_test )
493 glEnable( GL_DEPTH_TEST );
502 static void init_shaders(void) {
504 if( false && Shader::is_VP_supported() ) {
505 shFresnel = new Shader("/FlightGear/data/Textures/fresnel_vp.txt", "fresnel_vp");
506 // shFresnel->bindNames("somedata", 0);
508 glActiveTexturePtr = (glActiveTextureProc) SGLookupFunction("glActiveTextureARB");
509 const int fresnelSize = 512;
510 unsigned char imageFresnel[ fresnelSize * 3 ];
511 for(int i = 0; i < fresnelSize; i++) {
512 const float R0 = 0.2f;
513 float NdotV = float( i ) / float( fresnelSize );
514 float f = R0 + (1.0f-R0)*pow(1.0f - NdotV, 5);
515 unsigned char ff = (unsigned char) (f * 255.0);
516 imageFresnel[i*3+0] = imageFresnel[i*3+1] = imageFresnel[i*3+2] = ff;
518 glGenTextures( 1, &texFresnel );
519 glBindTexture(GL_TEXTURE_1D, texFresnel );
520 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
521 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
522 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
523 glTexParameteri(GL_TEXTURE_1D, GL_GENERATE_MIPMAP_SGIS, true);
524 glTexImage1D(GL_TEXTURE_1D, 0, 3, fresnelSize, 0, GL_RGB, GL_UNSIGNED_BYTE, imageFresnel);
525 glBindTexture(GL_TEXTURE_1D, 0 );
527 sgMakeIdentMat4( shadIdentMatrix );
532 ////////////////////////////////////////////////////////////////////////
533 // Implementation of SGShaderAnimation
534 ////////////////////////////////////////////////////////////////////////
536 SGShaderAnimation::SGShaderAnimation ( SGPropertyNode *prop_root,
537 SGPropertyNode_ptr props )
538 : SGAnimation(props, new ssgBranch),
540 _condition_value(true),
542 _param_1(props->getFloatValue("param", 1.0f)),
543 _depth_test(props->getBoolValue("depth-test", true)),
544 _factor(props->getFloatValue("factor", 1.0f)),
546 _speed(props->getFloatValue("speed", 1.0f)),
554 SGPropertyNode_ptr node = props->getChild("condition");
556 _condition = sgReadCondition(prop_root, node);
557 _condition_value = false;
559 node = props->getChild("factor-prop");
561 _factor_prop = prop_root->getNode(node->getStringValue(), true);
562 node = props->getChild("speed-prop");
564 _speed_prop = prop_root->getNode(node->getStringValue(), true);
566 sgSetVec4(_envColor, 0.0f, 0.0f, 0.0f, 1.0f);
567 node = props->getChild("texture");
569 _effectTexture = ssgGetCurrentOptions()->createTexture( (char *) node->getStringValue(), 0, 0, 0);
570 glBindTexture(GL_TEXTURE_2D, _effectTexture->getHandle() );
571 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &_texWidth);
572 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &_texHeight);
574 _textureData = new unsigned char[_texWidth * _texHeight * 3];
575 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, _textureData);
576 glBindTexture(GL_TEXTURE_2D, 0 );
578 string shader_name = props->getStringValue("shader");
579 if( shader_name == "fresnel" || shader_name == "reflection" )
581 else if( shader_name == "heat-haze" )
583 else if( shader_name == "chrome" && _effectTexture)
587 static void setCallBack(ssgBranch *branch, ssgBase *user_data, ssgCallback cb) {
588 for (int i = 0; i < branch->getNumKids(); i++) {
589 ssgEntity *e = branch->getKid(i);
590 if( e->isAKindOf( ssgTypeBranch() ) )
591 setCallBack( (ssgBranch *) e, user_data, cb);
592 else if( e->isAKindOf( ssgTypeVtxTable() ) ) {
593 e->setCallback( SSG_CALLBACK_PREDRAW, cb );
594 e->setUserData( user_data );
599 void SGShaderAnimation::init()
603 if( _shader_type == 1 && Shader::is_VP_supported() && shFresnel)
604 setCallBack( getBranch(), (ssgBase *) this, fresnel_shader_callback );
605 else if( _shader_type == 2 ) {
606 // this is the same extension with different names
607 isRectangleTextureSupported = SGIsOpenGLExtensionSupported("GL_EXT_texture_rectangle") ||
608 SGIsOpenGLExtensionSupported("GL_ARB_texture_rectangle") ||
609 SGIsOpenGLExtensionSupported("GL_NV_texture_rectangle");
610 setCallBack( getBranch(), (ssgBase *) this, heat_haze_shader_callback );
612 else if( _shader_type == 3 )
613 setCallBack( getBranch(), (ssgBase *) this, chrome_shader_callback );
615 setCallBack( getBranch(), (ssgBase *) this, null_shader_callback );
618 SGShaderAnimation::~SGShaderAnimation()
621 delete _effectTexture;
626 SGShaderAnimation::update()
629 _condition_value = _condition->test();
631 _factor = _factor_prop->getFloatValue();
633 _speed = _speed_prop->getFloatValue();
637 void sgShaderFrameInit(double delta_time_sec) {
638 haveBackground = false;
639 totalTime += delta_time_sec;