]> git.mxchange.org Git - simgear.git/blob - simgear/scene/model/shadanim.cxx
Modified Files:
[simgear.git] / simgear / scene / model / shadanim.cxx
1 // non fixed Opengl pipeline rendering
2 //
3 // Written by Harald JOHNSEN, started Jully 2005.
4 //
5 // Copyright (C) 2005  Harald JOHNSEN
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 as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 //
22
23 #ifdef HAVE_CONFIG_H
24 #  include <simgear_config.h>
25 #endif
26
27 #include <osg/Group>
28 #include <osg/Program>
29 #include <osg/Shader>
30 #include <osg/StateSet>
31 #include <osg/TextureCubeMap>
32 #include <osg/TexEnvCombine>
33 #include <osg/TexGen>
34 #include <osg/Texture1D>
35 #include <osgUtil/HighlightMapGenerator>
36
37 #include <simgear/scene/util/SGUpdateVisitor.hxx>
38 #include <simgear/threads/SGThread.hxx>
39 #include <simgear/threads/SGGuard.hxx>
40
41 #include <simgear/props/condition.hxx>
42 #include <simgear/props/props.hxx>
43
44 #include <simgear/debug/logstream.hxx>
45
46 #include "animation.hxx"
47 #include "model.hxx"
48 /*
49     <animation>
50         <type>shader</type>
51         <shader>fresnel</shader>
52         <object-name>...</object-name>
53     </animation>
54
55     <animation>
56         <type>shader</type>
57         <shader>heat-haze</shader>
58         <object-name>...</object-name>
59         <speed>...</speed>
60         <speed-prop>...</speed-prop>
61         <factor>...</factor>
62         <factor-prop>...</factor-prop>
63     </animation>
64
65     <animation>
66         <type>shader</type>
67         <shader>chrome</shader>
68         <texture>...</texture>
69         <object-name>...</object-name>
70     </animation>
71
72     <animation>
73         <type>shader</type>
74         <shader></shader>
75         <object-name>...</object-name>
76         <depth-test>false</depth-test>
77     </animation>
78
79 */
80
81
82 class SGMapGenCallback :
83   public osg::StateAttribute::Callback {
84 public:
85   virtual void operator () (osg::StateAttribute* sa, osg::NodeVisitor* nv)
86   {
87     SGUpdateVisitor* updateVisitor = dynamic_cast<SGUpdateVisitor*>(nv);
88     if (!updateVisitor)
89       return;
90
91     if (distSqr(_lastLightDirection, updateVisitor->getLightDirection()) < 1e-4
92         && distSqr(_lastLightColor, updateVisitor->getAmbientLight()) < 1e-4)
93       return;
94
95     _lastLightDirection = updateVisitor->getLightDirection();
96     _lastLightColor = updateVisitor->getAmbientLight();
97
98     osg::TextureCubeMap *tcm = static_cast<osg::TextureCubeMap*>(sa);
99
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();
106
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));
120   }
121 private:
122   SGVec3f _lastLightDirection;
123   SGVec4f _lastLightColor;
124 };
125
126 static osg::TextureCubeMap*
127 getOrCreateTextureCubeMap()
128 {
129   static osg::TextureCubeMap* textureCubeMap = 0;
130   if (textureCubeMap)
131     return textureCubeMap;
132
133   static SGMutex mutex;
134   SGGuard<SGMutex> locker(mutex);
135   if (textureCubeMap)
136     return textureCubeMap;
137
138   // create and setup the texture object
139   textureCubeMap = new osg::TextureCubeMap;
140
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);    
146   
147   textureCubeMap->setUpdateCallback(new SGMapGenCallback);
148
149   return textureCubeMap;
150 }
151
152 static void create_specular_highlights(osg::Node *node)
153 {
154   osg::StateSet *ss = node->getOrCreateStateSet();
155   
156   // create and setup the texture object
157   osg::TextureCubeMap *tcm = getOrCreateTextureCubeMap();
158   
159   // enable texturing, replacing any textures in the subgraphs
160   ss->setTextureAttributeAndModes(0, tcm, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
161   
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);
166   
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);
175 }
176
177
178 SGShaderAnimation::SGShaderAnimation(const SGPropertyNode* configNode,
179                                      SGPropertyNode* modelRoot) :
180   SGAnimation(configNode, modelRoot)
181 {
182 }
183
184 osg::Group*
185 SGShaderAnimation::createAnimationGroup(osg::Group& parent)
186 {
187   osg::Group* group = new osg::Group;
188   group->setName("shader animation");
189   parent.addChild(group);
190
191   std::string shader_name = getConfig()->getStringValue("shader", "");
192 //   if( shader_name == "fresnel" || shader_name == "reflection" )
193 //     _shader_type = 1;
194 //   else if( shader_name == "heat-haze" )
195 //     _shader_type = 2;
196 //   else
197   if( shader_name == "chrome")
198     create_specular_highlights(group);
199
200   return group;
201 }
202
203 #if 0
204 // static Shader *shFresnel=NULL;
205 // static GLuint texFresnel = 0;
206
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;
214
215 // static glActiveTextureProc glActiveTexturePtr = 0;
216 // static sgMat4 shadIdentMatrix;
217
218
219 // static int null_shader_callback( ssgEntity *e ) {
220 //      GLuint dlist = 0;
221 //     ssgLeaf *leaf = (ssgLeaf *) e;
222 // #ifdef _SSG_USE_DLIST
223 //     dlist = leaf->getDListIndex();
224 //     if( ! dlist ) {
225 //         leaf->makeDList();
226 //         dlist = leaf->getDListIndex();
227 //     }
228 // #endif
229 //     if( ! dlist )
230 //         return true;
231 //     ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
232 //     if ( sst )
233 //         sst->apply();
234
235 //     SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
236 //     if( ! my_shader->_depth_test )
237 //         glDisable( GL_DEPTH_TEST );
238 //     glCallList ( dlist ) ;
239 //     // restore states
240 //     if( ! my_shader->_depth_test )
241 //         glEnable( GL_DEPTH_TEST );
242
243 //     // don't draw !
244 //     return false;
245 // }
246
247 // static int heat_haze_shader_callback( ssgEntity *e ) {
248 //    if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() )
249 //        return true;
250
251 //      GLuint dlist = 0;
252 //     ssgLeaf *leaf = (ssgLeaf *) e;
253 // #ifdef _SSG_USE_DLIST
254 //     dlist = leaf->getDListIndex();
255 //     if( ! dlist ) {
256 //         leaf->makeDList();
257 //         dlist = leaf->getDListIndex();
258 //     }
259 // #endif
260 //     if( ! dlist )
261 //         return true;
262
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;
278 //             }
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;
290 //                 else
291 //                     internalFormat = GL_RGB5_A1;
292 //             } else {
293 //                 if( alphaBits != 0 )
294 //                     internalFormat = GL_RGBA8;
295 //             }
296 //             glTexImage2D(texBackgroundTarget, 0, internalFormat, 
297 //                             texBackgroundWidth, texBackgroundHeight, 0, GL_RGB, GL_FLOAT, NULL);
298
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);
303 //         }
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 );
312 //         } else {
313 //             glCopyTexSubImage2D( texBackgroundTarget, 0, 0, 0, 
314 //                 (screen_width - texBackgroundWidth) / 2, 
315 //                 (screen_height - texBackgroundHeight) / 2, 
316 //                 texBackgroundWidth, texBackgroundHeight );
317 //         }
318 //         haveBackground = true;
319 //         glBindTexture(texBackgroundTarget, 0);
320 //         glDisable(texBackgroundTarget);
321 //     }
322 //     ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
323 //     if ( sst )
324 //         sst->apply();
325
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 );
331 //     if(1) {
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);
337 //             glLoadIdentity();
338 //             glTranslatef( noiseDist, 0.0f, 0.0f );
339 //         glMatrixMode(GL_MODELVIEW);
340
341 //         glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
342
343 //         // background texture
344 //         glActiveTexturePtr( GL_TEXTURE1_ARB );
345 //         glEnable(texBackgroundTarget);
346 //         glBindTexture(texBackgroundTarget, texBackground);
347
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);
356 //             glLoadIdentity();
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 );
362 //             } else {
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 );
366 //             }
367 //             glMultMatrixf( (GLfloat *) CameraProjM );
368 //             glMultMatrixf( (GLfloat *) CameraViewM );
369 //             glTranslatef( deltaPos, deltaPos, deltaPos );
370 //         glMatrixMode(GL_MODELVIEW);
371
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 );
384
385 //         sgVec4 enviro = {1.00f, 1.00f, 1.00f, 0.85f};
386
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);
394
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 ); 
400
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 ) ;
406
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 ); 
411
412 //         glMatrixMode(GL_TEXTURE);
413 //         glTranslatef( deltaPos*0.7f, deltaPos*1.7f, deltaPos*0.7f );
414 //         glMatrixMode(GL_MODELVIEW);
415 //         glCallList ( dlist ) ;
416
417
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);
424 //             glLoadIdentity();
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);
430 //             glLoadIdentity();
431 //         glMatrixMode(GL_MODELVIEW);
432 //         glEnable(GL_TEXTURE_2D);
433 //         glBindTexture(GL_TEXTURE_2D, 0);
434 //     }
435 //     // restore states
436 //     if( ! my_shader->_depth_test )
437 //         glEnable( GL_DEPTH_TEST );
438
439 //     glEnable( GL_LIGHTING );
440 //     glDepthMask( GL_TRUE );
441 //     if( sst )
442 //         sst->force();
443
444 //    // don't draw !
445 //     return false;
446 // }
447
448 // static int fresnel_shader_callback( ssgEntity *e ) {
449 //    if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() )
450 //        return true;
451
452 //      GLuint dlist = 0;
453 //     ssgLeaf *leaf = (ssgLeaf *) e;
454 // #ifdef _SSG_USE_DLIST
455 //     dlist = leaf->getDListIndex();
456 //     if( ! dlist ) {
457 //         leaf->makeDList();
458 //         dlist = leaf->getDListIndex();
459 //     }
460 // #endif
461 //     if( ! dlist )
462 //         return true;
463 //     ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
464 //     if ( sst )
465 //         sst->apply();
466
467 //     sgVec4 sunColor, ambientColor;
468 //     ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor );
469 //     ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor );
470
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);
476
477 //      if( true ) {
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);
510 //     }
511 //     // restore states
512 // //    glBindTexture(GL_TEXTURE_2D, 0);
513 // //    glDepthFunc(GL_LESS);
514 // //    glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
515 //    if( sst )
516 //          sst->force();
517
518 //     // don't draw !
519 //     return false;
520 // }
521
522
523
524 // static int chrome_shader_callback( ssgEntity *e ) {
525 //    if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() )
526 //        return true;
527
528 //      GLuint dlist = 0;
529 //     ssgLeaf *leaf = (ssgLeaf *) e;
530 // #ifdef _SSG_USE_DLIST
531 //     dlist = leaf->getDListIndex();
532 //     if( ! dlist ) {
533 //         leaf->makeDList();
534 //         dlist = leaf->getDListIndex();
535 //     }
536 // #endif
537 //     if( ! dlist )
538 //         return true;
539 //     ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
540 //     if ( sst )
541 //         sst->apply();
542
543 //     SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
544 //     if( ! my_shader->_depth_test )
545 //         glDisable( GL_DEPTH_TEST );
546
547 //     GLint maskTexComponent = 3;
548 //     glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &maskTexComponent);
549
550 //     // The fake env chrome texture
551 //     glActiveTexturePtr( GL_TEXTURE1_ARB );
552 //     glEnable(GL_TEXTURE_2D);
553 //     {
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());
561
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 );
574 //         }
575 //     }
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 ); 
586
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);
590 //     } else {
591 //         // c = chrome tex
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 ); 
595
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);
599 //     }
600 //     // automatic generation of texture coordinates
601 //     // from normals
602
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 );
607
608 //     glCallList ( dlist ) ;
609
610 //     glActiveTexturePtr( GL_TEXTURE1_ARB );
611 //     glDisable( GL_TEXTURE_GEN_S );
612 //     glDisable( GL_TEXTURE_GEN_T );
613
614 //     glMatrixMode(GL_TEXTURE);
615 //         glLoadIdentity();
616 //     glMatrixMode(GL_MODELVIEW);
617
618 //     glDisable(GL_TEXTURE_2D);
619 //     glBindTexture(GL_TEXTURE_2D, 0);
620 //     glActiveTexturePtr( GL_TEXTURE0_ARB );
621
622 //     // restore states
623 //     if( ! my_shader->_depth_test )
624 //         glEnable( GL_DEPTH_TEST );
625
626 //     if( sst )
627 //         sst->force();
628
629 //    // don't draw !
630 //     return false;
631 // }
632
633 // static void init_shaders(void) {
634 //      Shader::Init();
635 //     if( false && Shader::is_VP_supported() ) {
636 //          shFresnel = new Shader("/FlightGear/data/Textures/fresnel_vp.txt", "fresnel_vp");
637 //     }
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;
647 //     }
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 );
656
657 //     sgMakeIdentMat4( shadIdentMatrix );
658
659 //      initDone = true;
660 // }
661
662 // ////////////////////////////////////////////////////////////////////////
663 // // Implementation of SGShaderAnimation
664 // ////////////////////////////////////////////////////////////////////////
665
666 SGShaderAnimation::SGShaderAnimation ( SGPropertyNode *prop_root,
667                    SGPropertyNode_ptr props )
668   : SGAnimation(props, new osg::Group),
669     _condition(0),
670     _condition_value(true),
671     _shader_type(0),
672     _param_1(props->getFloatValue("param", 1.0f)),
673     _depth_test(props->getBoolValue("depth-test", true)),
674     _factor(props->getFloatValue("factor", 1.0f)),
675     _factor_prop(0),
676     _speed(props->getFloatValue("speed", 1.0f)),
677     _speed_prop(0),
678     _textureData(0),
679     _texWidth(0),
680     _texHeight(0)
681
682 {
683     SGPropertyNode_ptr node = props->getChild("condition");
684     if (node != 0) {
685         _condition = sgReadCondition(prop_root, node);
686         _condition_value = false;
687     }
688     node = props->getChild("factor-prop");
689     if( node )
690         _factor_prop = prop_root->getNode(node->getStringValue(), true);
691     node = props->getChild("speed-prop");
692     if( node )
693         _speed_prop = prop_root->getNode(node->getStringValue(), true);
694
695     _envColor = osg::Vec4(0, 0, 0, 1);
696     node = props->getChild("texture");
697     if( node ) {
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);
702
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 );
706     }
707     string shader_name = props->getStringValue("shader");
708     if( shader_name == "fresnel" || shader_name == "reflection" )
709         _shader_type = 1;
710     else if( shader_name == "heat-haze" )
711         _shader_type = 2;
712     else if( shader_name == "chrome" && _effectTexture.valid())
713         _shader_type = 3;
714 }
715
716 void SGShaderAnimation::init()
717 {
718 //     if( ! initDone )
719 //         init_shaders();
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 );
728 //     }
729 //     else if( _shader_type == 3 )
730 //         setCallBack( getBranch(), (ssgBase *) this, chrome_shader_callback );
731 //     else
732 //         setCallBack( getBranch(), (ssgBase *) this, null_shader_callback );
733 }
734
735 SGShaderAnimation::~SGShaderAnimation()
736 {
737   delete _condition;
738   delete _textureData;
739 }
740
741 void
742 SGShaderAnimation::operator()(osg::Node* node, osg::NodeVisitor* nv)
743
744   if (_condition)
745     _condition_value = _condition->test();
746   if( _factor_prop)
747     _factor = _factor_prop->getFloatValue();
748   if( _speed_prop)
749     _speed = _speed_prop->getFloatValue();
750
751   // OSGFIXME fiddle with totalTime
752   totalTime = nv->getFrameStamp()->getReferenceTime();
753
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.
757   traverse(node, nv);
758 }
759 #endif