rendergl1.c

Go to the documentation of this file.
00001 // File rendergl1.c
00002 
00003 #define MODULE_RENDERGL1
00004 
00005 #include "render.h"
00006 #include "..\shaders\shaders.h"
00007 #include "..\gl2.h"
00008 
00009 // These are still under investigation 
00010 //#define  NEAR_CLIP_PLANE    1.0 // minimum possible - may not give good scale
00011 #define  NEAR_CLIP_PLANE    1.0  // best working hypothesis so far
00012 //#define  NEAR_CLIP_PLANE    75.0 // seems good on a distance scale but may be too far aways
00013 #define  FAR_CLIP_PLANE   500.0  // Scale so that ALL objects inside this distance
00014 //#define  GROUND_RECTS        40  
00015 #define  GROUND_RECTS       120  
00016 
00017 //#define  ANGL_FOV 46.0  // Original settings - too wide
00018 #define  ANGL_FOV 35.3    // should give the same Ar as software renderr
00019 
00020 extern double DepthScalingGL,FrontDepthGL,BackDepthGL;
00021 extern char gszHomeDir[];
00022 extern GLint DlistID;
00023 extern int TEXTUREBUFFER_WIDTH;
00024 extern int TEXTUREBUFFER_HEIGHT;
00025 extern GLuint g_check_texture;
00026 extern GLuint g_map_texture;
00027 extern GLuint g_ref_texture;  
00028 extern GLuint g_bump_texture;
00029 extern GLuint g_tran_texture;
00030 extern GLuint g_movie_texture;
00031 extern GLuint g_env_texture;
00032 extern GLuint g_envB_texture;
00033 extern GLuint g_envN_texture;
00034 extern GLuint g_noise_texture;
00035 extern GLuint g_env3D_texture;
00036 extern GLuint g_sky_texture;
00037 
00038 double GlobalScale;
00039 
00040 static void Draw3dScene(GLfloat);
00041 static void Draw3dObjects(int pass, BOOL clip);
00042 static void DrawPlain3dObjects(void);
00043 static void DrawSky(GLfloat);
00044 static void DrawGround(BOOL,GLfloat);
00045 static void DrawGroundShadow(void);
00046 static void DrawGroundReflection(GLfloat);
00047 static void PositionLights(void);
00048 static void CancelLights(void);
00049 static BOOL IsaNoise(int i);
00050 static void DrawMaterialPolys(BOOL, BOOL,long, matl *, long, face *, long, vertex *);
00051 static void DrawMappedPolys(BOOL,BOOL,long, matl*, long, imap *, long, face *, long, vertex *);
00052 static void TextureWithAlpha(long x, long y, unsigned char *R, unsigned char *G, unsigned char *B, 
00053                       unsigned char alpha, BOOL bDecal,
00054                       unsigned char r, unsigned char g, unsigned char b);
00055 static void Texture(long x, long y, unsigned char *R, unsigned char *G, unsigned char *B);
00056 static void InstallShadowMatrix(GLfloat [4], GLfloat [4]);
00057 static void InstallReflectionMatrix(GLfloat p0[3], GLfloat n[3]);
00058 
00059 
00060 typedef struct{
00061         GLfloat x, y;
00062 } jitter_point;
00063 
00064 static jitter_point jj2[] = {
00065 {0.25, 0.75}, {0.75, 0.25}
00066 }; 
00067 static jitter_point jj3[] = {
00068 {0.5033922635, 0.8317967229}, {0.7806016275, 0.2504380877},
00069 {0.2261828938, 0.4131553612}
00070 };
00071 static jitter_point jj4[] = {
00072 {0.375, 0.25}, {0.125, 0.75}, {0.875, 0.25}, {0.625, 0.75}
00073 };
00074 static jitter_point jj5[] = {
00075 {0.5, 0.5}, {0.3, 0.1}, {0.7, 0.9}, {0.9, 0.3}, {0.1, 0.7}
00076 };
00077 static jitter_point jj6[] = {
00078 {0.4646464646, 0.4646464646}, {0.1313131313, 0.7979797979},
00079 {0.5353535353, 0.8686868686}, {0.8686868686, 0.5353535353},
00080 {0.7979797979, 0.1313131313}, {0.2020202020, 0.2020202020}
00081 };
00082 static jitter_point jj8[] = {
00083 {0.5625, 0.4375}, {0.0625, 0.9375}, {0.3125, 0.6875}, {0.6875, 0.8125},
00084 {0.8125, 0.1875}, {0.9375, 0.5625}, {0.4375, 0.0625}, {0.1875, 0.3125}
00085 };
00086 static jitter_point jj9[] = {
00087 {0.5, 0.5}, {0.1666666666, 0.9444444444}, {0.5, 0.1666666666},
00088 {0.5, 0.8333333333}, {0.1666666666, 0.2777777777},
00089 {0.8333333333, 0.3888888888}, {0.1666666666, 0.6111111111},
00090 {0.8333333333, 0.7222222222}, {0.8333333333, 0.0555555555}
00091 };
00092 static jitter_point jj12[] = {
00093 {0.4166666666, 0.625}, {0.9166666666, 0.875}, {0.25, 0.375},
00094 {0.4166666666, 0.125}, {0.75, 0.125}, {0.0833333333, 0.125}, {0.75, 0.625},
00095 {0.25, 0.875}, {0.5833333333, 0.375}, {0.9166666666, 0.375},
00096 {0.0833333333, 0.625}, {0.583333333, 0.875}
00097 };
00098 static jitter_point jj16[] = {
00099 {0.375, 0.4375}, {0.625, 0.0625}, {0.875, 0.1875}, {0.125, 0.0625},
00100 {0.375, 0.6875}, {0.875, 0.4375}, {0.625, 0.5625}, {0.375, 0.9375},
00101 {0.625, 0.3125}, {0.125, 0.5625}, {0.125, 0.8125}, {0.375, 0.1875},
00102 {0.875, 0.9375}, {0.875, 0.6875}, {0.125, 0.3125}, {0.625, 0.8125}
00103 };
00104 static jitter_point *jjp[]={0,0,jj2,jj3,jj4,jj5,jj6,0,jj8,jj9,0,0,jj12,0,0,0,jj16};
00105 
00106 
00107 void RenderCameraView(BOOL renderbuffer,BOOL bAntiAliased,int jitter, int aa, GLfloat asp){ // render into the current colour buffer
00108  double dx,dy,dz,maxd;                                                       // with AA if required and using a
00109  dx=(double)(ClipXmax-ClipXmin); // this scaling still needs work            //  Display List when AA 
00110  dy=(double)(ClipYmax-ClipYmin);
00111  dz=(double)(ClipZmax-ClipZmin);
00112  maxd=max(dy,dz);
00113  maxd=max(dx,maxd);
00114  GlobalScale=(FAR_CLIP_PLANE)/maxd;
00115  DepthScalingGL=GlobalScale;
00116  FrontDepthGL=NEAR_CLIP_PLANE;
00117  if(R_Nground == 0)BackDepthGL=FAR_CLIP_PLANE*2.0;
00118  else              BackDepthGL=FAR_CLIP_PLANE*5.0;
00119  //if(debug != NULL && jitter == 0)fprintf(debug,"GLrender: GlobalScale=%lf maxd=%lf FCP=%lf RCP=%lf\n",GlobalScale,maxd,FrontDepthGL,BackDepthGL);
00120  if(bAntiAliased && jitter == 0){ 
00121    //if(debug != NULL)fprintf(debug,"Building Display list TXBUFFER SIZE [%ld %ld]\n",TEXTUREBUFFER_WIDTH,TEXTUREBUFFER_HEIGHT);
00122    glNewList(1,GL_COMPILE);
00123    Draw3dScene(asp);
00124    glEndList();
00125    DlistID=1;
00126  } 
00127  glMatrixMode( GL_PROJECTION );
00128  glLoadIdentity();
00129  if(bAntiAliased){
00130    accPerspective(ANGL_FOV/CamSx,asp,FrontDepthGL,BackDepthGL,
00131                     jjp[aa][jitter].x-0.5,jjp[aa][jitter].y-0.5,0.0,0.0,1.0);
00132    //if(debug != NULL)fprintf(debug,"Rendering AA sample %ld of %ld at (%lf,%lf)\n",jitter,aa,jjp[aa][jitter].x-0.5,jjp[aa][jitter].y-0.5);
00133  }
00134  else{
00135    gluPerspective(ANGL_FOV/CamSx,asp,FrontDepthGL,BackDepthGL);
00136  }
00137  glViewport( 0, 0, TEXTUREBUFFER_WIDTH, TEXTUREBUFFER_HEIGHT );
00138  glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
00139  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00140  glMatrixMode( GL_MODELVIEW );
00141  glLoadIdentity();
00142  if(DlistID > 0){
00143    //if(debug != NULL)fprintf(debug,"Running Display List\n");
00144    glCallList(DlistID);
00145  }
00146  else Draw3dScene(asp);
00147 }
00148 
00149 static void Draw3dScene(GLfloat asp){
00150  GLdouble GroundClip[4];
00151  GLfloat color[4]={0.0,0.0,0.0,0.5};
00152  //if(debug != NULL)fprintf(debug,"Drawing Scene\n");
00153  if(Nsky > 0)DrawSky(asp);
00154  if(R_Nground > 0){ // render the ground and its shadows and reflection
00155    glEnable(GL_STENCIL_TEST);
00156    glClear(GL_STENCIL_BUFFER_BIT);
00157    glStencilFunc(GL_ALWAYS,1,0xFFFFFFFF);
00158    glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);
00159    glDepthMask(GL_FALSE);
00160    glColor4ub(0,0,0,0);
00161    DrawGround(FALSE,1.0);
00162    glDepthMask(GL_TRUE);
00163    //Ground.refl=0.50;  // 50 %
00164    if(Ground.refl > 0.01){  // Render the Ground reflection
00165      glStencilFunc(GL_NOTEQUAL,0,0xFFFFFFFF);
00166      glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
00167      DrawGroundReflection(asp);
00168      glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
00169      glEnable(GL_BLEND);   // darken the reflection 
00170      glColor4ub(0,0,0,(unsigned char)((1.0-Ground.refl)*255.0)); 
00171      DrawGround(FALSE,1.0);
00172    }
00173    PositionLights();
00174    glDepthMask(GL_FALSE);
00175    glEnable(GL_LIGHTING);
00176    DrawGround(TRUE,1.0-Ground.refl);  // draw the ground in with the appropriate degree of blending if relective
00177    glFlush();
00178    glDisable(GL_LIGHTING);
00179    CancelLights();
00180    glDepthMask(GL_TRUE);
00181    if(Ground.refl > 0.01)glDisable(GL_BLEND);
00182    glStencilFunc(GL_EQUAL,1,0xFFFFFFFF);
00183    glStencilOp(GL_KEEP,GL_KEEP,GL_INCR);
00184    if(Nlights > 0 && Lights > 0)DrawGroundShadow();
00185    glDisable(GL_STENCIL_TEST);
00186    GroundClip[0]=-Ground.n[0]; GroundClip[1]=-Ground.n[2]; GroundClip[2]=Ground.n[1]; // clip everything below the ground
00187    GroundClip[3]=DOT(Ground.n,Ground.p)*GlobalScale; 
00188    // NOTE ATI/NVIDIA differences - this may requre us to build in our own clipping mechanism
00189    // GLSL in ATI automatically puts in the clipping planes nVidia does not. On nVidia gl_ClipVertex needs
00190    // to be set on VS but on ATI this causes a problem with the colour of ftagments. To allow our shaders to run on
00191    // both hardware we use our own clipping mechanism in the fragment shaders. Thus if the ground plane is in use
00192    // we clip using access to the clipping planes. so the enable below is redundant, but we cannot include it as it
00193    // seems to upset the reflection with it is clipped (ODD).
00194    //glEnable(GL_CLIP_PLANE0);  // done in ftag shader
00195    glClipPlane(GL_CLIP_PLANE0,GroundClip);
00196  }
00197  PositionLights();
00198  glEnable(GL_LIGHTING);
00199  Draw3dObjects(1,(R_Nground > 0 ? TRUE: FALSE));
00200  glDisable(GL_LIGHTING);
00201  CancelLights();
00202  if(Nparticles > 0)RenderParticlesGL((R_Nground > 0 ? TRUE: FALSE)); // particles will be AA
00203  //if(R_Nground > 0)glDisable(GL_CLIP_PLANE0); // done in frag shader
00204  glFlush();
00205 }
00206 
00207 static void DrawGround(BOOL bDrawAll, GLfloat NonRefFract){
00208  int i,j,progID=6;
00209  GLfloat x,y,z,tangent[3];
00210  if(bDrawAll){
00211    glNormal3f(-Ground.n[0],-Ground.n[2],Ground.n[1]);
00212    UseShaderProgram(progID); 
00213    if(Ground.shiny)SetUniformVariable(1,"SpecularContribution",1.0);  
00214    else            SetUniformVariable(1,"SpecularContribution",0.0);
00215    SetUniformVariable(progID,"GroundHeight",Ground.height);  // effect scaling value default 1.0 but could be more or less
00216    VECCOPY(GlobalScale*Ground.dx,tangent)
00217    SetUniformVector(progID,"Tangent",tangent[0],-tangent[2],tangent[1]);
00218    SetUniformVariable(progID,"NonRefFract",NonRefFract);
00219    if(Ground.mapped && Ground.map.bLoadedS && Ground.map.p24R != NULL){
00220      if(Ground.maptype == TILE)SetUniformInteger(4,"bTiled",1);
00221      else                      SetUniformInteger(4,"bTiled",0);
00222      SetUniformInteger(progID,"bShaded",1);
00223      //SetUniformInteger(progID,"bDecal",0); // NOT on Ground
00224      glActiveTexture(GL_TEXTURE0);  // Surface Map
00225      glBindTexture(GL_TEXTURE_2D,g_map_texture);
00226      Texture(Ground.map.xmax,Ground.map.ymax,Ground.map.p24R,Ground.map.p24G,Ground.map.p24B);
00227      if(Ground.map.moziac){
00228        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT);
00229        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT);
00230      }
00231      else{
00232        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00233        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00234      }
00235      SetUniformInteger(progID,"SurfaceMap",0);
00236      SetUniformInteger(progID,"bS",100);
00237    }
00238    else if(Ground.type == TEXTU){ // textured 
00239      SetUniformVector(progID,"MaterialC",(GLfloat)Ground.acolor[0]/255.0,
00240                                          (GLfloat)Ground.acolor[1]/255.0,
00241                                          (GLfloat)Ground.acolor[2]/255.0);
00242      SetUniformInteger(progID,"bS",(int)Ground.texture);
00243      if(Ground.texture < 4 || Ground.texture == 10){ // need bump map
00244        glActiveTexture(GL_TEXTURE0); 
00245        glBindTexture(GL_TEXTURE_2D,g_envB_texture);
00246        SetUniformInteger(progID,"NormalMap",0);
00247      }
00248    }
00249    else SetUniformInteger(progID,"bS",0);
00250 
00251    glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
00252    glEnable(GL_COLOR_MATERIAL);
00253    glColor4ub(Ground.color[0],Ground.color[1],Ground.color[2],255);
00254  }
00255  glBegin(GL_QUADS);
00256  for(i=-GROUND_RECTS/2;i<GROUND_RECTS/2+1;i++)
00257  for(j=-GROUND_RECTS/2;j<GROUND_RECTS/2+1;j++){
00258    x=(GLfloat)(Ground.p[0] + i*Ground.dx[0] + j*Ground.dy[0])*GlobalScale;
00259    y=(GLfloat)(Ground.p[1] + i*Ground.dx[1] + j*Ground.dy[1])*GlobalScale;
00260    z=(GLfloat)(Ground.p[2] + i*Ground.dx[2] + j*Ground.dy[2])*GlobalScale;
00261    glTexCoord2f((GLfloat)i,(GLfloat)j);
00262    glVertex3f(x,z,-y);
00263    x=x+(GLfloat)Ground.dx[0]*GlobalScale;
00264    y=y+(GLfloat)Ground.dx[1]*GlobalScale;
00265    z=z+(GLfloat)Ground.dx[2]*GlobalScale;
00266    glTexCoord2f((GLfloat)i+1.0,(GLfloat)j);
00267    glVertex3f(x,z,-y);
00268    x=x+(GLfloat)Ground.dy[0]*GlobalScale;
00269    y=y+(GLfloat)Ground.dy[1]*GlobalScale;
00270    z=z+(GLfloat)Ground.dy[2]*GlobalScale;
00271    glTexCoord2f((GLfloat)i+1.0,(GLfloat)j+1.0);
00272    glVertex3f(x,z,-y);
00273    x=x-(GLfloat)Ground.dx[0]*GlobalScale;
00274    y=y-(GLfloat)Ground.dx[1]*GlobalScale;
00275    z=z-(GLfloat)Ground.dx[2]*GlobalScale;
00276    glTexCoord2f((GLfloat)i,(GLfloat)j+1.0);
00277    glVertex3f(x,z,-y);
00278  }
00279  glEnd();
00280  if(bDrawAll){
00281    if(Ground.mapped && Ground.map.bLoadedS && Ground.map.p24R != NULL){
00282      glBindTexture(GL_TEXTURE_2D,0);  
00283    }
00284    else if(Ground.type == TEXTU){ 
00285      if(Ground.texture < 4 || Ground.texture == 10){ 
00286        glBindTexture(GL_TEXTURE_2D,0);  
00287      }
00288    }
00289    glDisable(GL_COLOR_MATERIAL); 
00290    UseShaderProgram(0); 
00291  }
00292 }
00293 
00294 static void DrawGroundReflection(GLfloat asp){
00295  GLdouble GroundClip[4];
00296  GLfloat n[3],p[3];
00297  n[0] = -Ground.n[0]; n[1] = -Ground.n[2]; n[2] = Ground.n[1];
00298  p[0] = Ground.p[0]*GlobalScale; p[1] = Ground.p[2]*GlobalScale; p[2] = -Ground.p[1]*GlobalScale; 
00299  GroundClip[0]=-n[0]; GroundClip[1]=-n[1]; GroundClip[2]=-n[2]; // clip away everything above ground
00300  GroundClip[3]=-DOT(Ground.n,Ground.p)*GlobalScale; 
00301 // glEnable(GL_CLIP_PLANE0); // Done in Shader
00302  glClipPlane(GL_CLIP_PLANE0,GroundClip);
00303  glPushMatrix();
00304  InstallReflectionMatrix(p,n);
00305  if(Nsky > 0)DrawSky(asp);  
00306  PositionLights();
00307  glEnable(GL_LIGHTING);
00308  Draw3dObjects(1,TRUE); 
00309  glDisable(GL_LIGHTING);
00310  glPopMatrix();
00311 // glDisable(GL_CLIP_PLANE0); // Done in Frag Shader
00312 }
00313 
00314 static void DrawGroundShadow(void){  // Only the first light
00315  int i;
00316  GLfloat n[4]; // plane equation
00317  GLfloat p[4]; // position of light
00318  p[0] =  Lights[0].p[0]*GlobalScale; 
00319  p[1] =  Lights[0].p[2]*GlobalScale; 
00320  p[2] = -Lights[0].p[1]*GlobalScale; 
00321 // glLightfv(GL_LIGHT0,GL_POSITION,p);
00322  p[3] = 1.0; // position of light //  p[3]=0.0; // for directional light source
00323  n[0] = -Ground.n[0]; n[1] = -Ground.n[2]; n[2] = Ground.n[1];  // so that it points UP from ground
00324  n[3]=  DOT(Ground.n,Ground.p)*GlobalScale; // +ve sign because ground normal has been reversed
00325  glDisable(GL_DEPTH_TEST);
00326  glDepthMask(GL_FALSE); 
00327  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
00328  glEnable(GL_BLEND);
00329  glPushMatrix();
00330  InstallShadowMatrix(n,p);
00331  glColor4ub(0,0,0,64);  // fraction of shadow
00332  DrawPlain3dObjects();
00333  glPopMatrix();
00334  glDisable(GL_BLEND);
00335  glDepthMask(GL_TRUE);  
00336  glEnable(GL_DEPTH_TEST); 
00337 }
00338 
00339 static void PositionLights(void){  // Only 1 light at present
00340  int i,j;
00341  GLfloat d[]={1.0,1.0,1.0,1.0};
00342  GLfloat a[]={0.1,0.1,0.1,1.0};
00343  GLfloat s[]={1.0,1.0,1.0,1.0};
00344  GLenum lightID[8]={GL_LIGHT0,GL_LIGHT1,GL_LIGHT2,GL_LIGHT3,GL_LIGHT4,GL_LIGHT5,GL_LIGHT6,GL_LIGHT7};
00345  GLfloat p[4]; p[3] = 1.0; // position of light
00346  if(Nlights > 0 && Lights != NULL){
00347    for(i=0;i<min(Nlights,8);i++){
00348      glEnable(lightID[i]);
00349      for(j=0;j<3;j++)d[j]=((GLfloat)Lights[i].color[j])/255.0;
00350      glLightfv(lightID[i],GL_DIFFUSE,d);
00351      glLightfv(lightID[i],GL_AMBIENT,a);
00352      glLightfv(lightID[i],GL_SPECULAR,s);
00353      // set up any attenuation
00354      //glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.15);
00355      //glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.05);
00356      p[0] =  Lights[i].p[0]*GlobalScale; 
00357      p[1] =  Lights[i].p[2]*GlobalScale; 
00358      p[2] = -Lights[i].p[1]*GlobalScale; 
00359      glLightfv(lightID[i],GL_POSITION,p);
00360      if(Lights[i].type == SPOTLIGHT){
00361         GLfloat dirl[3];
00362         dirl[0] = -Lights[i].d[0], // our light structure, i.e. Light's "d" points in opposite direction.
00363         dirl[1] = -Lights[i].d[2], 
00364         dirl[2] =  Lights[i].d[1];
00365         glLightfv(lightID[i],GL_SPOT_DIRECTION,dirl);
00366         glLightf(lightID[i],GL_SPOT_CUTOFF,Lights[i].cone2*180.0/PI);
00367         glLightf(lightID[i],GL_SPOT_EXPONENT,1.0);
00368      }
00369    }
00370  }
00371  else{
00372    glEnable(GL_LIGHT0);
00373    glLightfv(GL_LIGHT0,GL_DIFFUSE,d);
00374    glLightfv(GL_LIGHT0,GL_AMBIENT,a);
00375    glLightfv(GL_LIGHT0,GL_SPECULAR,s);
00376  }
00377 }
00378 
00379 static void CancelLights(void){
00380  int i;
00381  GLenum lightID[8]={GL_LIGHT0,GL_LIGHT1,GL_LIGHT2,GL_LIGHT3,GL_LIGHT4,GL_LIGHT5,GL_LIGHT6,GL_LIGHT7};
00382  if(Nlights > 0 && Lights != NULL){
00383    for(i=0;i<min(Nlights,8);i++)glDisable(lightID[i]);
00384  }
00385  else glDisable(GL_LIGHT0);
00386 }
00387 
00388 static void DrawSky(GLfloat asp){
00389  int x,y,i,j;
00390  unsigned char *Image,*px,*r,*g,*b;
00391  Image=NULL;
00392  glDepthMask(GL_FALSE);
00393  glPushMatrix();
00394  glMatrixMode(GL_PROJECTION);
00395  glPushMatrix();
00396  glLoadIdentity();
00397  if(Sky.type == SKYMAPPED ||Sky.type == SKYCUBE)
00398        gluPerspective(ANGL_FOV/CamSx,asp,0.1,5);
00399  else  glOrtho(-1.0,1.0,-1.0,1.0,0.0,2.0);
00400  glMatrixMode( GL_MODELVIEW );
00401  glLoadIdentity();
00402  glRasterPos2i(-1.0,-1.0);
00403  if(Sky.type == SKYMAPPED || Sky.type == BACKDROP ||Sky.type == SKYCUBE){
00404    if(Sky.mapped && Sky.map.bLoadedS){
00405      x =Sky.map.xmax; y=Sky.map.ymax;
00406      if((Image=(unsigned char *)X__Malloc(x*y*3+3)) != NULL){
00407        for(j=0;j<y;j++){ 
00408          px=(Image+(y-j-1)*x*3);
00409          r=(Sky.map.p24R + j*x); g=(Sky.map.p24G + j*x); b=(Sky.map.p24B + j*x);
00410          for(i=0;i<x;i++){
00411            *px++ = *r++; *px++ = *g++; *px++ = *b++;
00412          } 
00413        }
00414      }
00415    }
00416  }
00417  if(Sky.type == SKYCOLOUR){
00418    glClearColor((GLfloat)Sky.Zenith[0]/255.0,(GLfloat)Sky.Zenith[1]/255.0,(GLfloat)Sky.Zenith[2]/255.0,1.0);
00419    glClear(GL_COLOR_BUFFER_BIT);
00420  }
00421  else if(Sky.type == SKYGRADED){
00422    GLfloat horizon[3],zenith[3];
00423    for(i=0;i<3;i++){zenith[i]=(GLfloat)Sky.Zenith[i]/255.0; horizon[i]=(GLfloat)Sky.Horizon[i]/255.0;}
00424    glBegin(GL_QUADS);
00425    glColor3fv(zenith);  glVertex3f(-1.0,-1.0,-1.0);
00426    glColor3fv(zenith);  glVertex3f( 1.0,-1.0,-1.0);
00427    glColor3fv(horizon); glVertex3f( 1.0, 0.0,-1.0);
00428    glColor3fv(horizon); glVertex3f(-1.0, 0.0,-1.0);
00429    glColor3fv(horizon); glVertex3f(-1.0, 0.0,-1.0);
00430    glColor3fv(horizon); glVertex3f( 1.0, 0.0,-1.0);
00431    glColor3fv(zenith);  glVertex3f( 1.0, 1.0,-1.0);
00432    glColor3fv(zenith);  glVertex3f(-1.0, 1.0,-1.0);
00433    glEnd();
00434  }
00435  else if(Sky.type == SKYMAPPED){
00436    if(Image != NULL){
00437      glActiveTexture(GL_TEXTURE0); 
00438      glBindTexture(GL_TEXTURE_2D,g_sky_texture);
00439      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT);
00440      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT);
00441      glTexImage2D(GL_TEXTURE_2D,0,3,x,y,0,GL_RGB,GL_UNSIGNED_BYTE,(GLvoid *)Image);
00442      glColor4ub(255,255,255,255);
00443      UseShaderProgram(7); 
00444      SetUniformInteger(7,"SkyMap",0); // tex unit 0
00445      {
00446      GLUquadricObj *Q;
00447      glRotatef(-CamTheta*180.0/PI,0.0,0.0,1.0); // Bank on axis
00448      glRotatef(-CamAlpha*180.0/PI,1.0,0.0,0.0); // 
00449      glRotatef(-CamPhi*180.0/PI,0.0,1.0,0.0);   // vertical axis - heading
00450      glRotatef(-90.0,1.0,0.0,0.0);
00451      Q=gluNewQuadric();
00452      gluQuadricTexture(Q,GL_TRUE);
00453      gluSphere(Q,5.0,20,20);
00454      gluDeleteQuadric(Q);
00455      }
00456      UseShaderProgram(0); 
00457      glBindTexture(GL_TEXTURE_2D,0);
00458    }
00459  }
00460  else if(Sky.type == BACKDROP){
00461    if(Image != NULL){
00462      glPixelZoom((GLfloat)TEXTUREBUFFER_WIDTH/(GLfloat)x,
00463                  (GLfloat)TEXTUREBUFFER_HEIGHT/(GLfloat)y);
00464      glDrawPixels((GLsizei)x,(GLsizei)y,GL_RGB,GL_UNSIGNED_BYTE,(GLvoid *)Image);
00465    }
00466  }
00467  else if(Sky.type == SKYCUBE){
00468    if(Image != NULL){
00469      GLfloat six=1.0/6.0,xss,xff;
00470      glActiveTexture(GL_TEXTURE0); 
00471      glBindTexture(GL_TEXTURE_2D,g_sky_texture);
00472      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT);
00473      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT);
00474      glTexImage2D(GL_TEXTURE_2D,0,3,x,y,0,GL_RGB,GL_UNSIGNED_BYTE,(GLvoid *)Image);
00475      glColor4ub(255,255,255,255);
00476      glRotatef(-CamTheta*180.0/PI,0.0,0.0,1.0); // Bank on axis
00477      glRotatef(-CamAlpha*180.0/PI,1.0,0.0,0.0); // 
00478      glRotatef(-CamPhi*180.0/PI,0.0,1.0,0.0);   // vertical axis - heading
00479      glBegin(GL_QUADS);
00480      xss=0.0; xff=xss+six;
00481      glTexCoord2f(xss,0.0); glVertex3f(-1.0,-1.0,-1.0);  // front 
00482      glTexCoord2f(xff,0.0); glVertex3f( 1.0,-1.0,-1.0);
00483      glTexCoord2f(xff,1.0); glVertex3f( 1.0, 1.0,-1.0);
00484      glTexCoord2f(xss,1.0); glVertex3f(-1.0, 1.0,-1.0);
00485      xss=xss+six, xff=xff+six;
00486      glTexCoord2f(xss,0.0); glVertex3f( 1.0,-1.0,-1.0); // right
00487      glTexCoord2f(xff,0.0); glVertex3f( 1.0,-1.0, 1.0);
00488      glTexCoord2f(xff,1.0); glVertex3f( 1.0, 1.0, 1.0);
00489      glTexCoord2f(xss,1.0); glVertex3f( 1.0, 1.0,-1.0);
00490      xss=xss+six, xff=xff+six;
00491      glTexCoord2f(xss,0.0); glVertex3f( 1.0,-1.0, 1.0);  // back
00492      glTexCoord2f(xff,0.0); glVertex3f(-1.0,-1.0, 1.0);
00493      glTexCoord2f(xff,1.0); glVertex3f(-1.0, 1.0, 1.0);
00494      glTexCoord2f(xss,1.0); glVertex3f( 1.0, 1.0, 1.0);
00495      xss=xss+six, xff=xff+six;
00496      glTexCoord2f(xss,0.0); glVertex3f(-1.0,-1.0, 1.0);  //left
00497      glTexCoord2f(xff,0.0); glVertex3f(-1.0,-1.0,-1.0);
00498      glTexCoord2f(xff,1.0); glVertex3f(-1.0, 1.0,-1.0);
00499      glTexCoord2f(xss,1.0); glVertex3f(-1.0, 1.0, 1.0);
00500      xss=xss+six, xff=xff+six;
00501      glTexCoord2f(xss,0.0); glVertex3f(-1.0, 1.0,-1.0);  // top
00502      glTexCoord2f(xff,0.0); glVertex3f( 1.0, 1.0,-1.0);
00503      glTexCoord2f(xff,1.0); glVertex3f( 1.0, 1.0, 1.0);
00504      glTexCoord2f(xss,1.0); glVertex3f(-1.0, 1.0, 1.0);
00505      xss=xss+six, xff=xff+six;
00506      glTexCoord2f(xss,0.0); glVertex3f(-1.0,-1.0, 1.0);  // bottom
00507      glTexCoord2f(xff,0.0); glVertex3f( 1.0,-1.0, 1.0);
00508      glTexCoord2f(xff,1.0); glVertex3f( 1.0,-1.0,-1.0);
00509      glTexCoord2f(xss,1.0); glVertex3f(-1.0,-1.0,-1.0);
00510      glEnd();
00511      glBindTexture(GL_TEXTURE_2D,0);
00512    }
00513  }
00514  glMatrixMode(GL_PROJECTION);
00515  glPopMatrix();
00516  glMatrixMode( GL_MODELVIEW);
00517  glPopMatrix();
00518  glDepthMask(GL_TRUE);
00519  if(Image != NULL)X__Free(Image);
00520 }
00521 
00522 static void DrawPlain3dObjects(void){  // used for rendering shadows
00523  GLfloat x,y,z;
00524  long i,j,k;
00525  long Nvert,Nface,nImaps,nMats;
00526  vertex *vp,*MainVp; 
00527  face   *fp,*MainFp;
00528  for(k=0;k<ObjectCount;k++){
00529    if(!Object[k].in_use)continue;
00530    MainVp=Object[k].Vbase;
00531    MainFp=Object[k].Fbase;
00532    Nvert=Object[k].NoVertices;
00533    Nface=Object[k].NoFaces;
00534    if(Nface > 0){
00535      glBegin(GL_TRIANGLES);
00536      for(fp=MainFp,i=0;i<Nface;i++,fp++){
00537        for(j=0;j<3;j++){
00538          vp=(MainVp+(fp->V[j]));
00539          x=((GLfloat)(vp->p[0]))*GlobalScale;
00540          y=((GLfloat)(vp->p[1]))*GlobalScale;
00541          z=((GLfloat)(vp->p[2]))*GlobalScale;
00542          glVertex3f(x,z,-y);
00543        }
00544      }
00545      glEnd();
00546    }
00547  }
00548  return;
00549 }
00550 
00551 static void Draw3dObjects(int pass, BOOL clip){
00552  GLfloat x,y,z,
00553          glos_color[]={1.0,1.0,1.0,1.0},
00554          dark_color[]={0.0,0.0,0.0,1.0},
00555          black[]={0.1,0.1,0.1,1.0},
00556          dull[]={0.0},
00557          shiny[]={100.0},dot;
00558  long i,j,k;
00559  long Nvert,Nface,nImaps,nMats;
00560  vertex *vp,*MainVp; 
00561  face   *fp,*MainFp;
00562  imap   *iMap;
00563  matl   *iMat;
00564  for(k=0;k<ObjectCount;k++){ // possibly draw all transp in a later pass not yet implemented TODO
00565    if(!Object[k].in_use)continue;
00566    MainVp=Object[k].Vbase;
00567    MainFp=Object[k].Fbase;
00568    iMap=Object[k].Mbase;
00569    iMat=Object[k].Tbase;
00570    Nvert=Object[k].NoVertices;
00571    Nface=Object[k].NoFaces;
00572    nMats=Object[k].NoMats;
00573    nImaps= Object[k].NoMaps;
00574    if(Nface > 0){
00575      // First Draw Polygons that have basic attributes only
00576      UseShaderProgram(1); 
00577      SetUniformInteger(1,"Clip1",(int)clip);
00578      SetUniformVariable(1,"SpecularContribution",0.5);   // only mix in a little
00579      glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,shiny);
00580      glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,glos_color);
00581      glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
00582      glEnable(GL_COLOR_MATERIAL);  // set color material properties
00583      glBegin(GL_TRIANGLES);
00584      for(fp=MainFp,i=0;i<Nface;i++,fp++){
00585        if(fp->ffmap >= 0)continue; // don't draw the mapped polygons or
00586        if(fp->ffmat >= 0)continue; // materials in this pass
00587        glColor4ub(fp->color[0],fp->color[1],fp->color[2],255);
00588        for(j=0;j<3;j++){
00589          vp=(MainVp+(fp->V[j]));
00590          x=((GLfloat)(vp->p[0]))*GlobalScale;
00591          y=((GLfloat)(vp->p[1]))*GlobalScale;
00592          z=((GLfloat)(vp->p[2]))*GlobalScale;
00593          if(fp->bSmooth){
00594            //if(fp->pn[j][1] > 0.0)glNormal3f(-fp->pn[j][0],-fp->pn[j][2],fp->pn[j][1]);
00595            //else                  
00596            glNormal3f(fp->pn[j][0],fp->pn[j][2],-fp->pn[j][1]);
00597          }
00598          else {
00599            //if(fp->n[1] > 0.0)glNormal3f(-fp->n[0],-fp->n[2],fp->n[1]);
00600            //else              
00601            glNormal3f(fp->n[0],fp->n[2],-fp->n[1]);
00602          }
00603          glVertex3f(x,z,-y);
00604        }
00605      }
00606      glEnd();
00607      UseShaderProgram(0); 
00608      glDisable(GL_COLOR_MATERIAL);
00609      if(nMats > 0 && Nface > 0)DrawMaterialPolys(FALSE,clip,nMats,iMat,Nface,MainFp,Nvert,MainVp);
00610      //if(nImaps > 0 && Nface > 0)DrawMappedPolys(FALSE,clip,nMats,iMat,nImaps,iMap,Nface,MainFp,Nvert,MainVp);
00611      if(nImaps > 0 && Nface > 0)DrawMappedPolys(TRUE,clip,nMats,iMat,nImaps,iMap,Nface,MainFp,Nvert,MainVp);
00612      if(nMats > 0 && Nface > 0)DrawMaterialPolys(TRUE,clip,nMats,iMat,Nface,MainFp,Nvert,MainVp);
00613      if(nMats > 0 && Nface > 0)DrawExternalMaterialPolys(FALSE,clip,nMats,iMat,Nface,MainFp,Nvert,MainVp);
00614    }
00615  }
00616  // Go back and draw transparent polys - TO DO - still on object basis
00617  return;
00618 }
00619 
00620 static void DrawMaterialPolys(BOOL bDrawTransparent, BOOL bClip, 
00621             long nMats, matl *iMat, 
00622             long Nface, face *MainFp, long Nvert, vertex *MainVp){
00623  int i,j,k,pass,matID=0;
00624  vector mN,mX,mY,mP,mp;
00625  GLfloat uu,vv,ww,spower,color[3];
00626  GLuint progID;
00627  GLint  attrloc;
00628  GLfloat x,y,z,
00629          glos_color[]={1.0,1.0,1.0,1.0},
00630          dark_color[]={0.0,0.0,0.0,1.0},
00631          black[]={0.1,0.1,0.1,1.0},
00632          dull[]={0.0},
00633          shiny[]={100.0},dot;
00634  vertex *vp;
00635  face   *fp;
00636  //
00637  color[0]=1.0; color[1]=1.0; color[2]=1.0;
00638  glEnable(GL_COLOR_MATERIAL);
00639  glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
00640  for(pass=0;pass<3;pass++){ // render transparency last
00641    if(bDrawTransparent && pass != 2)continue;
00642    if(!bDrawTransparent && pass == 2)continue;
00643    for(k=0;k<nMats;k++){
00644      if(iMat[k].bInternalShader)matID=iMat[k].internalShaderID;
00645      else if(iMat[k].shaderID[0] >= 0 || iMat[k].shaderID[1] >= 0 || // skip any external shaders
00646              iMat[k].shaderID[2] >= 0 || iMat[k].shaderID[3] >= 0)continue;
00647      if(pass == 0)progID=3; else progID=2;
00648      // skip any 3D Textures - put them in next pass //
00649      if(pass == 0 && !IsaNoise(matID))continue;  // skip unless a noise texture
00650      if(pass != 0 &&  IsaNoise(matID))continue;  // SKIP if a noise textures
00651      if(pass == 1 && iMat[k].transp > 0)continue;
00652      if(pass == 2 && iMat[k].transp == 0)continue;
00653      for(i=0;i<3;i++)color[i]=(GLfloat)iMat[k].color[i]/255.0;
00654      // set gl properites for this face
00655      glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,shiny);
00656      glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,glos_color);
00657      if(iMat[k].transp > 0){ // Set transparent blending
00658        glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,dull);
00659        glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,dark_color);
00660        glEnable(GL_BLEND);
00661        glDepthMask(GL_FALSE);
00662        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
00663        color[3]=(1.0 - (GLfloat)iMat[k].transp / 255.0);
00664      }
00665      else   color[3]=1.0;
00666      glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,color);
00667      glColor4fv(color);
00668      UseShaderProgram(progID);   
00669      SetUniformInteger(progID,"Clip1",(int)bClip);
00670      SetUniformVariable(progID,"MixRatio",(GLfloat)iMat[k].refl/255.0);
00671      SetUniformVariable(progID,"ShaderParameter",(GLfloat)iMat[k].params[0]/255.0); // shader parameter
00672      // Set up the reflection transformation for the reflected direction - this will UNDO the camera
00673      // orientation so that the reflection vector still points in a direction that is relative to world coordinates
00674      SetUniformVector(progID,"AntiNormal1",AntiCameraGL[0][0],AntiCameraGL[1][0],AntiCameraGL[2][0]);
00675      SetUniformVector(progID,"AntiNormal2",AntiCameraGL[0][1],AntiCameraGL[1][1],AntiCameraGL[2][1]);
00676      SetUniformVector(progID,"AntiNormal3",AntiCameraGL[0][2],AntiCameraGL[1][2],AntiCameraGL[2][2]);
00677      if(pass > 0 && iMat[k].refl > 0){
00678        glActiveTexture(GL_TEXTURE0);
00679        glBindTexture(GL_TEXTURE_2D,g_env_texture);
00680        SetUniformInteger(progID,"RefMap",0); // texture unit 0
00681      }
00682      if(matID == 8 || matID == 9 ||matID == 13){ // Bumpy - use normal map 
00683        glActiveTexture(GL_TEXTURE1);
00684        glBindTexture(GL_TEXTURE_2D,g_envB_texture);
00685        SetUniformInteger(progID,"NormalMap",1);
00686        SetUniformVector(progID,"Uvector",(GLfloat)(iMat[k].ax.bu_norm[0]),
00687                                          (GLfloat)(iMat[k].ax.bu_norm[2]),
00688                                         -(GLfloat)(iMat[k].ax.bu_norm[1]));
00689        SetUniformVector(progID,"Vvector",(GLfloat)(iMat[k].ax.bv_norm[0]),
00690                                          (GLfloat)(iMat[k].ax.bv_norm[2]),
00691                                         -(GLfloat)(iMat[k].ax.bv_norm[1]));
00692        SetUniformVector(progID,"Wvector",(GLfloat)(iMat[k].ax.bn[0]),
00693                                          (GLfloat)(iMat[k].ax.bn[2]),
00694                                         -(GLfloat)(iMat[k].ax.bn[1]));
00695     }
00696      if(pass == 0){  // A noise texture 
00697 //       glDisable(GL_TEXTURE_2D); 
00698 //       glEnable(GL_TEXTURE_3D);
00699 //       glActiveTexture(GL_TEXTURE1);
00700        glActiveTexture(GL_TEXTURE0);
00701        glBindTexture(GL_TEXTURE_3D,g_noise_texture);
00702 //       SetUniformInteger(progID,"NoiseMap",1); 
00703        SetUniformInteger(progID,"NoiseMap",0); 
00704        if(iMat[k].refl > 0){
00705 //         glActiveTexture(GL_TEXTURE0);
00706          glActiveTexture(GL_TEXTURE1);
00707 //         glBindTexture(GL_TEXTURE_2D,g_env_texture);
00708          glBindTexture(GL_TEXTURE_3D,g_env3D_texture);
00709 //         SetUniformInteger(progID,"RefMap",0); // texture unit 0
00710          SetUniformInteger(progID,"RefMap",1); // texture unit 0
00711        }
00712      }
00713      spower=(20.0 + (80.0 - 10.0)*(GLfloat)(iMat[k].gloss)/255.0);
00714      SetUniformVariable(progID,"SpecularPower",spower);
00715      if(iMat[k].bShiny)SetUniformVariable(progID,"SpecularContribution",1.0);
00716      else              SetUniformVariable(progID,"SpecularContribution",0.0);
00717      SetUniformVector(progID,"MaterialC",(GLfloat)iMat[k].texco[0]/255.0,
00718                                          (GLfloat)iMat[k].texco[1]/255.0,
00719                                          (GLfloat)iMat[k].texco[2]/255.0);
00720      SetUniformInteger(progID,"ShaderID",matID);
00721      attrloc=GetAttibuteLocation(progID,"ShaderPosition");
00722      glBegin(GL_TRIANGLES);
00723      fp=MainFp; for(i=0;i<Nface;i++,fp++){ // daw the mapped polys
00724        if(fp->ffmat != k || fp->ffmap >= 0  || fp->ffmat < 0)continue; //skip
00725        for(j=0;j<3;j++){
00726          vp=(MainVp+(fp->V[j]));
00727          x=((GLfloat)(vp->p[0]))*GlobalScale;
00728          y=((GLfloat)(vp->p[1]))*GlobalScale;
00729          z=((GLfloat)(vp->p[2]))*GlobalScale;
00730          if(fp->bSmooth){
00731            //if(fp->pn[j][1] > 0.0)glNormal3f(-fp->pn[j][0],-fp->pn[j][2],fp->pn[j][1]);
00732            //else
00733            glNormal3f(fp->pn[j][0],fp->pn[j][2],-fp->pn[j][1]);
00734          }
00735          else {
00736            //if(fp->n[1] > 0.0)glNormal3f(-fp->n[0],-fp->n[2],fp->n[1]);
00737            //else
00738            glNormal3f(fp->n[0],fp->n[2],-fp->n[1]);
00739          }
00740          uu=fp->uu[j]; vv=fp->vv[j]; ww=fp->ww[j];
00741          //fprintf(debug,"Face %ld Vertex %ld - uu=%f vv=%f ww=%f\n",i,j,uu,vv,ww);
00742          //SetAttributeVector(3,"ShaderPosition",uu,vv,ww);   // DO NOT USE THIS !!! Get the location first
00743          SetAttributeVectorID(progID,attrloc,uu,vv,ww);  
00744          glVertex3f(x,z,-y);
00745        }
00746      }
00747      glEnd();
00748      UseShaderProgram(0); 
00749      // any material attributes that need to be undone ?
00750      if(iMat[k].transp > 0){ // Set transparent blending
00751        glDepthMask(GL_TRUE);
00752        glDisable(GL_BLEND);
00753      }
00754      if(matID == 8 ||matID == 9 ||matID == 13){
00755        glActiveTexture(GL_TEXTURE1);
00756        glBindTexture(GL_TEXTURE_2D,0);
00757        glActiveTexture(GL_TEXTURE0);
00758      }
00759      if(iMat[k].refl > 0){
00760        if(pass == 0){
00761          glActiveTexture(GL_TEXTURE1);
00762          glBindTexture(GL_TEXTURE_3D,0);
00763        }
00764        else{
00765          glActiveTexture(GL_TEXTURE0);
00766          glBindTexture(GL_TEXTURE_2D,0);
00767        }
00768      }
00769      if(pass == 0){
00770        glActiveTexture(GL_TEXTURE0);  
00771 //       glActiveTexture(GL_TEXTURE1);  ///// unbind the noise
00772        glBindTexture(GL_TEXTURE_3D,0);
00773 //       glDisable(GL_TEXTURE_3D);
00774 //       glEnable(GL_TEXTURE_2D);
00775      }
00776    }
00777  }
00778  glDisable(GL_COLOR_MATERIAL);
00779 }
00780 
00781 static BOOL IsaNoise(int i){
00782   if(i == 1 || i == 2 || i == 3 || i == 6 || i == 7 || i == 10 || i == 11 || i == 12)return TRUE;
00783   return FALSE;
00784 }
00785 
00786 static void DrawMappedPolys(BOOL bDrawTransparent,BOOL bClip,
00787             long nMats, matl *iMat,  
00788             long nImaps, imap *iMap, 
00789             long Nface, face *MainFp, long Nvert, vertex *MainVp){
00790  GLfloat mixColour[4]={0.0,0.0,0.0,0.0};
00791  GLfloat x,y,z,n[3],
00792          dot;
00793  GLint   TanLoc,BinLoc;
00794  face *fp;
00795  vertex *v;
00796  int i,j,k,m;
00797  BOOL refmap;
00798  int brushID;
00799  vector mN,mX,mY,mP;
00800  GLfloat alpha,beta,tangent[3],binormal[3]; //tangent/binormal not used yet
00801  GLfloat colour3,bc[4]={0.0,0.0,0.0,0.0};
00802  for(k=0;k<nImaps;k++){       // loop over all maps
00803    UseShaderProgram(4);   
00804    SetUniformInteger(4,"bTransPass",(int)bDrawTransparent);  // transparency ?
00805    SetUniformInteger(4,"Clip1",(int)bClip); // to clip or not to clip ?
00806    // Assign anti-reflection matrix
00807    SetUniformVector(4,"AntiNormal1",AntiCameraGL[0][0],AntiCameraGL[1][0],AntiCameraGL[2][0]); // OGL needs
00808    SetUniformVector(4,"AntiNormal2",AntiCameraGL[0][1],AntiCameraGL[1][1],AntiCameraGL[2][1]); // this order
00809    SetUniformVector(4,"AntiNormal3",AntiCameraGL[0][2],AntiCameraGL[1][2],AntiCameraGL[2][2]);
00810    refmap=FALSE;
00811    if(iMap[k].bTiled)SetUniformInteger(4,"bTiled",1);
00812    else              SetUniformInteger(4,"bTiled",0);
00813    if(iMap[k].bShaded)SetUniformInteger(4,"bShaded",1);
00814    else               SetUniformInteger(4,"bShaded",0);
00815    if(iMap[k].bDecal)SetUniformInteger(4,"bDecal",1);
00816    else              SetUniformInteger(4,"bDecal",0);
00817    glActiveTexture(GL_TEXTURE0);  // Surface Map
00818    glBindTexture(GL_TEXTURE_2D,0);  
00819    if(iMap[k].bLoadedS){     
00820      SetUniformInteger(4,"bS",1);
00821 //     if(iMap[k].bAnimS)glBindTexture(GL_TEXTURE_2D,g_movie_texture); 
00822 //     else 
00823      if(iMap[k].p24R != NULL){
00824        glBindTexture(GL_TEXTURE_2D,g_map_texture);
00825        TextureWithAlpha(iMap[k].xmax,iMap[k].ymax,iMap[k].p24R,iMap[k].p24G,iMap[k].p24B,255,
00826        iMap[k].bDecal,iMap[k].kc[0],iMap[k].kc[1],iMap[k].kc[2]);
00827      }
00828      else glBindTexture(GL_TEXTURE_2D,g_check_texture);
00829      if(iMap[k].moziac){
00830        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT);
00831        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT);
00832      }
00833      else{
00834        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00835        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00836      }
00837      SetUniformVariable(4,"MixSurface",(GLfloat)iMap[k].pp*0.01);
00838      SetUniformInteger(4,"SurfaceMap",0); // texture unit 0
00839    }
00840    else SetUniformInteger(4,"bS",0);
00841    glActiveTexture(GL_TEXTURE1);  // Reflection Map
00842    glBindTexture(GL_TEXTURE_2D,0);
00843    if(iMap[k].bLoadedR){
00844      SetUniformInteger(4,"bR",1);
00845 //     if(iMap[k].bAnimR)glBindTexture(GL_TEXTURE_2D,g_movie_texture);
00846 //     else 
00847      if(iMap[k].p24Rrefl != NULL){
00848        glBindTexture(GL_TEXTURE_2D,g_ref_texture);
00849        Texture(iMap[k].xmaxrefl,iMap[k].ymaxrefl,iMap[k].p24Rrefl,iMap[k].p24Grefl,iMap[k].p24Brefl);
00850      }
00851      else glBindTexture(GL_TEXTURE_2D,g_check_texture);
00852      refmap=TRUE;
00853      SetUniformVariable(4,"MixRef",(GLfloat)iMap[k].rp*0.01);
00854      SetUniformInteger(4,"RefMap",1); // texture unit 1
00855    }
00856    else SetUniformInteger(4,"bR",0);
00857    glActiveTexture(GL_TEXTURE2);
00858    glBindTexture(GL_TEXTURE_2D,0);
00859    if(iMap[k].bLoadedB){   
00860      SetUniformInteger(4,"bB",1);
00861 //     if(iMap[k].bAnimB)glBindTexture(GL_TEXTURE_2D,g_movie_texture);
00862 //     else 
00863      if(iMap[k].p24Rbump != NULL){
00864        glBindTexture(GL_TEXTURE_2D,g_bump_texture);
00865        Texture(iMap[k].xmaxbump,iMap[k].ymaxbump,iMap[k].p24Rbump,iMap[k].p24Gbump,iMap[k].p24Bbump);
00866      }
00867      else glBindTexture(GL_TEXTURE_2D,g_check_texture);
00868      if(iMap[k].moziac){
00869        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT);
00870        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT);
00871      }
00872      else{
00873        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00874        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00875      }
00876      SetUniformVariable(4,"MixBump",(GLfloat)iMap[k].bp*0.01);
00877      SetUniformInteger(4,"BumpMap",2); // texture unit 2
00878    }
00879    else SetUniformInteger(4,"bB",0);
00880 
00881    glActiveTexture(GL_TEXTURE3);
00882    glBindTexture(GL_TEXTURE_2D,0);
00883    if(iMap[k].bLoadedT){ // Transparency map  // discard any Transparent pixels
00884      SetUniformInteger(4,"bT",1);
00885 //     if(iMap[k].bAnimT)glBindTexture(GL_TEXTURE_2D,g_movie_texture);
00886 //     else 
00887      if(iMap[k].p24Rtran != NULL){
00888        glBindTexture(GL_TEXTURE_2D,g_tran_texture);
00889        Texture(iMap[k].xmaxtran,iMap[k].ymaxtran,iMap[k].p24Rtran,iMap[k].p24Gtran,iMap[k].p24Btran);
00890      }
00891      else glBindTexture(GL_TEXTURE_2D,g_check_texture);
00892      if(iMap[k].moziac){
00893        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT);
00894        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT);
00895      }
00896      else{
00897        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00898        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00899      }
00900      SetUniformInteger(4,"TransMap",3); // texture unit 3
00901    }
00902    else SetUniformInteger(4,"bT",0);
00903 
00904    glActiveTexture(GL_TEXTURE0);   // Render the mapped surface - loop over the materials
00905    m = -1; 
00906    matloop:
00907    glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
00908    glEnable(GL_COLOR_MATERIAL);
00909    colour3=1.0;
00910    if(bDrawTransparent && iMap[k].bLoadedT){
00911      glEnable(GL_BLEND);
00912      glDepthMask(GL_FALSE);
00913      glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
00914      colour3=1.0;
00915    }
00916    else if(m >= 0){
00917      if(iMat[m].bShiny)SetUniformVariable(4,"SpecularContribution",1.0);
00918      else              SetUniformVariable(4,"SpecularContribution",0.0);
00919      if(iMat[m].transp > 0){ // Set transparent blending
00920        glEnable(GL_BLEND);
00921        glDepthMask(GL_FALSE);
00922        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
00923        colour3=(1.0 - (GLfloat)iMat[m].transp / 255.0);
00924      }
00925    }
00926    else SetUniformVariable(4,"SpecularContribution",0.5);
00927    // There should really be set on a per vertex basis but 
00928    // calculating them here is OK because we don't user true BINORMAL
00929    // may be hardware dependent - thes need to be set per map
00930    VECCOPY(iMap[k].x,tangent)  normalize(tangent);
00931    VECCOPY(iMap[k].y,binormal) normalize(binormal);
00932    TanLoc=GetAttibuteLocation(4,"Tangent"); // Needs to be called before glBegin !!!!
00933    BinLoc=GetAttibuteLocation(4,"Binormal");
00934    //SetAttributeVector(4,"Tangent",tangent[0],tangent[2],-tangent[1]); //  
00935    //SetAttributeVector(4,"Binormal",binormal[0],binormal[2],-binormal[1]); 
00936    //
00937    glBegin(GL_TRIANGLES);
00938    fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++,fp++){
00939      if(fp->ffmap < 0)continue; /* if not mapped */
00940      if(m >= 0 && fp->ffmat != m)continue; // not this material
00941      if(m == -1 && fp->ffmat >= 0)continue; // or this basic one
00942      brushID=fp->ffmap;
00943      if(brushID != k)continue;         /* skip if not this map */
00944      if(m == -1)glColor4ub(fp->color[0],fp->color[1],fp->color[2],(unsigned char)(colour3*255));
00945      else       glColor4ub(iMat[m].color[0],iMat[m].color[1],iMat[m].color[2],(unsigned char)(colour3*255));
00946      for(j=0;j<3;j++){
00947        v=(MainVp+(fp->V[j]));
00948        x=((GLfloat)(v->p[0]))*GlobalScale;
00949        y=((GLfloat)(v->p[1]))*GlobalScale;
00950        z=((GLfloat)(v->p[2]))*GlobalScale;
00951        if(fp->bSmooth){ /* smoothed */
00952          if(fp->pn[j][1] > 0.0)glNormal3f(-fp->pn[j][0],-fp->pn[j][2],fp->pn[j][1]);
00953          else                  glNormal3f(fp->pn[j][0],fp->pn[j][2],-fp->pn[j][1]);
00954        }
00955        else {
00956          if(fp->n[1] > 0.0)glNormal3f(-fp->n[0],-fp->n[2],fp->n[1]);
00957          else              glNormal3f(fp->n[0],fp->n[2],-fp->n[1]);
00958        }
00959        //SetAttributeVector(4,"Tangent",tangent[0],tangent[2],-tangent[1]); // DO NOT USE
00960        //SetAttributeVector(4,"Binormal",binormal[0],binormal[2],-binormal[1]); // DO NOT USE
00961        SetAttributeVectorID(4,TanLoc,tangent[0],tangent[2],-tangent[1]);   // 
00962        SetAttributeVectorID(4,BinLoc,binormal[0],binormal[2],-binormal[1]); 
00963        alpha=fp->uu[j]; beta=fp->vv[j];
00964        glMultiTexCoord2f(GL_TEXTURE0,alpha,beta);  // for non reflective textures
00965        glVertex3f(x,z,-y);
00966      }
00967    }
00968    glEnd();
00969    if((bDrawTransparent && iMap[k].bLoadedT) || (m >= 0 && iMat[m].transp > 0)){
00970      glDepthMask(GL_TRUE);
00971      glDisable(GL_BLEND);
00972    }
00973 
00974    glDisable(GL_COLOR_MATERIAL);
00975    m++;
00976    if(nMats > 0 && m >= 0 && m < nMats)goto matloop;
00977    glActiveTexture(GL_TEXTURE3); 
00978    glBindTexture(GL_TEXTURE_2D,0);
00979    glActiveTexture(GL_TEXTURE2); 
00980    glBindTexture(GL_TEXTURE_2D,0);
00981    glActiveTexture(GL_TEXTURE1); 
00982    glBindTexture(GL_TEXTURE_2D,0);
00983    glActiveTexture(GL_TEXTURE0); 
00984    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00985    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00986    glBindTexture(GL_TEXTURE_2D,0);
00987    UseShaderProgram(0); 
00988  }   // each map
00989 }
00990 
00991 static void TextureWithAlpha(long x, long y, unsigned char *R, unsigned char *G, unsigned char *B, 
00992                       unsigned char alpha, BOOL bDecal,
00993                       unsigned char r, unsigned char g, unsigned char b){  // no border
00994   unsigned char *pout,*p;
00995   long i,j;
00996   pout=X__Malloc(x*y*4); p=pout;
00997   for(i=0;i<y;i++)for(j=0;j<x;j++){
00998     *p++ = *R++;
00999     *p++ = *G++;
01000     *p++ = *B++;
01001     if(bDecal){
01002       if(*(p-3) == r && *(p-2) == g && *(p-1) == b)*p++ = 0;
01003       else  *p++ = alpha;
01004     }
01005     else  *p++ = alpha;
01006   }
01007   glTexImage2D(GL_TEXTURE_2D,0,4,x,y,0,GL_RGBA,GL_UNSIGNED_BYTE,(GLvoid *)pout);
01008   X__Free(pout);
01009 }
01010 
01011 static void Texture(long x, long y, unsigned char *R, unsigned char *G, unsigned char *B){
01012   unsigned char *pout,*p;
01013   long i,j;
01014   pout=X__Malloc(x*y*3); p=pout;
01015   for(i=0;i<y;i++)for(j=0;j<x;j++){
01016     *p++ = *R++;
01017     *p++ = *G++;
01018     *p++ = *B++;
01019   }
01020   glTexImage2D(GL_TEXTURE_2D,0,3,x,y,0,GL_RGB,GL_UNSIGNED_BYTE,(GLvoid *)pout);
01021   X__Free(pout);
01022 }
01023 
01024 static void InstallShadowMatrix(GLfloat ground[4], GLfloat light[4]){
01025 GLfloat dot;
01026 GLfloat shadowMat[4][4];
01027 dot = ground[0] * light[0] +
01028       ground[1] * light[1] +
01029       ground[2] * light[2] +
01030       ground[3] * light[3];
01031 shadowMat[0][0] = dot - light[0] * ground[0];
01032 shadowMat[1][0] = 0.0 - light[0] * ground[1];
01033 shadowMat[2][0] = 0.0 - light[0] * ground[2];
01034 shadowMat[3][0] = 0.0 - light[0] * ground[3];
01035 shadowMat[0][1] = 0.0 - light[1] * ground[0];
01036 shadowMat[1][1] = dot - light[1] * ground[1];
01037 shadowMat[2][1] = 0.0 - light[1] * ground[2];
01038 shadowMat[3][1] = 0.0 - light[1] * ground[3];
01039 shadowMat[0][2] = 0.0 - light[2] * ground[0];
01040 shadowMat[1][2] = 0.0 - light[2] * ground[1];
01041 shadowMat[2][2] = dot - light[2] * ground[2];
01042 shadowMat[3][2] = 0.0 - light[2] * ground[3];
01043 shadowMat[0][3] = 0.0 - light[3] * ground[0];
01044 shadowMat[1][3] = 0.0 - light[3] * ground[1];
01045 shadowMat[2][3] = 0.0 - light[3] * ground[2];
01046 shadowMat[3][3] = dot - light[3] * ground[3];
01047 glMultMatrixf((const GLfloat*)shadowMat);
01048 }
01049 
01050 static void InstallReflectionMatrix(GLfloat p0[3], GLfloat n[3]){
01051 GLfloat d;
01052 GLfloat refMat[4][4];
01053 GLfloat n0s,n1s,n2s;
01054 d = DOT(p0,n);
01055 n0s=n[0]*n[0]; n1s=n[1]*n[1]; n2s=n[2]*n[2];
01056 refMat[0][0] = 1-2.0*n0s;
01057 refMat[0][1] = -2.0*n[0]*n[1];
01058 refMat[0][2] = -2.0*n[0]*n[2];
01059 refMat[0][3] = 0.0;
01060 refMat[1][0] = -2.0*n[1]*n[0];
01061 refMat[1][1] = 1-2.0*n1s;
01062 refMat[1][2] = -2.0*n[1]*n[2];
01063 refMat[1][3] = 0.0;
01064 refMat[2][0] = -2.0*n[2]*n[0];
01065 refMat[2][1] = -2.0*n[2]*n[1];
01066 refMat[2][2] = 1-2.0*n2s;
01067 refMat[2][3] = 0.0;
01068 refMat[3][0] = 2.0*d*n[0];
01069 refMat[3][1] = 2.0*d*n[1];
01070 refMat[3][2] = 2.0*d*n[2];
01071 refMat[3][3] = 1.0;
01072 glMultMatrixf((const GLfloat*)refMat);
01073 }

Generated on Sun Apr 27 14:20:13 2014 for OpenFX by  doxygen 1.5.6