]> git.mxchange.org Git - simgear.git/blob - simgear/scene/model/shadanim.cxx
- better error message when submodel loading failed
[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 <plib/sg.h>
28 #include <plib/ssg.h>
29 #include <plib/ul.h>
30
31 #include <simgear/props/condition.hxx>
32 #include <simgear/props/props.hxx>
33 #include <simgear/screen/extensions.hxx>
34
35 #include <simgear/debug/logstream.hxx>
36
37 #include <simgear/screen/shader.h>
38
39 #include "animation.hxx"
40 /*
41     <animation>
42         <type>shader</type>
43         <shader>fresnel</shader>
44         <object-name>...</object-name>
45     </animation>
46
47     <animation>
48         <type>shader</type>
49         <shader>heat-haze</shader>
50         <object-name>...</object-name>
51         <speed>...</speed>
52         <speed-prop>...</speed-prop>
53         <factor>...</factor>
54         <factor-prop>...</factor-prop>
55     </animation>
56
57     <animation>
58         <type>shader</type>
59         <shader>chrome</shader>
60         <texture>...</texture>
61         <object-name>...</object-name>
62     </animation>
63
64     <animation>
65         <type>shader</type>
66         <shader></shader>
67         <object-name>...</object-name>
68         <depth-test>false</depth-test>
69     </animation>
70
71 */
72 static Shader *shFresnel=NULL;
73 static GLuint texFresnel = 0;
74
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;
82
83 static glActiveTextureProc glActiveTexturePtr = 0;
84 static double totalTime = 0.0;
85 static sgMat4 shadIdentMatrix;
86
87
88 static int null_shader_callback( ssgEntity *e ) {
89         GLuint dlist = 0;
90     ssgLeaf *leaf = (ssgLeaf *) e;
91 #ifdef _SSG_USE_DLIST
92     dlist = leaf->getDListIndex();
93     if( ! dlist ) {
94         leaf->makeDList();
95         dlist = leaf->getDListIndex();
96     }
97 #endif
98     if( ! dlist )
99         return true;
100     ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
101     if ( sst )
102         sst->apply();
103
104     SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
105     if( ! my_shader->_depth_test )
106         glDisable( GL_DEPTH_TEST );
107     glCallList ( dlist ) ;
108     // restore states
109     if( ! my_shader->_depth_test )
110         glEnable( GL_DEPTH_TEST );
111
112     // don't draw !
113     return false;
114 }
115
116 static int heat_haze_shader_callback( ssgEntity *e ) {
117         GLuint dlist = 0;
118     ssgLeaf *leaf = (ssgLeaf *) e;
119 #ifdef _SSG_USE_DLIST
120     dlist = leaf->getDListIndex();
121     if( ! dlist ) {
122         leaf->makeDList();
123         dlist = leaf->getDListIndex();
124     }
125 #endif
126     if( ! dlist )
127         return true;
128
129     GLint viewport[4];
130     glGetIntegerv( GL_VIEWPORT, viewport );
131     const int screen_width = viewport[2];
132     const int screen_height = viewport[3];
133     if( ! haveBackground ) {
134         // store the backbuffer in a texture
135         if( ! texBackground ) {
136             // allocate our texture here so we don't waste memory if no model use that effect
137             // check if we need a rectangle texture and if the card support it
138             if( (screen_width > 1024 || screen_height > 1024) && isRectangleTextureSupported ) {
139                 // Note that the 3 (same) extensions use the same enumerants
140                 texBackgroundTarget = GL_TEXTURE_RECTANGLE_NV;
141                 istexBackgroundRectangle = true;
142                 texBackgroundWidth = screen_width;
143                 texBackgroundHeight = screen_height;
144             }
145             glGenTextures(1, &texBackground);
146             glEnable(texBackgroundTarget);
147             glBindTexture(texBackgroundTarget, texBackground);
148             // trying to match the backbuffer pixel format
149             GLint internalFormat = GL_RGB8;
150             GLint colorBits = 0, alphaBits = 0;
151             glGetIntegerv( GL_BLUE_BITS, &colorBits );
152             glGetIntegerv( GL_ALPHA_BITS, &alphaBits );
153             if(colorBits == 5) {
154                 if( alphaBits == 0 )
155                     internalFormat = GL_RGB5;
156                 else
157                     internalFormat = GL_RGB5_A1;
158             } else {
159                 if( alphaBits != 0 )
160                     internalFormat = GL_RGBA8;
161             }
162             glTexImage2D(texBackgroundTarget, 0, internalFormat, 
163                             texBackgroundWidth, texBackgroundHeight, 0, GL_RGB, GL_FLOAT, NULL);
164
165             glTexParameteri(texBackgroundTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
166             glTexParameteri(texBackgroundTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
167             glTexParameteri(texBackgroundTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
168             glTexParameteri(texBackgroundTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
169         }
170         glEnable(texBackgroundTarget);
171         glBindTexture(texBackgroundTarget, texBackground);
172         // center of texture = center of screen
173         // obviously we don't have the whole screen if screen_width > texBackgroundWidth
174         // if rectangle textures are not supported, this give some artifacts on the borders
175         if( istexBackgroundRectangle ) {
176             glCopyTexSubImage2D( texBackgroundTarget, 0, 0, 0, 
177                 0, 0, texBackgroundWidth, texBackgroundHeight );
178         } else {
179             glCopyTexSubImage2D( texBackgroundTarget, 0, 0, 0, 
180                 (screen_width - texBackgroundWidth) / 2, 
181                 (screen_height - texBackgroundHeight) / 2, 
182                 texBackgroundWidth, texBackgroundHeight );
183         }
184         haveBackground = true;
185         glBindTexture(texBackgroundTarget, 0);
186         glDisable(texBackgroundTarget);
187     }
188     ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
189     if ( sst )
190         sst->apply();
191
192     SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
193     if( ! my_shader->_depth_test )
194         glDisable( GL_DEPTH_TEST );
195     glDepthMask( GL_FALSE );
196     glDisable( GL_LIGHTING );
197     if(1) {
198         // noise texture, tex coord from the model translated by a time factor
199         glActiveTexturePtr( GL_TEXTURE0_ARB );
200         glEnable(GL_TEXTURE_2D);
201         const float noiseDist = fmod(- totalTime * my_shader->_factor * my_shader->_speed, 4.0);
202         glMatrixMode(GL_TEXTURE);
203             glLoadIdentity();
204             glTranslatef( noiseDist, 0.0f, 0.0f );
205         glMatrixMode(GL_MODELVIEW);
206
207         glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
208
209         // background texture
210         glActiveTexturePtr( GL_TEXTURE1_ARB );
211         glEnable(texBackgroundTarget);
212         glBindTexture(texBackgroundTarget, texBackground);
213
214         // automatic generation of texture coordinates
215         // map to screen space
216         sgMat4 CameraProjM, CameraViewM;
217         glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat *) CameraProjM);
218         glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) CameraViewM);
219         // const float dummy_scale = 1.0f; //0.95f;
220         const float deltaPos = 0.05f;
221         glMatrixMode(GL_TEXTURE);
222             glLoadIdentity();
223             if( istexBackgroundRectangle ) {
224                 // coords go from 0.0 to n, not from 0.0 to 1.0
225                 glTranslatef( texBackgroundWidth * 0.5f, texBackgroundHeight * 0.5f, 0.0f );
226                 glScalef( texBackgroundWidth * 0.5f,
227                     texBackgroundHeight * 0.5f, 1.0f );
228             } else {
229                 glTranslatef( 0.5f, 0.5f, 0.0f );
230                 glScalef( float( screen_width ) / float( texBackgroundWidth ) * 0.5f,
231                     float( screen_height ) / float( texBackgroundHeight ) * 0.5f, 1.0f );
232             }
233             glMultMatrixf( (GLfloat *) CameraProjM );
234             glMultMatrixf( (GLfloat *) CameraViewM );
235             glTranslatef( deltaPos, deltaPos, deltaPos );
236         glMatrixMode(GL_MODELVIEW);
237
238         glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
239         glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
240         glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
241         glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
242         glTexGenfv( GL_S, GL_EYE_PLANE, shadIdentMatrix[0] );
243         glTexGenfv( GL_T, GL_EYE_PLANE, shadIdentMatrix[1] );
244         glTexGenfv( GL_R, GL_EYE_PLANE, shadIdentMatrix[2] );
245         glTexGenfv( GL_Q, GL_EYE_PLANE, shadIdentMatrix[3] );
246         glEnable( GL_TEXTURE_GEN_S );
247         glEnable( GL_TEXTURE_GEN_T );
248         glEnable( GL_TEXTURE_GEN_R );
249         glEnable( GL_TEXTURE_GEN_Q );
250
251         sgVec4 enviro = {1.00f, 1.00f, 1.00f, 0.85f};
252
253         glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
254         glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE ); 
255         glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
256         glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); 
257         glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT_ARB );
258         glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); 
259                 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, enviro);
260
261         glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
262         glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE0_ARB);
263         glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
264         glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB );
265         glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA ); 
266
267         glCallList ( dlist ) ;
268         glMatrixMode(GL_TEXTURE);
269         glTranslatef( - deltaPos*2.0f, -deltaPos*2.5f, -deltaPos*2.0f );
270         glMatrixMode(GL_MODELVIEW);
271         glCallList ( dlist ) ;
272
273         // alter colors only on last rendering
274         // sgVec4 fLight = {0.93f, 0.93f, 1.00f, 0.85f};
275         glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB );
276         glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); 
277
278         glMatrixMode(GL_TEXTURE);
279         glTranslatef( deltaPos*0.7f, deltaPos*1.7f, deltaPos*0.7f );
280         glMatrixMode(GL_MODELVIEW);
281         glCallList ( dlist ) ;
282
283
284         glActiveTexturePtr( GL_TEXTURE1_ARB );
285         glDisable( GL_TEXTURE_GEN_S );
286         glDisable( GL_TEXTURE_GEN_T );
287         glDisable( GL_TEXTURE_GEN_R );
288         glDisable( GL_TEXTURE_GEN_Q );
289         glMatrixMode(GL_TEXTURE);
290             glLoadIdentity();
291         glMatrixMode(GL_MODELVIEW);
292         glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
293         glDisable(texBackgroundTarget);
294         glActiveTexturePtr( GL_TEXTURE0_ARB );
295         glMatrixMode(GL_TEXTURE);
296             glLoadIdentity();
297         glMatrixMode(GL_MODELVIEW);
298         glEnable(GL_TEXTURE_2D);
299         glBindTexture(GL_TEXTURE_2D, 0);
300     }
301     // restore states
302     if( ! my_shader->_depth_test )
303         glEnable( GL_DEPTH_TEST );
304
305     glEnable( GL_LIGHTING );
306     glDepthMask( GL_TRUE );
307     if( sst )
308         sst->force();
309
310    // don't draw !
311     return false;
312 }
313
314 static int fresnel_shader_callback( ssgEntity *e ) {
315         GLuint dlist = 0;
316     ssgLeaf *leaf = (ssgLeaf *) e;
317 #ifdef _SSG_USE_DLIST
318     dlist = leaf->getDListIndex();
319     if( ! dlist ) {
320         leaf->makeDList();
321         dlist = leaf->getDListIndex();
322     }
323 #endif
324     if( ! dlist )
325         return true;
326     ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
327     if ( sst )
328         sst->apply();
329
330     sgVec4 sunColor, ambientColor;
331     ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor );
332     ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor );
333
334     // SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
335     glEnable(GL_BLEND);
336         glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
337         glEnable(GL_ALPHA_TEST);
338         glAlphaFunc(GL_GREATER, 0.0f);
339
340         if( true ) {
341 //        sgVec4 R = {0.5,0.0,0.0,0.0};
342         sgVec4 enviro = {1.0,0.0,0.0,1.0};
343 //        sgCopyVec4( enviro, sunColor );
344         glActiveTexturePtr( GL_TEXTURE0_ARB );
345         glEnable(GL_TEXTURE_2D);
346         glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
347         glActiveTexturePtr( GL_TEXTURE1_ARB );
348         glDisable(GL_TEXTURE_2D);
349         glEnable(GL_TEXTURE_1D);
350         glBindTexture(GL_TEXTURE_1D, texFresnel);
351         // c = a0 * a2 + a1 * (1-a2)
352 //        glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
353 //        glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
354         glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
355         glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB ); 
356         glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_CONSTANT_ARB );
357         glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); 
358         glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB );
359         glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); 
360         glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE );
361         glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR ); 
362                 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, enviro);
363         shFresnel->enable();
364             shFresnel->bind();
365             glCallList ( dlist ) ;
366         shFresnel->disable();
367         glActiveTexturePtr( GL_TEXTURE1_ARB );
368         glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
369         glDisable(GL_TEXTURE_1D);
370         glActiveTexturePtr( GL_TEXTURE0_ARB );
371         glDisable(GL_TEXTURE_1D);
372         glEnable(GL_TEXTURE_2D);
373     }
374     // restore states
375 //    glBindTexture(GL_TEXTURE_2D, 0);
376 //    glDepthFunc(GL_LESS);
377 //    glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
378    if( sst )
379             sst->force();
380
381     // don't draw !
382     return false;
383 }
384
385
386
387 static int chrome_shader_callback( ssgEntity *e ) {
388         GLuint dlist = 0;
389     ssgLeaf *leaf = (ssgLeaf *) e;
390 #ifdef _SSG_USE_DLIST
391     dlist = leaf->getDListIndex();
392     if( ! dlist ) {
393         leaf->makeDList();
394         dlist = leaf->getDListIndex();
395     }
396 #endif
397     if( ! dlist )
398         return true;
399     ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState());
400     if ( sst )
401         sst->apply();
402
403     SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() );
404     if( ! my_shader->_depth_test )
405         glDisable( GL_DEPTH_TEST );
406
407     GLint maskTexComponent = 3;
408     glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &maskTexComponent);
409
410     // The fake env chrome texture
411     glActiveTexturePtr( GL_TEXTURE1_ARB );
412     glEnable(GL_TEXTURE_2D);
413     {
414         // No lighting is computed in spherical mapping mode because the environment
415         // is supposed to be allready lighted. We must reshade our environment texture.
416         sgVec4 sunColor, ambientColor, envColor;
417         ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor );
418         ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor );
419         sgAddScaledVec3( envColor, ambientColor, sunColor, 0.4f);
420         glBindTexture(GL_TEXTURE_2D, my_shader->_effectTexture->getHandle());
421
422         sgVec3 delta_light;
423         sgSubVec3(delta_light, envColor, my_shader->_envColor);
424         if( (fabs(delta_light[0]) + fabs(delta_light[1]) + fabs(delta_light[2])) > 0.05f ) {
425                     sgCopyVec3( my_shader->_envColor, envColor );
426             // reload the texture data and let the driver reshade it for us
427             glPixelTransferf( GL_RED_SCALE, envColor[0] );
428             glPixelTransferf( GL_GREEN_SCALE, envColor[1] );
429             glPixelTransferf( GL_BLUE_SCALE, envColor[2] );
430             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, my_shader->_texWidth, my_shader->_texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, my_shader->_textureData);
431             glPixelTransferf( GL_RED_SCALE, 1.0f );
432             glPixelTransferf( GL_GREEN_SCALE, 1.0f );
433             glPixelTransferf( GL_BLUE_SCALE, 1.0f );
434         }
435     }
436     if( maskTexComponent == 4 ) {
437         // c = lerp(model tex, chrome tex, model tex alpha)
438         glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
439         glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB ); 
440         glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB );
441         glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); 
442         glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE );
443         glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); 
444         glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PREVIOUS_ARB );
445         glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA ); 
446
447         glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
448         glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
449         glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
450     } else {
451         // c = chrome tex
452         glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
453         glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
454         glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); 
455
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);
459     }
460     // automatic generation of texture coordinates
461     // from normals
462
463     glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
464     glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
465     glEnable( GL_TEXTURE_GEN_S );
466     glEnable( GL_TEXTURE_GEN_T );
467
468     glCallList ( dlist ) ;
469
470     glActiveTexturePtr( GL_TEXTURE1_ARB );
471     glDisable( GL_TEXTURE_GEN_S );
472     glDisable( GL_TEXTURE_GEN_T );
473
474     glMatrixMode(GL_TEXTURE);
475         glLoadIdentity();
476     glMatrixMode(GL_MODELVIEW);
477
478     glDisable(GL_TEXTURE_2D);
479     glBindTexture(GL_TEXTURE_2D, 0);
480     glActiveTexturePtr( GL_TEXTURE0_ARB );
481
482     // restore states
483     if( ! my_shader->_depth_test )
484         glEnable( GL_DEPTH_TEST );
485
486     if( sst )
487         sst->force();
488
489    // don't draw !
490     return false;
491 }
492
493 static void init_shaders(void) {
494         Shader::Init();
495     if( false && Shader::is_VP_supported() ) {
496             shFresnel = new Shader("/FlightGear/data/Textures/fresnel_vp.txt", "fresnel_vp");
497 //        shFresnel->bindNames("somedata", 0);
498     }
499         glActiveTexturePtr = (glActiveTextureProc) SGLookupFunction("glActiveTextureARB");
500     const int fresnelSize = 512;
501     unsigned char imageFresnel[ fresnelSize * 3 ];
502     for(int i = 0; i < fresnelSize; i++) {
503         const float R0 = 0.2f;
504         float NdotV = float( i ) / float( fresnelSize );
505         float f = R0 + (1.0f-R0)*pow(1.0f - NdotV, 5);
506         unsigned char ff = (unsigned char) (f * 255.0);
507         imageFresnel[i*3+0] = imageFresnel[i*3+1] = imageFresnel[i*3+2] = ff;
508     }
509     glGenTextures( 1, &texFresnel );
510         glBindTexture(GL_TEXTURE_1D, texFresnel );
511         glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
512     glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
513     glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
514         glTexParameteri(GL_TEXTURE_1D, GL_GENERATE_MIPMAP_SGIS, true);
515         glTexImage1D(GL_TEXTURE_1D, 0, 3, fresnelSize, 0, GL_RGB, GL_UNSIGNED_BYTE, imageFresnel);
516         glBindTexture(GL_TEXTURE_1D, 0 );
517
518     sgMakeIdentMat4( shadIdentMatrix );
519
520         initDone = true;
521 }
522
523 ////////////////////////////////////////////////////////////////////////
524 // Implementation of SGShaderAnimation
525 ////////////////////////////////////////////////////////////////////////
526
527 SGShaderAnimation::SGShaderAnimation ( SGPropertyNode *prop_root,
528                    SGPropertyNode_ptr props )
529   : SGAnimation(props, new ssgBranch),
530     _condition(0),
531     _condition_value(true),
532     _shader_type(0),
533     _param_1(props->getFloatValue("param", 1.0f)),
534     _depth_test(props->getBoolValue("depth-test", true)),
535     _factor(props->getFloatValue("factor", 1.0f)),
536     _factor_prop(0),
537     _speed(props->getFloatValue("speed", 1.0f)),
538     _speed_prop(0),
539     _effectTexture(0),
540     _textureData(0),
541     _texWidth(0),
542     _texHeight(0)
543
544 {
545     SGPropertyNode_ptr node = props->getChild("condition");
546     if (node != 0) {
547         _condition = sgReadCondition(prop_root, node);
548         _condition_value = false;
549     }
550     node = props->getChild("factor-prop");
551     if( node )
552         _factor_prop = prop_root->getNode(node->getStringValue(), true);
553     node = props->getChild("speed-prop");
554     if( node )
555         _speed_prop = prop_root->getNode(node->getStringValue(), true);
556
557     sgSetVec4(_envColor, 0.0f, 0.0f, 0.0f, 1.0f);
558     node = props->getChild("texture");
559     if( node ) {
560         _effectTexture = ssgGetCurrentOptions()->createTexture( (char *) node->getStringValue(), 0, 0, 0);
561         glBindTexture(GL_TEXTURE_2D, _effectTexture->getHandle() );
562         glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &_texWidth);
563         glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &_texHeight);
564
565         _textureData = new unsigned char[_texWidth * _texHeight * 3];
566         glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, _textureData);
567         glBindTexture(GL_TEXTURE_2D, 0 );
568     }
569     string shader_name = props->getStringValue("shader");
570     if( shader_name == "fresnel" || shader_name == "reflection" )
571         _shader_type = 1;
572     else if( shader_name == "heat-haze" )
573         _shader_type = 2;
574     else if( shader_name == "chrome" && _effectTexture)
575         _shader_type = 3;
576 }
577
578 static void setCallBack(ssgBranch *branch, ssgBase *user_data, ssgCallback cb) {
579     for (int i = 0; i < branch->getNumKids(); i++) {
580         ssgEntity *e = branch->getKid(i);
581         if( e->isAKindOf( ssgTypeBranch() ) )
582             setCallBack( (ssgBranch *) e, user_data, cb);
583         else if( e->isAKindOf( ssgTypeVtxTable() ) ) {
584                 e->setCallback( SSG_CALLBACK_PREDRAW, cb );
585             e->setUserData( user_data );
586         }
587     }
588 }
589
590 void SGShaderAnimation::init()
591 {
592     if( ! initDone )
593         init_shaders();
594     if( _shader_type == 1 && Shader::is_VP_supported() && shFresnel)
595         setCallBack( getBranch(), (ssgBase *) this, fresnel_shader_callback );
596     else if( _shader_type == 2 ) {
597         // this is the same extension with different names
598         isRectangleTextureSupported = SGIsOpenGLExtensionSupported("GL_EXT_texture_rectangle") ||
599             SGIsOpenGLExtensionSupported("GL_ARB_texture_rectangle") ||
600             SGIsOpenGLExtensionSupported("GL_NV_texture_rectangle");
601         setCallBack( getBranch(), (ssgBase *) this, heat_haze_shader_callback );
602     }
603     else if( _shader_type == 3 )
604         setCallBack( getBranch(), (ssgBase *) this, chrome_shader_callback );
605     else
606         setCallBack( getBranch(), (ssgBase *) this, null_shader_callback );
607 }
608
609 SGShaderAnimation::~SGShaderAnimation()
610 {
611     delete _condition;
612     delete _effectTexture;
613     delete _textureData;
614 }
615
616 int
617 SGShaderAnimation::update()
618 {
619     if (_condition)
620         _condition_value = _condition->test();
621     if( _factor_prop)
622         _factor = _factor_prop->getFloatValue();
623     if( _speed_prop)
624         _speed = _speed_prop->getFloatValue();
625     return 2;
626 }
627
628 void sgShaderFrameInit(double delta_time_sec) {
629     haveBackground = false;
630     totalTime += delta_time_sec;
631 }