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>
28 #include <osg/Program>
30 #include <osg/StateSet>
31 #include <osg/TextureCubeMap>
32 #include <osg/TexEnvCombine>
34 #include <osg/Texture1D>
35 #include <osgUtil/HighlightMapGenerator>
37 #include <simgear/scene/util/SGUpdateVisitor.hxx>
38 #include <simgear/threads/SGThread.hxx>
39 #include <simgear/threads/SGGuard.hxx>
41 #include <simgear/props/condition.hxx>
42 #include <simgear/props/props.hxx>
44 #include <simgear/debug/logstream.hxx>
46 #include "animation.hxx"
51 <shader>fresnel</shader>
52 <object-name>...</object-name>
57 <shader>heat-haze</shader>
58 <object-name>...</object-name>
60 <speed-prop>...</speed-prop>
62 <factor-prop>...</factor-prop>
67 <shader>chrome</shader>
68 <texture>...</texture>
69 <object-name>...</object-name>
75 <object-name>...</object-name>
76 <depth-test>false</depth-test>
82 class SGMapGenCallback :
83 public osg::StateAttribute::Callback {
85 virtual void operator () (osg::StateAttribute* sa, osg::NodeVisitor* nv)
87 SGUpdateVisitor* updateVisitor = dynamic_cast<SGUpdateVisitor*>(nv);
91 if (distSqr(_lastLightDirection, updateVisitor->getLightDirection()) < 1e-4
92 && distSqr(_lastLightColor, updateVisitor->getAmbientLight()) < 1e-4)
95 _lastLightDirection = updateVisitor->getLightDirection();
96 _lastLightColor = updateVisitor->getAmbientLight();
98 osg::TextureCubeMap *tcm = static_cast<osg::TextureCubeMap*>(sa);
100 // FIXME: need an update or callback ...
101 // generate the six highlight map images (light direction = [1, 1, -1])
102 osg::ref_ptr<osgUtil::HighlightMapGenerator> mapgen;
103 mapgen = new osgUtil::HighlightMapGenerator(_lastLightDirection.osg(),
104 _lastLightColor.osg(), 5);
105 mapgen->generateMap();
107 // assign the six images to the texture object
108 tcm->setImage(osg::TextureCubeMap::POSITIVE_X,
109 mapgen->getImage(osg::TextureCubeMap::POSITIVE_X));
110 tcm->setImage(osg::TextureCubeMap::NEGATIVE_X,
111 mapgen->getImage(osg::TextureCubeMap::NEGATIVE_X));
112 tcm->setImage(osg::TextureCubeMap::POSITIVE_Y,
113 mapgen->getImage(osg::TextureCubeMap::POSITIVE_Y));
114 tcm->setImage(osg::TextureCubeMap::NEGATIVE_Y,
115 mapgen->getImage(osg::TextureCubeMap::NEGATIVE_Y));
116 tcm->setImage(osg::TextureCubeMap::POSITIVE_Z,
117 mapgen->getImage(osg::TextureCubeMap::POSITIVE_Z));
118 tcm->setImage(osg::TextureCubeMap::NEGATIVE_Z,
119 mapgen->getImage(osg::TextureCubeMap::NEGATIVE_Z));
122 SGVec3f _lastLightDirection;
123 SGVec4f _lastLightColor;
126 static osg::TextureCubeMap*
127 getOrCreateTextureCubeMap()
129 static osg::ref_ptr<osg::TextureCubeMap> textureCubeMap;
130 if (textureCubeMap.get())
131 return textureCubeMap.get();
133 static SGMutex mutex;
134 SGGuard<SGMutex> locker(mutex);
135 if (textureCubeMap.get())
136 return textureCubeMap.get();
138 // create and setup the texture object
139 textureCubeMap = new osg::TextureCubeMap;
141 textureCubeMap->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);
142 textureCubeMap->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP);
143 textureCubeMap->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP);
144 textureCubeMap->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
145 textureCubeMap->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
147 textureCubeMap->setUpdateCallback(new SGMapGenCallback);
149 return textureCubeMap.get();
152 static void create_specular_highlights(osg::Node *node)
154 osg::StateSet *ss = node->getOrCreateStateSet();
156 // create and setup the texture object
157 osg::TextureCubeMap *tcm = getOrCreateTextureCubeMap();
159 // enable texturing, replacing any textures in the subgraphs
160 ss->setTextureAttributeAndModes(0, tcm, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
162 // texture coordinate generation
163 osg::TexGen *tg = new osg::TexGen;
164 tg->setMode(osg::TexGen::REFLECTION_MAP);
165 ss->setTextureAttributeAndModes(0, tg, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
167 // use TexEnvCombine to add the highlights to the original lighting
168 osg::TexEnvCombine *te = new osg::TexEnvCombine;
169 te->setCombine_RGB(osg::TexEnvCombine::ADD);
170 te->setSource0_RGB(osg::TexEnvCombine::TEXTURE);
171 te->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
172 te->setSource1_RGB(osg::TexEnvCombine::PRIMARY_COLOR);
173 te->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
174 ss->setTextureAttributeAndModes(0, te, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
178 SGShaderAnimation::SGShaderAnimation(const SGPropertyNode* configNode,
179 SGPropertyNode* modelRoot) :
180 SGAnimation(configNode, modelRoot)
185 SGShaderAnimation::createAnimationGroup(osg::Group& parent)
187 osg::Group* group = new osg::Group;
188 group->setName("shader animation");
189 parent.addChild(group);
191 std::string shader_name = getConfig()->getStringValue("shader", "");
192 // if( shader_name == "fresnel" || shader_name == "reflection" )
194 // else if( shader_name == "heat-haze" )
197 if( shader_name == "chrome")
198 create_specular_highlights(group);
204 // static Shader *shFresnel=NULL;
205 // static GLuint texFresnel = 0;
207 // static GLuint texBackground = 0;
208 // static int texBackgroundWidth = 1024, texBackgroundHeight = 1024;
209 // static GLenum texBackgroundTarget = GL_TEXTURE_2D;
210 // static bool isRectangleTextureSupported = false;
211 // static bool istexBackgroundRectangle = false;
212 // static bool initDone = false;
213 static bool haveBackground = false;
215 // static glActiveTextureProc glActiveTexturePtr = 0;
216 // static sgMat4 shadIdentMatrix;
219 // static int null_shader_callback( ssgEntity *e ) {
221 // ssgLeaf *leaf = (ssgLeaf *) e;
222 // #ifdef _SSG_USE_DLIST
223 // dlist = leaf->getDListIndex();
225 // leaf->makeDList();
226 // dlist = leaf->getDListIndex();
231 // ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
235 // SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
236 // if( ! my_shader->_depth_test )
237 // glDisable( GL_DEPTH_TEST );
238 // glCallList ( dlist ) ;
240 // if( ! my_shader->_depth_test )
241 // glEnable( GL_DEPTH_TEST );
247 // static int heat_haze_shader_callback( ssgEntity *e ) {
248 // if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() )
252 // ssgLeaf *leaf = (ssgLeaf *) e;
253 // #ifdef _SSG_USE_DLIST
254 // dlist = leaf->getDListIndex();
256 // leaf->makeDList();
257 // dlist = leaf->getDListIndex();
263 // GLint viewport[4];
264 // glGetIntegerv( GL_VIEWPORT, viewport );
265 // const int screen_width = viewport[2];
266 // const int screen_height = viewport[3];
267 // if( ! haveBackground ) {
268 // // store the backbuffer in a texture
269 // if( ! texBackground ) {
270 // // allocate our texture here so we don't waste memory if no model use that effect
271 // // check if we need a rectangle texture and if the card support it
272 // if( (screen_width > 1024 || screen_height > 1024) && isRectangleTextureSupported ) {
273 // // Note that the 3 (same) extensions use the same enumerants
274 // texBackgroundTarget = GL_TEXTURE_RECTANGLE_NV;
275 // istexBackgroundRectangle = true;
276 // texBackgroundWidth = screen_width;
277 // texBackgroundHeight = screen_height;
279 // glGenTextures(1, &texBackground);
280 // glEnable(texBackgroundTarget);
281 // glBindTexture(texBackgroundTarget, texBackground);
282 // // trying to match the backbuffer pixel format
283 // GLint internalFormat = GL_RGB8;
284 // GLint colorBits = 0, alphaBits = 0;
285 // glGetIntegerv( GL_BLUE_BITS, &colorBits );
286 // glGetIntegerv( GL_ALPHA_BITS, &alphaBits );
287 // if(colorBits == 5) {
288 // if( alphaBits == 0 )
289 // internalFormat = GL_RGB5;
291 // internalFormat = GL_RGB5_A1;
293 // if( alphaBits != 0 )
294 // internalFormat = GL_RGBA8;
296 // glTexImage2D(texBackgroundTarget, 0, internalFormat,
297 // texBackgroundWidth, texBackgroundHeight, 0, GL_RGB, GL_FLOAT, NULL);
299 // glTexParameteri(texBackgroundTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
300 // glTexParameteri(texBackgroundTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
301 // glTexParameteri(texBackgroundTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
302 // glTexParameteri(texBackgroundTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
304 // glEnable(texBackgroundTarget);
305 // glBindTexture(texBackgroundTarget, texBackground);
306 // // center of texture = center of screen
307 // // obviously we don't have the whole screen if screen_width > texBackgroundWidth
308 // // if rectangle textures are not supported, this give some artifacts on the borders
309 // if( istexBackgroundRectangle ) {
310 // glCopyTexSubImage2D( texBackgroundTarget, 0, 0, 0,
311 // 0, 0, texBackgroundWidth, texBackgroundHeight );
313 // glCopyTexSubImage2D( texBackgroundTarget, 0, 0, 0,
314 // (screen_width - texBackgroundWidth) / 2,
315 // (screen_height - texBackgroundHeight) / 2,
316 // texBackgroundWidth, texBackgroundHeight );
318 // haveBackground = true;
319 // glBindTexture(texBackgroundTarget, 0);
320 // glDisable(texBackgroundTarget);
322 // ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
326 // SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
327 // if( ! my_shader->_depth_test )
328 // glDisable( GL_DEPTH_TEST );
329 // glDepthMask( GL_FALSE );
330 // glDisable( GL_LIGHTING );
332 // // noise texture, tex coord from the model translated by a time factor
333 // glActiveTexturePtr( GL_TEXTURE0_ARB );
334 // glEnable(GL_TEXTURE_2D);
335 // const float noiseDist = fmod(- totalTime * my_shader->_factor * my_shader->_speed, 4.0);
336 // glMatrixMode(GL_TEXTURE);
338 // glTranslatef( noiseDist, 0.0f, 0.0f );
339 // glMatrixMode(GL_MODELVIEW);
341 // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
343 // // background texture
344 // glActiveTexturePtr( GL_TEXTURE1_ARB );
345 // glEnable(texBackgroundTarget);
346 // glBindTexture(texBackgroundTarget, texBackground);
348 // // automatic generation of texture coordinates
349 // // map to screen space
350 // sgMat4 CameraProjM, CameraViewM;
351 // glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat *) CameraProjM);
352 // glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) CameraViewM);
353 // // const float dummy_scale = 1.0f; //0.95f;
354 // const float deltaPos = 0.05f;
355 // glMatrixMode(GL_TEXTURE);
357 // if( istexBackgroundRectangle ) {
358 // // coords go from 0.0 to n, not from 0.0 to 1.0
359 // glTranslatef( texBackgroundWidth * 0.5f, texBackgroundHeight * 0.5f, 0.0f );
360 // glScalef( texBackgroundWidth * 0.5f,
361 // texBackgroundHeight * 0.5f, 1.0f );
363 // glTranslatef( 0.5f, 0.5f, 0.0f );
364 // glScalef( float( screen_width ) / float( texBackgroundWidth ) * 0.5f,
365 // float( screen_height ) / float( texBackgroundHeight ) * 0.5f, 1.0f );
367 // glMultMatrixf( (GLfloat *) CameraProjM );
368 // glMultMatrixf( (GLfloat *) CameraViewM );
369 // glTranslatef( deltaPos, deltaPos, deltaPos );
370 // glMatrixMode(GL_MODELVIEW);
372 // glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
373 // glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
374 // glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
375 // glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
376 // glTexGenfv( GL_S, GL_EYE_PLANE, shadIdentMatrix[0] );
377 // glTexGenfv( GL_T, GL_EYE_PLANE, shadIdentMatrix[1] );
378 // glTexGenfv( GL_R, GL_EYE_PLANE, shadIdentMatrix[2] );
379 // glTexGenfv( GL_Q, GL_EYE_PLANE, shadIdentMatrix[3] );
380 // glEnable( GL_TEXTURE_GEN_S );
381 // glEnable( GL_TEXTURE_GEN_T );
382 // glEnable( GL_TEXTURE_GEN_R );
383 // glEnable( GL_TEXTURE_GEN_Q );
385 // sgVec4 enviro = {1.00f, 1.00f, 1.00f, 0.85f};
387 // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
388 // glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
389 // glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
390 // glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
391 // glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT_ARB );
392 // glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
393 // glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, enviro);
395 // glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
396 // glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE0_ARB);
397 // glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
398 // glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB );
399 // glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA );
401 // glCallList ( dlist ) ;
402 // glMatrixMode(GL_TEXTURE);
403 // glTranslatef( - deltaPos*2.0f, -deltaPos*2.5f, -deltaPos*2.0f );
404 // glMatrixMode(GL_MODELVIEW);
405 // glCallList ( dlist ) ;
407 // // alter colors only on last rendering
408 // // sgVec4 fLight = {0.93f, 0.93f, 1.00f, 0.85f};
409 // glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB );
410 // glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
412 // glMatrixMode(GL_TEXTURE);
413 // glTranslatef( deltaPos*0.7f, deltaPos*1.7f, deltaPos*0.7f );
414 // glMatrixMode(GL_MODELVIEW);
415 // glCallList ( dlist ) ;
418 // glActiveTexturePtr( GL_TEXTURE1_ARB );
419 // glDisable( GL_TEXTURE_GEN_S );
420 // glDisable( GL_TEXTURE_GEN_T );
421 // glDisable( GL_TEXTURE_GEN_R );
422 // glDisable( GL_TEXTURE_GEN_Q );
423 // glMatrixMode(GL_TEXTURE);
425 // glMatrixMode(GL_MODELVIEW);
426 // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
427 // glDisable(texBackgroundTarget);
428 // glActiveTexturePtr( GL_TEXTURE0_ARB );
429 // glMatrixMode(GL_TEXTURE);
431 // glMatrixMode(GL_MODELVIEW);
432 // glEnable(GL_TEXTURE_2D);
433 // glBindTexture(GL_TEXTURE_2D, 0);
436 // if( ! my_shader->_depth_test )
437 // glEnable( GL_DEPTH_TEST );
439 // glEnable( GL_LIGHTING );
440 // glDepthMask( GL_TRUE );
448 // static int fresnel_shader_callback( ssgEntity *e ) {
449 // if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() )
453 // ssgLeaf *leaf = (ssgLeaf *) e;
454 // #ifdef _SSG_USE_DLIST
455 // dlist = leaf->getDListIndex();
457 // leaf->makeDList();
458 // dlist = leaf->getDListIndex();
463 // ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
467 // sgVec4 sunColor, ambientColor;
468 // ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor );
469 // ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor );
471 // // SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
472 // glEnable(GL_BLEND);
473 // glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
474 // glEnable(GL_ALPHA_TEST);
475 // glAlphaFunc(GL_GREATER, 0.0f);
478 // // sgVec4 R = {0.5,0.0,0.0,0.0};
479 // sgVec4 enviro = {1.0,0.0,0.0,1.0};
480 // // sgCopyVec4( enviro, sunColor );
481 // glActiveTexturePtr( GL_TEXTURE0_ARB );
482 // glEnable(GL_TEXTURE_2D);
483 // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
484 // glActiveTexturePtr( GL_TEXTURE1_ARB );
485 // glDisable(GL_TEXTURE_2D);
486 // glEnable(GL_TEXTURE_1D);
487 // glBindTexture(GL_TEXTURE_1D, texFresnel);
488 // // c = a0 * a2 + a1 * (1-a2)
489 // // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
490 // // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
491 // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
492 // glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB );
493 // glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_CONSTANT_ARB );
494 // glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
495 // glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB );
496 // glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
497 // glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE );
498 // glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR );
499 // glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, enviro);
500 // shFresnel->enable();
501 // shFresnel->bind();
502 // glCallList ( dlist ) ;
503 // shFresnel->disable();
504 // glActiveTexturePtr( GL_TEXTURE1_ARB );
505 // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
506 // glDisable(GL_TEXTURE_1D);
507 // glActiveTexturePtr( GL_TEXTURE0_ARB );
508 // glDisable(GL_TEXTURE_1D);
509 // glEnable(GL_TEXTURE_2D);
512 // // glBindTexture(GL_TEXTURE_2D, 0);
513 // // glDepthFunc(GL_LESS);
514 // // glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
524 // static int chrome_shader_callback( ssgEntity *e ) {
525 // if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() )
529 // ssgLeaf *leaf = (ssgLeaf *) e;
530 // #ifdef _SSG_USE_DLIST
531 // dlist = leaf->getDListIndex();
533 // leaf->makeDList();
534 // dlist = leaf->getDListIndex();
539 // ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
543 // SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
544 // if( ! my_shader->_depth_test )
545 // glDisable( GL_DEPTH_TEST );
547 // GLint maskTexComponent = 3;
548 // glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &maskTexComponent);
550 // // The fake env chrome texture
551 // glActiveTexturePtr( GL_TEXTURE1_ARB );
552 // glEnable(GL_TEXTURE_2D);
554 // // No lighting is computed in spherical mapping mode because the environment
555 // // is supposed to be allready lighted. We must reshade our environment texture.
556 // sgVec4 sunColor, ambientColor, envColor;
557 // ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor );
558 // ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor );
559 // sgAddScaledVec3( envColor, ambientColor, sunColor, 0.4f);
560 // glBindTexture(GL_TEXTURE_2D, my_shader->_effectTexture->getHandle());
562 // sgVec3 delta_light;
563 // sgSubVec3(delta_light, envColor, my_shader->_envColor);
564 // if( (fabs(delta_light[0]) + fabs(delta_light[1]) + fabs(delta_light[2])) > 0.05f ) {
565 // sgCopyVec3( my_shader->_envColor, envColor );
566 // // reload the texture data and let the driver reshade it for us
567 // glPixelTransferf( GL_RED_SCALE, envColor[0] );
568 // glPixelTransferf( GL_GREEN_SCALE, envColor[1] );
569 // glPixelTransferf( GL_BLUE_SCALE, envColor[2] );
570 // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, my_shader->_texWidth, my_shader->_texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, my_shader->_textureData);
571 // glPixelTransferf( GL_RED_SCALE, 1.0f );
572 // glPixelTransferf( GL_GREEN_SCALE, 1.0f );
573 // glPixelTransferf( GL_BLUE_SCALE, 1.0f );
576 // if( maskTexComponent == 4 ) {
577 // // c = lerp(model tex, chrome tex, model tex alpha)
578 // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
579 // glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB );
580 // glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB );
581 // glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
582 // glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE );
583 // glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
584 // glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PREVIOUS_ARB );
585 // glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA );
587 // glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
588 // glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
589 // glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
592 // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
593 // glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
594 // glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
596 // glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
597 // glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
598 // glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
600 // // automatic generation of texture coordinates
603 // glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
604 // glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
605 // glEnable( GL_TEXTURE_GEN_S );
606 // glEnable( GL_TEXTURE_GEN_T );
608 // glCallList ( dlist ) ;
610 // glActiveTexturePtr( GL_TEXTURE1_ARB );
611 // glDisable( GL_TEXTURE_GEN_S );
612 // glDisable( GL_TEXTURE_GEN_T );
614 // glMatrixMode(GL_TEXTURE);
616 // glMatrixMode(GL_MODELVIEW);
618 // glDisable(GL_TEXTURE_2D);
619 // glBindTexture(GL_TEXTURE_2D, 0);
620 // glActiveTexturePtr( GL_TEXTURE0_ARB );
623 // if( ! my_shader->_depth_test )
624 // glEnable( GL_DEPTH_TEST );
633 // static void init_shaders(void) {
635 // if( false && Shader::is_VP_supported() ) {
636 // shFresnel = new Shader("/FlightGear/data/Textures/fresnel_vp.txt", "fresnel_vp");
638 // glActiveTexturePtr = (glActiveTextureProc) SGLookupFunction("glActiveTextureARB");
639 // const int fresnelSize = 512;
640 // unsigned char imageFresnel[ fresnelSize * 3 ];
641 // for(int i = 0; i < fresnelSize; i++) {
642 // const float R0 = 0.2f;
643 // float NdotV = float( i ) / float( fresnelSize );
644 // float f = R0 + (1.0f-R0)*pow(1.0f - NdotV, 5);
645 // unsigned char ff = (unsigned char) (f * 255.0);
646 // imageFresnel[i*3+0] = imageFresnel[i*3+1] = imageFresnel[i*3+2] = ff;
648 // glGenTextures( 1, &texFresnel );
649 // glBindTexture(GL_TEXTURE_1D, texFresnel );
650 // glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
651 // glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
652 // glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
653 // glTexParameteri(GL_TEXTURE_1D, GL_GENERATE_MIPMAP_SGIS, true);
654 // glTexImage1D(GL_TEXTURE_1D, 0, 3, fresnelSize, 0, GL_RGB, GL_UNSIGNED_BYTE, imageFresnel);
655 // glBindTexture(GL_TEXTURE_1D, 0 );
657 // sgMakeIdentMat4( shadIdentMatrix );
662 // ////////////////////////////////////////////////////////////////////////
663 // // Implementation of SGShaderAnimation
664 // ////////////////////////////////////////////////////////////////////////
666 SGShaderAnimation::SGShaderAnimation ( SGPropertyNode *prop_root,
667 SGPropertyNode_ptr props )
668 : SGAnimation(props, new osg::Group),
670 _condition_value(true),
672 _param_1(props->getFloatValue("param", 1.0f)),
673 _depth_test(props->getBoolValue("depth-test", true)),
674 _factor(props->getFloatValue("factor", 1.0f)),
676 _speed(props->getFloatValue("speed", 1.0f)),
683 SGPropertyNode_ptr node = props->getChild("condition");
685 _condition = sgReadCondition(prop_root, node);
686 _condition_value = false;
688 node = props->getChild("factor-prop");
690 _factor_prop = prop_root->getNode(node->getStringValue(), true);
691 node = props->getChild("speed-prop");
693 _speed_prop = prop_root->getNode(node->getStringValue(), true);
695 _envColor = osg::Vec4(0, 0, 0, 1);
696 node = props->getChild("texture");
698 _effectTexture = SGLoadTexture2D(node->getStringValue());
699 // glBindTexture(GL_TEXTURE_2D, _effectTexture->getHandle() );
700 // glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &_texWidth);
701 // glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &_texHeight);
703 // _textureData = new unsigned char[_texWidth * _texHeight * 3];
704 // glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, _textureData);
705 // glBindTexture(GL_TEXTURE_2D, 0 );
707 string shader_name = props->getStringValue("shader");
708 if( shader_name == "fresnel" || shader_name == "reflection" )
710 else if( shader_name == "heat-haze" )
712 else if( shader_name == "chrome" && _effectTexture.valid())
716 void SGShaderAnimation::init()
720 // if( _shader_type == 1 && Shader::is_VP_supported() && shFresnel)
721 // setCallBack( getBranch(), (ssgBase *) this, fresnel_shader_callback );
722 // else if( _shader_type == 2 ) {
723 // // this is the same extension with different names
724 // isRectangleTextureSupported = SGIsOpenGLExtensionSupported("GL_EXT_texture_rectangle") ||
725 // SGIsOpenGLExtensionSupported("GL_ARB_texture_rectangle") ||
726 // SGIsOpenGLExtensionSupported("GL_NV_texture_rectangle");
727 // setCallBack( getBranch(), (ssgBase *) this, heat_haze_shader_callback );
729 // else if( _shader_type == 3 )
730 // setCallBack( getBranch(), (ssgBase *) this, chrome_shader_callback );
732 // setCallBack( getBranch(), (ssgBase *) this, null_shader_callback );
735 SGShaderAnimation::~SGShaderAnimation()
742 SGShaderAnimation::operator()(osg::Node* node, osg::NodeVisitor* nv)
745 _condition_value = _condition->test();
747 _factor = _factor_prop->getFloatValue();
749 _speed = _speed_prop->getFloatValue();
751 // OSGFIXME fiddle with totalTime
752 totalTime = nv->getFrameStamp()->getReferenceTime();
754 // note, callback is responsible for scenegraph traversal so
755 // should always include call traverse(node,nv) to ensure
756 // that the rest of cullbacks and the scene graph are traversed.