gldesign2.c

Go to the documentation of this file.
00001 /* --
00002 OpenFX Modelling, Animation and Rendering Package
00003 -- */
00004 
00005 /* file GLDESIGN2.C   */
00006 
00007 #define _DSCRUCT_SUB 1
00008 
00009 #include "gldesign1.h"
00010 
00011 extern unsigned char *LoadMAP(char *InFile, long *xx,long *yy);
00012 
00013 extern GLfloat up_angle,round_angle;
00014 extern GLfloat gbRed,gbGreen,gbBlue;
00015 extern GLfloat gwRed,gwGreen,gwBlue;
00016 extern GLfloat near_plane,far_plane,vertex_scale;
00017 extern GLint listID,mode,bounding_box,current_map;
00018 extern BOOL  Mapped,Update,Fastest,Clamped,
00019       Cmaterial,AttenuateLight,TwoSided,
00020       ScrollBars,bDrawMapping,bOverlayWire,bOverlayWireHidden,bSelectOnlyInView,
00021       bThickWire,bNurbsWireOnly,
00022       bStereo,bStereoDraw;
00023 extern char gszBMPfile[],gszBMPdir[],gszRootDir[];
00024 extern GLMAP    *glMapList;
00025 extern long     NglMapList;
00026 extern void TextureWithAlpha(long x, long y, unsigned char *pin, unsigned char alpha, BOOL, 
00027                       unsigned char,unsigned char, unsigned char);
00028 
00029 extern GLuint g_check_texture;
00030 extern GLuint g_map_texture;
00031 extern GLuint g_movie_texture;
00032 extern GLuint g_env_texture;
00033 extern GLuint g_envB_texture;
00034 extern GLuint g_bump_texture;
00035 extern GLuint g_ref_texture;
00036 extern GLuint g_tran_texture;
00037 extern GLuint g_noise_texture;
00038 extern GLubyte checkImage[checkImageWidth][checkImageHeight][3];
00039 
00040 extern void DrawGlNurbs(GLfloat);
00041 extern void DrawProjectMapRectangle(void);
00042 extern void makeCheckImageMap(int id);
00043 extern void GetMappingCoordS(int id, vector n, vector dx, vector dy, vector p0, long *pv,
00044                  GLfloat * a, GLfloat * b);
00045 extern void GetMappingCoordP(int id, vector n, vector x, vector y, vector p0,
00046                              long *pv,
00047                              GLfloat *a, GLfloat *b);
00048 extern void GetMappingCoordC(int id, vector n, vector x, vector y, vector p0,
00049                 long *pv,
00050                 GLfloat *a, GLfloat *b);
00051 extern void GetMapNormal(int k, vector mP, vector mX, vector mY,
00052                          vector mN);
00053 extern BOOL normalise(GLfloat *v);
00054 extern BOOL Normalize(point x,point y,point z,GLfloat *n);
00055 
00056 extern BOOL inview(vertex  *vp);
00057 extern void FixUpMapEdge(GLfloat alpha[]);
00058 
00059 static void DrawMappedPolysProg(GLfloat scale, normal *nv);
00060 static void GetRelativeCoord(vector n, vector x, vector y, vector pb, vector pf,
00061                 GLfloat * a, GLfloat * b, GLfloat *c);
00062 static void GetTextureNormal(int k, vector mP, vector mX, vector mY,
00063                          vector mN);
00064 static void fix_tangents(normal t0, normal t1, normal t2, normal *tng);
00065 
00066 static BOOL IsaNoise(int i){
00067 //  if(i == 1 || i == 2 || i == 3 || i == 6 || i == 10 || i == 11 || i == 12)return TRUE;
00068   if(i == 1 || i == 2 || i == 3 || i == 6 || i == 7 || i == 10 || i == 11 || i == 12)return TRUE;
00069   return FALSE;
00070 }
00071 
00072 void Make3dDisplayListProg(void){
00073  GLfloat x,y,z,scale,n[3],tangent[3],color[4],vv[3],*spec_color,
00074          glos_color[]={1.0,1.0,1.0,1.0},
00075          dark_color[]={0.0,0.0,0.0,1.0},
00076          black[]={0.1,0.1,0.1,1.0},
00077          dull[]={0.0},
00078          shiny[]={100.0},dot;
00079  face *fp;
00080  vertex *v,*v1,*v2,*v0,*vnext;
00081  normal *nv; //,*nt,tng,ftng[3];
00082  int i,j,jn,k,m,Vi,V[3];
00083  if(Nface == 0 && Nnurbs == 0){
00084    if(listID > 0){glDeleteLists(1,1);listID=0;}
00085    return;
00086  }
00087  if(Nvert > 0){
00088    if((nv=(normal *)X__Malloc(sizeof(normal)*Nvert)) == NULL){
00089      return;
00090    }
00091 //   if((nt=(normal *)X__Malloc(sizeof(normal)*Nvert)) == NULL){  // tangent vector
00092 //     X__Free(nv);
00093 //     return;
00094 //   }
00095    for(i=0;i<Nvert;i++)for(j=0;j<3;j++)nv[i][j]=0.0; // nt[i][j]=0.0;
00096  }
00097  fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++){  // calculate the vertex normals
00098    V[0]=fp->V[0]; V[1]=fp->V[1]; V[2]=fp->V[2];
00099    v0=(MainVp+V[0]); v1=(MainVp+V[1]); v2=(MainVp+V[2]);
00100    if(inview(v0) || inview(v1) || inview(v2)){
00101      VECSUB((GLfloat)v1->xyz,(GLfloat)v0->xyz,tangent)
00102      //for(j=0;j<3;j++)VECCOPY(tangent,nt[V[j]])
00103      if(Normalize(v0->xyz,v1->xyz,v2->xyz,n)){
00104        for(j=0;j<3;j++){
00105          dot=DOT(nv[V[j]],n);
00106          if(dot >  1.e-5){
00107            VECSUM(nv[V[j]],n,nv[V[j]])
00108          }
00109          else if(dot < -1.e-5){
00110            VECSUB(nv[V[j]],n,nv[V[j]])
00111          }
00112          else{
00113            VECSUM(nv[V[j]],n,nv[V[j]])
00114          }
00115        }
00116      }
00117    }
00118    fp++;
00119  }
00120  //if(Nvert > 0)for(i=0;i<Nvert;i++){
00121  //  normalise(nv[i]); 
00122  //  CROSS(nt[i],nv[i],tng)
00123  //  CROSS(nv[i],tng,nt[i])
00124  //  normalise(nt[i]);
00125  //}
00126 
00127  if(listID > 0){glDeleteLists(1,1);listID=0;}
00128  glNewList(1,GL_COMPILE);
00129  
00130  color[3]=1.0; color[0]=1.0; color[1]=1.0; color[2]=1.0;
00131  scale=vertex_scale/TVsizeX;
00132  glEnable(GL_LIGHTING);
00133  
00134  // first draw the polygon with basic attributes only
00135  glEnable(GL_COLOR_MATERIAL);
00136  UseShaderProgram(1); 
00137  SetUniformInteger(1,"TwoSided",(int)TwoSided); 
00138  SetUniformVariable(1,"SpecularContribution",0.5);   // only mix in a little
00139  glBegin(GL_TRIANGLES);
00140  glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,shiny);
00141  glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,glos_color);
00142  fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++,fp++){
00143    if(Mapped && fp->imagemap >= 0)continue; // don't draw the mapped polygons shader prog can handle this
00144    if(fp->material  >= 0)continue;          // materials in this pass
00145    v0=(MainVp+fp->V[0]); v1=(MainVp+fp->V[1]); v2=(MainVp+fp->V[2]);
00146    if(inview(v0) || inview(v1) || inview(v2)){
00147        color[0]=(GLfloat)fp->color[0]/255.0;
00148        color[1]=(GLfloat)fp->color[1]/255.0;
00149        color[2]=(GLfloat)fp->color[2]/255.0;
00150        glColor4fv(color);
00151        if(Normalize(v0->xyz,v1->xyz,v2->xyz,n)){
00152          for(j=0;j<3;j++){
00153            Vi=fp->V[j]; v=(MainVp+Vi);
00154            x=((GLfloat)(v->xyz[0]-TVpointX-TVsizeX/2))*scale;
00155            y=((GLfloat)(v->xyz[1]-TVpointY-TVsizeY/2))*scale;
00156            z=((GLfloat)(v->xyz[2]-TVpointZ-TVsizeZ/2))*scale;
00157            if(fp->bSmooth){ /* smoothed */
00158              dot=DOT(nv[Vi],n);
00159              if(fabs(dot) < 0.5)glNormal3f(n[0],n[2],-n[1]);
00160              else if(dot  < 0.0)glNormal3f(-nv[Vi][0],-nv[Vi][2], nv[Vi][1]);
00161              else               glNormal3f( nv[Vi][0], nv[Vi][2],-nv[Vi][1]);
00162            }
00163            else{/* not smoothed */
00164              glNormal3f( n[0], n[2],-n[1]);
00165            }
00166            glVertex3f(x,z,-y);
00167          }
00168        }
00169    }
00170  }
00171  glEnd();
00172  UseShaderProgram(0); 
00173  glDisable(GL_COLOR_MATERIAL);
00174 
00175  DrawGlNurbs(GLU_FILL);
00176 
00177  if(Mapped && Nface > 0)DrawMappedPolysProg(scale,nv);
00178 
00179  if(nMats > 0 && Nface > 0){ // render the materials
00180    int pass,matID=0;
00181    vector mN,mX,mY,mP,mp;
00182    GLfloat uu,vv,ww,spower;
00183    GLuint progID;
00184    color[0]=1.0; color[1]=1.0; color[2]=1.0;
00185    glEnable(GL_COLOR_MATERIAL);
00186    glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
00187    for(pass=0;pass<3;pass++) // render transparency last
00188    for(k=0;k<nMats;k++){
00189      if(pass == 0)progID=3; else progID=2;
00190      if(iMat[k].bInternalShader)matID=iMat[k].internalShaderID;
00191      // skip any 3D Textures - put them in next pass //
00192      if(pass == 0 && !IsaNoise(matID))continue;  // skip unless a noise texture
00193      if(pass != 0 &&  IsaNoise(matID))continue;  // SKIP if a noise textures
00194      if(pass == 1 && iMat[k].transp > 0)continue;
00195      if(pass == 2 && iMat[k].transp == 0)continue;
00196      GetTextureNormal(k,mP,mX,mY,mN);
00197      for(i=0;i<3;i++)color[i]=(GLfloat)iMat[k].mcolour1[i]/255.0;
00198      // set gl properites for this face
00199      glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,shiny);
00200      glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,glos_color);
00201      if(iMat[k].transp > 0){ // Set transparent blending
00202        glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,dull);
00203        glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,dark_color);
00204        glEnable(GL_BLEND);
00205        glDepthMask(GL_FALSE);
00206        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
00207        color[3]=(1.0 - (GLfloat)iMat[k].transp / 255.0);
00208      }
00209      else color[3]=1.0;
00210      glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,color);
00211      glColor4fv(color);
00212      UseShaderProgram(progID);   
00213      SetUniformInteger(progID,"TwoSided",(int)TwoSided); 
00214      SetUniformVariable(progID,"MixRatio",(GLfloat)iMat[k].refl/255.0);
00215      SetUniformVariable(progID,"ShaderParameter",(GLfloat)iMat[k].params[0]/255.0); // shader parameter
00216      if(pass > 0 && iMat[k].refl > 0){
00217        glActiveTexture(GL_TEXTURE0);
00218        glBindTexture(GL_TEXTURE_2D,g_env_texture);
00219        SetUniformInteger(progID,"RefMap",0); // texture unit 0
00220      }
00221      if(matID == 8 || matID == 9 ||matID == 13){ // wrinkled (not bumpy that is in Noise texture)
00222        glActiveTexture(GL_TEXTURE1);
00223        glBindTexture(GL_TEXTURE_2D,g_envB_texture);
00224        SetUniformInteger(progID,"NormalMap",1);
00225        SetUniformVector(progID,"Uvector",(GLfloat)mX[0],-(GLfloat)mX[2],(GLfloat)mX[1]);
00226        SetUniformVector(progID,"Vvector",(GLfloat)mY[0],-(GLfloat)mY[2],(GLfloat)mY[1]);
00227        SetUniformVector(progID,"Wvector",(GLfloat)mN[0],-(GLfloat)mN[2],(GLfloat)mN[1]);
00228      }
00229      if(pass == 0){ // noisy texture and bumpy
00230        glDisable(GL_TEXTURE_2D);  // A noise texture 
00231        glEnable(GL_TEXTURE_3D);
00232        glActiveTexture(GL_TEXTURE1);
00233        glBindTexture(GL_TEXTURE_3D,g_noise_texture);
00234        SetUniformInteger(progID,"NoiseMap",1); // texture unit (was 1)
00235        if(iMat[k].refl > 0){
00236          glActiveTexture(GL_TEXTURE0);
00237          glBindTexture(GL_TEXTURE_2D,g_env_texture);
00238          SetUniformInteger(progID,"RefMap",0); // texture unit 0
00239        }
00240      }
00241      SetUniformInteger(progID,"ShaderID",matID);
00242      spower=(20.0 + (80.0 - 10.0)*(GLfloat)(iMat[k].gloss)/255.0);
00243      SetUniformVariable(progID,"SpecularPower",spower);
00244      if(iMat[k].bShiny)SetUniformVariable(progID,"SpecularContribution",1.0);
00245      else              SetUniformVariable(progID,"SpecularContribution",0.0);
00246      SetUniformVector(progID,"MaterialC",(GLfloat)iMat[k].mcolour2[0]/255.0,
00247                                          (GLfloat)iMat[k].mcolour2[1]/255.0,
00248                                          (GLfloat)iMat[k].mcolour2[2]/255.0);
00249      SetUniformInteger(progID,"ShaderID",matID);
00250      glBegin(GL_TRIANGLES);
00251      fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++,fp++){ // daw the mapped polys
00252        // skip the mapped polys - shader progs can handle this because the mapped surfaces do not have to be blended in
00253        //if(fp->material != k /* || (Mapped && fp->imagemap >= 0) */ || fp->material < 0)continue; //skip
00254        if(fp->material != k || (Mapped && fp->imagemap >= 0)  || fp->material < 0)continue; //skip
00255        v0=(MainVp+fp->V[0]); v1=(MainVp+fp->V[1]); v2=(MainVp+fp->V[2]);
00256        if(inview(v0) || inview(v1) || inview(v2)){
00257          if(Normalize(v0->xyz,v1->xyz,v2->xyz,n)){
00258            //fix_tangents(nt[fp->V[0]],nt[fp->V[1]],nt[fp->V[2]],ftng);
00259            for(j=0;j<3;j++){
00260              Vi=fp->V[j]; v=(MainVp+Vi);
00261              x=((GLfloat)(v->xyz[0]-TVpointX-TVsizeX/2))*scale;  mp[0]=(double)v->xyz[0];
00262              y=((GLfloat)(v->xyz[1]-TVpointY-TVsizeY/2))*scale;  mp[1]=(double)v->xyz[1];
00263              z=((GLfloat)(v->xyz[2]-TVpointZ-TVsizeZ/2))*scale;  mp[2]=(double)v->xyz[2];
00264              if(iMat[k].bSmooth){ /* smoothed */
00265                dot=DOT(nv[Vi],n);
00266                if(fabs(dot) < 0.5){
00267                  glNormal3f(n[0],n[2],-n[1]);
00268                  //SetAttributeVector(progID,"Tangent",ftng[j][0],ftng[j][2],-ftng[j][1]); 
00269                }
00270                else if(dot  < 0.0){
00271                  glNormal3f(-nv[Vi][0],-nv[Vi][2], nv[Vi][1]);
00272                  //SetAttributeVector(progID,"Tangent",ftng[j][0],-ftng[j][2],ftng[j][1]); 
00273                }
00274                else{
00275                  glNormal3f( nv[Vi][0], nv[Vi][2],-nv[Vi][1]);
00276                  //SetAttributeVector(progID,"Tangent",ftng[j][0],ftng[j][2],-ftng[j][1]); 
00277                }
00278              }
00279              else{/* not smoothed */
00280                glNormal3f( n[0], n[2],-n[1]);
00281                //SetAttributeVector(progID,"Tangent",ftng[j][0],ftng[j][2],-ftng[j][1]); 
00282              }
00283              GetRelativeCoord(mN,mX,mY,mP,mp, &uu, &vv, &ww);
00284              //SetAttributeVector(progID,"ShaderPosition",uu,ww,-vv);
00285              SetAttributeVector(progID,"ShaderPosition",uu,vv,ww);
00286              glVertex3f(x,z,-y);
00287            }
00288          }
00289        }
00290      }
00291      glEnd();
00292      UseShaderProgram(0); 
00293      // any material attributes that need to be undone ?
00294      if(iMat[k].transp > 0){ // Set transparent blending
00295        glDepthMask(GL_TRUE);
00296        glDisable(GL_BLEND);
00297      }
00298      if(matID == 8 ||matID == 9 ||matID == 13){
00299        glActiveTexture(GL_TEXTURE1);
00300        glBindTexture(GL_TEXTURE_2D,0);
00301        glActiveTexture(GL_TEXTURE0);
00302      }
00303      if(iMat[k].refl > 0){
00304        glActiveTexture(GL_TEXTURE0);
00305        glBindTexture(GL_TEXTURE_2D,0);
00306      }
00307      if(pass == 0){
00308        glActiveTexture(GL_TEXTURE1);  
00309        glBindTexture(GL_TEXTURE_3D,0);
00310        glDisable(GL_TEXTURE_3D);
00311        glEnable(GL_TEXTURE_2D);
00312      }
00313    }
00314    glEnable(GL_COLOR_MATERIAL);
00315  }
00316 
00317  // The mapping - Shader Progs don't need it to be blended so do it at the start
00318  // glEnable(GL_BLEND);
00319  // glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
00320  // if(Mapped && Nface > 0)DrawMappedPolysProg(scale,nv);
00321  // glDisable(GL_BLEND);
00322 
00323  glDisable(GL_LIGHTING);
00324  bThickWire=TRUE;
00325  if(bOverlayWire)DrawModelEdges();
00326  bThickWire=FALSE;
00327 
00328  glEndList();
00329  listID=1;
00330 
00331  X__Free(nv); // X__Free(nt);  // tangents are not used in the designer preview - give bad results
00332  return;
00333 }
00334 
00335 static void DrawMappedPolysProg(GLfloat scale, normal *nv){  
00336  GLfloat mixColour[4]={0.0,0.0,0.0,0.0};
00337  GLfloat x,y,z,n[3],
00338          dot;
00339  face *fp;
00340  vertex *v,*v1,*v2,*v0;
00341  int i,j,k,m,Vi;
00342  BOOL refmap;
00343  int brushID;
00344  vector mN,mX,mY,mP;
00345  GLfloat alpha[3],beta[3],tangent[3],binormal[3];
00346  GLfloat bc[4]={0.0,0.0,0.0,0.0};
00347 
00348  if(nImaps > 0)for(k=0;k<nImaps;k++){       // loop over all maps
00349    UseShaderProgram(4);   
00350    SetUniformInteger(4,"TwoSided",(int)TwoSided); 
00351    GetMapNormal(k,mP,mX,mY,mN);
00352    VECCOPY(mX,(GLfloat)tangent)
00353    VECCOPY(mY,(GLfloat)binormal)
00354    if(glMapList != NULL && k < NglMapList){
00355      refmap=FALSE;
00356      if(iMap[k].bTiled)SetUniformInteger(4,"bTiled",1);
00357      else              SetUniformInteger(4,"bTiled",0);
00358      if(iMap[k].bShaded)SetUniformInteger(4,"bShaded",1);
00359      else               SetUniformInteger(4,"bShaded",0);
00360      if(iMap[k].bDecal)SetUniformInteger(4,"bDecal",1);
00361      else              SetUniformInteger(4,"bDecal",0);
00362      glActiveTexture(GL_TEXTURE0);
00363      glBindTexture(GL_TEXTURE_2D,0);
00364      if(iMap[k].s == 1){    // .sp  
00365        SetUniformInteger(4,"bS",1);
00366        if(glMapList[k].bMovie)glBindTexture(GL_TEXTURE_2D,g_movie_texture);
00367        else if(glMapList[k].pixels != NULL){
00368          glBindTexture(GL_TEXTURE_2D,g_map_texture);
00369          TextureWithAlpha(glMapList[k].x,glMapList[k].y,glMapList[k].pixels,255,
00370          iMap[k].bDecal,iMap[k].k_colour[0],iMap[k].k_colour[1],iMap[k].k_colour[2]);
00371        }
00372        else glBindTexture(GL_TEXTURE_2D,g_check_texture);
00373        if(iMap[k].Map == PLANE_MOZIAC || iMap[k].Map == CYLINDER_MOZIAC){
00374            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT);
00375            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT);
00376        }
00377        else{
00378            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00379            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00380        }
00381        SetUniformVariable(4,"MixSurface",(GLfloat)iMap[k].sp*0.01);
00382        SetUniformInteger(4,"SurfaceMap",0); // texture unit 0
00383      }
00384      else SetUniformInteger(4,"bS",0);
00385 
00386      glActiveTexture(GL_TEXTURE1);
00387      glBindTexture(GL_TEXTURE_2D,0);
00388      if(iMap[k].r == 1){
00389        SetUniformInteger(4,"bR",1);
00390        if(glMapList[k].bMovieR){
00391          glBindTexture(GL_TEXTURE_2D,g_movie_texture);
00392        }
00393        else if(glMapList[k].pixelsR != NULL){
00394          glBindTexture(GL_TEXTURE_2D,g_ref_texture);
00395          glTexImage2D(GL_TEXTURE_2D,0,3,
00396                           glMapList[k].xR,glMapList[k].yR,
00397                           0,GL_RGB,GL_UNSIGNED_BYTE,
00398                           (GLvoid *)glMapList[k].pixelsR);
00399        }
00400        else glBindTexture(GL_TEXTURE_2D,g_check_texture);
00401        refmap=TRUE;
00402        SetUniformVariable(4,"MixRef",(GLfloat)iMap[k].rp*0.01);
00403        SetUniformInteger(4,"RefMap",1); // texture unit 1
00404      }
00405      else SetUniformInteger(4,"bR",0);
00406 
00407      glActiveTexture(GL_TEXTURE2);
00408      glBindTexture(GL_TEXTURE_2D,0);
00409      if(iMap[k].b == 1){   
00410        SetUniformInteger(4,"bB",1);
00411        if(glMapList[k].bMovie)glBindTexture(GL_TEXTURE_2D,g_movie_texture);
00412        else if(glMapList[k].pixelsB != NULL){
00413          glBindTexture(GL_TEXTURE_2D,g_bump_texture);
00414          glTexImage2D(GL_TEXTURE_2D,0,3,
00415                           glMapList[k].xB,glMapList[k].yB,
00416                           0,GL_RGB,GL_UNSIGNED_BYTE,
00417                           (GLvoid *)glMapList[k].pixelsB);
00418        }
00419        else glBindTexture(GL_TEXTURE_2D,g_check_texture);
00420        if(iMap[k].Map == PLANE_MOZIAC || iMap[k].Map == CYLINDER_MOZIAC){
00421            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT);
00422            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT);
00423        }
00424        else{
00425            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00426            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00427        }
00428        SetUniformVariable(4,"MixBump",(GLfloat)iMap[k].bp*0.01);
00429        SetUniformInteger(4,"BumpMap",2); // texture unit 2
00430      }
00431      else SetUniformInteger(4,"bB",0);
00432 
00433      glActiveTexture(GL_TEXTURE3);
00434      glBindTexture(GL_TEXTURE_2D,0);
00435      if(iMap[k].t == 1){ // Transparency map  // discard any Transparent pixels
00436        SetUniformInteger(4,"bT",1);
00437        if(glMapList[k].bMovie)glBindTexture(GL_TEXTURE_2D,g_movie_texture);
00438        else if(glMapList[k].pixelsT != NULL){
00439          glBindTexture(GL_TEXTURE_2D,g_tran_texture);
00440          glTexImage2D(GL_TEXTURE_2D,0,3,
00441                           glMapList[k].xT,glMapList[k].yT,
00442                           0,GL_RGB,GL_UNSIGNED_BYTE,
00443                           (GLvoid *)glMapList[k].pixelsT);
00444        }
00445        else glBindTexture(GL_TEXTURE_2D,g_check_texture);
00446        if(iMap[k].Map == PLANE_MOZIAC || iMap[k].Map == CYLINDER_MOZIAC){
00447          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT);
00448          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT);
00449        }
00450        else{
00451          glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00452          glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00453        }
00454        SetUniformInteger(4,"TransMap",3); // texture unit 3
00455      }
00456      else SetUniformInteger(4,"bT",0);
00457 
00458      // loop over all materials to get the border colour
00459      // any basic colour attributes will just appear as a grey border
00460      glActiveTexture(GL_TEXTURE0); 
00461      m = -1; 
00462      matloop:
00463      glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
00464      glEnable(GL_COLOR_MATERIAL);
00465      if(m >= 0){
00466        if(iMat[k].bShiny)SetUniformVariable(4,"SpecularContribution",1.0);
00467        else              SetUniformVariable(4,"SpecularContribution",0.0);
00468      }
00469      else SetUniformVariable(4,"SpecularContribution",0.5);
00470      glBegin(GL_TRIANGLES);
00471      fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++,fp++){
00472        if(fp->imagemap < 0)continue; /* if not mapped */
00473        if(m >= 0 && fp->material != m)continue; // not this material
00474        if(m == -1 && fp->material >= 0)continue; // or this basic one
00475        brushID=fp->imagemap;
00476        if(brushID != k)continue;         /* skip if not this map */
00477        if(m == -1)glColor4ub(fp->color[0],fp->color[1],fp->color[2],255);
00478        else       glColor4ub(iMat[m].mcolour1[0],iMat[m].mcolour1[1],iMat[m].mcolour1[2],255);
00479        v0=(MainVp+fp->V[0]); v1=(MainVp+fp->V[1]); v2=(MainVp+fp->V[2]);
00480        if(inview(v0) || inview(v1) || inview(v2)){
00481          if(Normalize(v0->xyz,v1->xyz,v2->xyz,n)){
00482            for(j=0;j<3;j++){
00483              Vi=fp->V[j]; v=(MainVp+Vi);
00484              if(fp->gp == TRUE){  // use face mapping coordinates
00485                alpha[j] = (GLfloat)(fp->x[j]); 
00486                beta[j]  = (GLfloat)(fp->y[j]); 
00487              }
00488              else if(iMap[k].Map == MAP_BY_VERTEX){
00489                alpha[j]=(GLfloat)v->x;
00490                beta[j]=(GLfloat)v->y;
00491              }
00492              else if(iMap[k].Map == MAP_SPHERICAL)
00493                   GetMappingCoordS(k,mN,mX,mY,mP,v->xyz,&(alpha[j]),&(beta[j]));
00494              else if(iMap[k].Map == CYLINDER || iMap[k].Map == CYLINDER_MOZIAC)
00495                   GetMappingCoordC(k,mN,mX,mY,mP,v->xyz,&(alpha[j]),&(beta[j]));
00496              else GetMappingCoordP(k,mN,mX,mY,mP,v->xyz,&(alpha[j]),&(beta[j]));
00497            }
00498            if(!fp->gp && (iMap[k].Map == CYLINDER || iMap[k].Map == CYLINDER_MOZIAC || iMap[k].Map == MAP_SPHERICAL)){
00499              FixUpMapEdge(alpha);
00500            }
00501            for(j=0;j<3;j++){
00502              Vi=fp->V[j]; v=(MainVp+Vi);
00503              x=((GLfloat)(v->xyz[0]-TVpointX-TVsizeX/2))*scale;
00504              y=((GLfloat)(v->xyz[1]-TVpointY-TVsizeY/2))*scale;
00505              z=((GLfloat)(v->xyz[2]-TVpointZ-TVsizeZ/2))*scale;
00506              if(fp->bSmooth){ /* smoothed */
00507                dot=DOT(nv[Vi],n);
00508                if(fabs(dot) < 0.5){
00509                  glNormal3f(n[0],n[2],-n[1]);
00510                  SetAttributeVector(4,"Tangent",tangent[0],tangent[2],-tangent[1]); 
00511                  SetAttributeVector(4,"Binormal",binormal[0],binormal[2],-binormal[1]); 
00512                }  
00513                else if(dot  < 0.0){
00514                  glNormal3f(-nv[Vi][0],-nv[Vi][2], nv[Vi][1]);
00515                  SetAttributeVector(4,"Tangent",tangent[0],-tangent[2],tangent[1]); 
00516                  SetAttributeVector(4,"Binormal",binormal[0],-binormal[2],binormal[1]); 
00517                }
00518                else{
00519                  glNormal3f( nv[Vi][0], nv[Vi][2],-nv[Vi][1]);
00520                  SetAttributeVector(4,"Tangent",tangent[0],tangent[2],-tangent[1]); 
00521                  SetAttributeVector(4,"Binormal",binormal[0],binormal[2],-binormal[1]); 
00522                }
00523              }
00524              else{/* not smoothed */
00525                glNormal3f( n[0], n[2],-n[1]);
00526                SetAttributeVector(4,"Tangent",tangent[0],tangent[2],-tangent[1]); 
00527                SetAttributeVector(4,"Binormal",binormal[0],binormal[2],-binormal[1]); 
00528              }
00529              if(!fp->gp && (iMap[k].Map == CYLINDER || iMap[k].Map == CYLINDER_MOZIAC))alpha[j] *= 360.0/(GLfloat)iMap[k].Angle;
00530              glMultiTexCoord2f(GL_TEXTURE0,alpha[j],beta[j]);  // for non reflective textures
00531              glVertex3f(x,z,-y);
00532            }
00533          }
00534        }
00535      }
00536      glEnd();
00537      glDisable(GL_COLOR_MATERIAL);
00538      m++;
00539      if(nMats > 0 && m >= 0 && m < nMats)goto matloop;
00540      glActiveTexture(GL_TEXTURE3); 
00541      glBindTexture(GL_TEXTURE_2D,0);
00542      glActiveTexture(GL_TEXTURE2); 
00543      glBindTexture(GL_TEXTURE_2D,0);
00544      glActiveTexture(GL_TEXTURE1); 
00545      glBindTexture(GL_TEXTURE_2D,0);
00546      glActiveTexture(GL_TEXTURE0); 
00547      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00548      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00549      glBindTexture(GL_TEXTURE_2D,0);
00550    } // valid map list
00551    UseShaderProgram(0);   
00552  }   // each map
00553 }
00554 
00555 
00556 
00557 #define TOL 1.e-4;
00558 
00559 static void GetRelativeCoord(vector n, vector x, vector y, vector pb, vector pf,
00560                 GLfloat * a, GLfloat * b, GLfloat *c){
00561  /* n        is normal to plane of axis
00562     x & y    are vectors along the edges of the map  x= left y = down
00563     pb       is position vector to base point on map
00564     fp       is position vector to vertex to be mapped
00565     a & b    are output of mapping coordinates [0 - 1]
00566  */
00567  int k;
00568  vector v1,p;
00569  GLfloat lg;
00570  GLfloat mu,dm,detmax,det1,det2,det3,ve1,ve2,ve3,vp1,vp2,vp3,p1,p2,p3;
00571  VECSUB(pb,pf,v1)
00572  mu=DOT(n,v1);
00573  VECSCALE(mu,n,v1)
00574  VECSUM(pf,v1,p)
00575  ve1=x[0]; ve2=x[1]; ve3=x[2];
00576  vp1=y[0]; vp2=y[1]; vp3=y[2];
00577  p1=p[0]-pb[0];
00578  p2=p[1]-pb[1];
00579  p3=p[2]-pb[2];
00580  det1=ve1*vp2-vp1*ve2;
00581  det2=ve1*vp3-vp1*ve3;
00582  det3=ve2*vp3-vp2*ve3;
00583  k=0; detmax=TOL;
00584  if((dm=fabs(det1)) > detmax){k=1; detmax=dm;}
00585  if((dm=fabs(det2)) > detmax){k=2; detmax=dm;}
00586  if((dm=fabs(det3)) > detmax){k=3; detmax=dm;}
00587  if(k == 1){
00588    *a=( vp2*p1-vp1*p2)/det1;
00589    *b=(-ve2*p1+ve1*p2)/det1;
00590  }
00591  else if(k == 2){
00592    *a=( vp3*p1-vp1*p3)/det2;
00593    *b=(-ve3*p1+ve1*p3)/det2;
00594  }
00595  else if(k == 3){
00596    *a=( vp3*p2-vp2*p3)/det3;
00597    *b=(-ve3*p2+ve2*p3)/det3;
00598  }
00599  else {
00600    *a = *b = 0.0;
00601  }
00602  lg = max(1.0,sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2]));
00603  *c = -mu / lg;
00604 }
00605 
00606 static void GetTextureNormal(int k, vector mP, vector mX, vector mY,
00607                          vector mN){
00608  GLfloat n[3];
00609  VECCOPY((double)iMat[k].ax.P,mP)
00610  VECSUB((double)iMat[k].ax.X,mP,mX)
00611  VECSUB((double)iMat[k].ax.Y,mP,mY)
00612  CROSS(mX,mY,mN)
00613  VECCOPY((GLfloat)mN,n)
00614  if(!normalise(n))MessageBeep(MB_OK);
00615  VECCOPY((double)n,mN)
00616  return;
00617 }
00618 
00619 static void fix_tangents(normal t0, normal t1, normal t2, normal *tng){
00620  VECCOPY(t0,tng[0])
00621  if(DOT(t0,t1) > 0) VECCOPY(t1,tng[1]) else VECSCALE(-1,t1,tng[1]);
00622  if(DOT(t0,t2) < 0) VECCOPY(t2,tng[2]) else VECSCALE(-1,t2,tng[2]);
00623 }
00624 
00625 #if 0
00626 //glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,mc);
00627 //         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00628 //         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00629 //         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00630 //         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00631 //{
00632 //static float CC[4]={0.0,1.0,0.0,0.4};
00633 //glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
00634 //glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,CC);
00635 //glTexEnvf(GL_TEXTURE_ENV,GL_SRC2_RGB,GL_CONSTANT);
00636 //glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND2_RGB,GL_SRC_ALPHA);
00637 //}
00638 TextureWithAlphaAndBorder(long x, long y, unsigned char *pin){   // border only for testing
00639   unsigned char *pout,*p;
00640   long i,j;
00641   pout=X__Malloc((x+2)*(y+2)*4); p=pout; memset(pout,255,(x+2)*(y+2)*4);
00642   p += (x+3)*4;
00643   for(i=0;i<y;i++){
00644     for(j=0;j<x;j++){
00645      *p++ = *pin++;
00646      *p++ = *pin++;
00647      *p++ = *pin++;
00648      *p++ = 255;
00649     }
00650     p += 2*4;
00651   }
00652   glTexImage2D(GL_TEXTURE_2D,0,4,x+2,y+2,1,GL_RGBA,GL_UNSIGNED_BYTE,(GLvoid *)pout);
00653   X__Free(pout);
00654 }
00655 
00657 static void DrawMappedPolyAlphaSurface(GLfloat scale, normal *nv){ // for debugging only
00658  GLfloat x,y,z,n[3],dot;
00659  face *fp;
00660  vertex *v,*v1,*v2,*v0;
00661  int i,j,k,m,Vi;
00662  BOOL refmap;
00663  int brushID;
00664  vector mN,mX,mY,mP;
00665  GLfloat alpha[3],beta[3];
00666  GLfloat bc[4];
00667 
00668  if(nImaps > 0)for(k=0;k<nImaps;k++){       // loop over all maps
00669    GetMapNormal(k,mP,mX,mY,mN);
00670    if(glMapList != NULL && k < NglMapList){
00671      refmap=FALSE;
00672      glBindTexture(GL_TEXTURE_2D,0);
00673      if(iMap[k].s == 1){    // .sp  
00674        if(glMapList[k].bMovie)glBindTexture(GL_TEXTURE_2D,g_movie_texture);
00675        else if(glMapList[k].pixels != NULL){
00676          glBindTexture(GL_TEXTURE_2D,g_map_texture);
00677          TextureWithAlpha(glMapList[k].x,glMapList[k].y,glMapList[k].pixels,255,
00678          iMap[k].bDecal,iMap[k].k_colour[0],iMap[k].k_colour[1],iMap[k].k_colour[2]);
00679        }
00680        else glBindTexture(GL_TEXTURE_2D,g_check_texture);
00681        if(iMap[k].bTiled){
00682          if(iMap[k].Map == PLANE_MOZIAC || iMap[k].Map == CYLINDER_MOZIAC){
00683            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT);
00684            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT);
00685          }
00686          else{
00687            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00688            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00689          }
00690        }
00691        else{
00692          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
00693          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
00694        } 
00695        glTexEnvf(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_REPLACE);
00696      }
00697      glEnable(GL_COLOR_MATERIAL);
00698      glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
00699      glColor4f(1.0,1.0,1.0,1.0);
00700      m = -1; 
00701      matloop:
00702      glBegin(GL_TRIANGLES);
00703      fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++,fp++){
00704        if(fp->imagemap < 0)continue; /* if not mapped */
00705        if(m >= 0 && fp->material != m)continue; // not this material
00706        if(m == -1 && fp->material >= 0)continue; // or this basic one
00707        brushID=fp->imagemap;
00708        if(brushID != k)continue;         /* skip if not this map */
00709        v0=(MainVp+fp->V[0]); v1=(MainVp+fp->V[1]); v2=(MainVp+fp->V[2]);
00710        if(inview(v0) || inview(v1) || inview(v2)){
00711          if(Normalize(v0->xyz,v1->xyz,v2->xyz,n)){
00712            for(j=0;j<3;j++){
00713              Vi=fp->V[j]; v=(MainVp+Vi);
00714              if(fp->gp == TRUE){  // use face mapping coordinates
00715                alpha[j] = (GLfloat)(fp->x[j]); 
00716                beta[j]  = (GLfloat)(fp->y[j]); 
00717              }
00718              else if(iMap[k].Map == MAP_BY_VERTEX){
00719                alpha[j]=(GLfloat)v->x;
00720                beta[j]=(GLfloat)v->y;
00721              }
00722              else if(iMap[k].Map == MAP_SPHERICAL)
00723                   GetMappingCoordS(k,mN,mX,mY,mP,v->xyz,&(alpha[j]),&(beta[j]));
00724              else if(iMap[k].Map == CYLINDER || iMap[k].Map == CYLINDER_MOZIAC)
00725                   GetMappingCoordC(k,mN,mX,mY,mP,v->xyz,&(alpha[j]),&(beta[j]));
00726              else GetMappingCoordP(k,mN,mX,mY,mP,v->xyz,&(alpha[j]),&(beta[j]));
00727            }
00728            if(!fp->gp && (iMap[k].Map == CYLINDER || iMap[k].Map == CYLINDER_MOZIAC || iMap[k].Map == MAP_SPHERICAL)){
00729              FixUpMapEdge(alpha);
00730            }
00731            for(j=0;j<3;j++){
00732              Vi=fp->V[j]; v=(MainVp+Vi);
00733              x=((GLfloat)(v->xyz[0]-TVpointX-TVsizeX/2))*scale;
00734              y=((GLfloat)(v->xyz[1]-TVpointY-TVsizeY/2))*scale;
00735              z=((GLfloat)(v->xyz[2]-TVpointZ-TVsizeZ/2))*scale;
00736              if(fp->bSmooth){ /* smoothed */
00737                dot=DOT(nv[Vi],n);
00738                if(fabs(dot) < 0.5)glNormal3f(n[0],n[2],-n[1]);
00739                else if(dot  < 0.0)glNormal3f(-nv[Vi][0],-nv[Vi][2], nv[Vi][1]);
00740                else               glNormal3f( nv[Vi][0], nv[Vi][2],-nv[Vi][1]);
00741              }
00742              else{/* not smoothed */
00743                glNormal3f( n[0], n[2],-n[1]);
00744              }
00745              if(!fp->gp && (iMap[k].Map == CYLINDER || iMap[k].Map == CYLINDER_MOZIAC))alpha[j] *= 360.0/(GLfloat)iMap[k].Angle;
00746              glTexCoord2f(alpha[j],beta[j]);
00747              glVertex3f(x,z,-y);
00748            }
00749          }
00750        }
00751      }
00752      glEnd();
00753      m++;
00754      if(nMats > 0 && m >= 0 && m < nMats)goto matloop;
00755      glEnable(GL_COLOR_MATERIAL);
00756      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00757      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00758      glBindTexture(GL_TEXTURE_2D,0);
00759    } // valid map list
00760  }   // each map
00761 }
00762 
00764            tangent[0] =  mX[0];
00765            tangent[1] =  mX[2];
00766            tangent[2] = -mX[1];
00767            // pass the tangent vector to the shader as a vertex attribute.
00768            glVertexAttrib3f(1,tangent[0],tangent[1],tangent[2]);
00769 
00771 
00772  fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++){  // calculate the surface normals
00773    V[0]=fp->V[0]; V[1]=fp->V[1]; V[2]=fp->V[2];
00774    v0=(MainVp+V[0]); v1=(MainVp+V[1]); v2=(MainVp+V[2]);
00775    if(inview(v0) || inview(v1) || inview(v2)){
00776      if(Normalize(v0->xyz,v1->xyz,v2->xyz,n)){
00777        for(j=0;j<3;j++){
00778          dot=DOT(nv[V[j]],n);
00779          if(fabs(dot) < 1.e-10){
00780            VECCOPY(n,nv[V[j]])
00781          }
00782          else if(dot >  0.5){
00783            VECSUM(nv[V[j]],n,nv[V[j]])
00784          }
00785          else if(dot < -0.5){
00786            VECSUB(nv[V[j]],n,nv[V[j]])
00787          }
00788        }
00789      }
00790    }
00791    fp++;
00792  }
00793  if(Nvert > 0)for(i=0;i<Nvert;i++)normalise(nv[i]);
00794 
00795 
00796 
00797 #endif

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