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