gldesign1_old.c

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 2,0 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000 - 2007 OpenFX Development Team
00004 -- */
00005 
00006 /* file GLDESIGN1.C  The DLL that provided OpenGL support for the designer */
00007 
00008 #define _DSCRUCT_SUB 1
00009 
00010 #include "gldesign1.h"
00011 
00012 extern unsigned char *LoadMAP(char *InFile, long *xx,long *yy);
00013 extern void ShadersInit(char *);
00014 extern void UseShaderProgram(long id);
00015 
00016 
00017 #define MAPDELTA 0.3333333
00018 
00019 extern GLfloat up_angle,round_angle,scale_view;
00020 extern GLfloat gbRed,gbGreen,gbBlue;
00021 extern GLfloat gwRed,gwGreen,gwBlue;
00022 extern GLfloat near_plane,far_plane;
00023 extern GLint listID,mode,flat,bounding_box,current_map;
00024 extern BOOL  Mapped,Update,Fastest,Clamped,
00025       Cmaterial,AttenuateLight,TwoSided,
00026       ScrollBars,bDrawMapping,bOverlayWire,
00027       bThickWire,bNurbsWireOnly,
00028       bStereo,bStereoDraw;
00029 extern char gszBMPfile[],gszBMPdir[],gszRootDir[];
00030 extern GLMAP    *glMapList;
00031 extern long     NglMapList;
00032 
00033 extern GLuint g_check_texture;
00034 extern GLuint g_map_texture;
00035 extern GLuint g_movie_texture;
00036 extern GLuint g_bump_texture;
00037 extern GLubyte checkImage[checkImageWidth][checkImageHeight][3];
00038 
00039 void PrepareStereo(double, double, double, double, 
00040                    double, double, double, double, 
00041                    double, double, double);
00042 void Make3dDisplayList(void);
00043 void DrawGlNurbs(GLfloat);
00044 void DrawProjectMapRectangle(void);
00045 void makeCheckImageMap(int id);
00046 void GetMappingCoordS(int id, vector n, vector dx, vector dy, vector p0, long *pv,
00047                  GLfloat * a, GLfloat * b);
00048 void GetMappingCoordP(int id, vector n, vector x, vector y, vector p0,
00049                              long *pv,
00050                              GLfloat *a, GLfloat *b);
00051 void GetMappingCoordC(int id, vector n, vector x, vector y, vector p0,
00052                 long *pv,
00053                 GLfloat *a, GLfloat *b);
00054 void GetMapNormal(int k, vector mP, vector mX, vector mY,
00055                          vector mN);
00056 static BOOL normalise(GLfloat *v);
00057 static BOOL Normalize(point x,point y,point z,GLfloat *n);
00058 static BOOL inview(vertex  *vp);
00059 static BOOL same_color(unsigned char *color);
00060 static void  FixUpMapEdge(GLfloat alpha[]);
00061 
00062 static RECT oldrect;
00063 
00064 
00065 BOOL bSetupPixelFormat(HDC hDC){
00066  static PIXELFORMATDESCRIPTOR pfd = {
00067    sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd
00068    1,                              // version number
00069    PFD_DRAW_TO_WINDOW |            // support window
00070    PFD_SUPPORT_OPENGL |            // support OpenGL
00071    PFD_DOUBLEBUFFER,               // double buffered
00072    PFD_TYPE_RGBA,                  // RGBA type
00073    24,                             // 24-bit color depth
00074    0, 0, 0, 0, 0, 0,               // color bits ignored
00075    0,                              // no alpha buffer
00076    0,                              // shift bit ignored
00077    0,                              // no accumulation buffer
00078    0, 0, 0, 0,                     // accum bits ignored
00079    32,                             // 32-bit z-buffer
00080    0,                              // no stencil buffer
00081    0,                              // no auxiliary buffer
00082    PFD_MAIN_PLANE,                 // main layer
00083    0,                              // reserved
00084    0, 0, 0                         // layer masks ignored
00085  };
00086  int pixelformat;
00087  if (bStereo){
00088    pfd.dwFlags |= PFD_STEREO;
00089  }
00090  if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ){
00091    MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK);
00092    return FALSE;
00093  }
00094  if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE) {
00095    MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK);
00096    return FALSE;
00097  }
00098  if (bStereo){
00099    pixelformat = GetPixelFormat (hDC);
00100    DescribePixelFormat (hDC, pixelformat, sizeof (PIXELFORMATDESCRIPTOR), &pfd);
00101    if (!(pfd.dwFlags & PFD_STEREO)){
00102      MessageBox (NULL, "GLDESIGN.DLL: Stereo mode not supported by this hardware.", "Stereo init error", MB_OK | MB_ICONINFORMATION);
00103      bStereoDraw=FALSE;
00104    }
00105    else bStereoDraw=TRUE;
00106  }
00107  return TRUE;
00108 }
00109 
00110 
00111 void SetMappingQuality(void){
00112  GLfloat parameter3[]={GL_SPHERE_MAP};
00113  if(Clamped){
00114    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00115    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00116  }
00117  else{
00118    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00119    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00120  }
00121  if(Fastest)glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_FASTEST);
00122  else       glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
00123  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00124  //To allow for reflection mapping
00125  glTexGenfv(GL_S,GL_TEXTURE_GEN_MODE,parameter3);  
00126  glTexGenfv(GL_T,GL_TEXTURE_GEN_MODE,parameter3);
00127 
00128  // We MUST tell OGL how the map is to be applied !!!!!!!!
00129  // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00130  // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00131  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00132  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00133 }
00134 
00135 static void makeCheckImageMap(int id){
00136  int i, j, c;
00137  if(id == 0){ /* simple checkered map */
00138    for (i = 0; i < checkImageWidth; i++) {
00139      for (j = 0; j < checkImageHeight; j++) {
00140        c = ((((i&0x8)==0)^((j&0x8))==0))*255;
00141        checkImage[i][j][0] = (GLubyte) c;
00142        checkImage[i][j][1] = (GLubyte) c;
00143        checkImage[i][j][2] = (GLubyte) c;
00144      }
00145    }
00146  }
00147 }
00148 
00149 GLvoid initialize(HWND hWnd){
00150  GLfloat   aspect;
00151  GLfloat d[]={1.0,1.0,1.0,1.0};
00152  GLfloat a[]={0.2,0.2,0.2,1.0};
00153  GLfloat s[]={1.0,1.0,1.0,1.0};
00154  GLfloat p[]={0.0,0.0,1.0,0.0};
00155  unsigned char *movie_image=NULL,movie_file[256];
00156  long movie_image_x,movie_image_y;
00157  ShadersInit(gszRootDir);
00158  if(AttenuateLight)p[3]=1.0;
00159  else              p[3]=0.0;
00160  GetClientRect(hWnd, &oldrect);
00161  glClearColor(gbRed,gbGreen,gbBlue,1.0);
00162  glMatrixMode(GL_PROJECTION);
00163  aspect = (GLfloat) oldrect.right / oldrect.bottom;;
00164  near_plane = 1.5; far_plane = 9.5;
00165  gluPerspective( 45.0, aspect, near_plane, far_plane);
00166  glMatrixMode( GL_MODELVIEW );
00167  glLoadIdentity();
00168  glClearDepth(1.0);
00169  glEnable(GL_DEPTH_TEST);
00170  if(TwoSided)glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
00171  else        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE);
00172  glEnable(GL_LIGHT0);
00173  glLightfv(GL_LIGHT0,GL_DIFFUSE,d);
00174  glLightfv(GL_LIGHT0,GL_AMBIENT,a);
00175  glLightfv(GL_LIGHT0,GL_SPECULAR,s);
00176  glLightfv(GL_LIGHT0,GL_POSITION,p);
00177  glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.15);
00178  glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.05);
00179  glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
00180  // make the dummy texture for missing maps
00181  glBindTexture(GL_TEXTURE_2D,g_check_texture);
00182  makeCheckImageMap(0);
00183  glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
00184               checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
00185               &checkImage[0][0][0]);
00186  SetMappingQuality(); // REQUIRED 
00187  // put something in the texture - needed before making display list
00188  glBindTexture(GL_TEXTURE_2D,g_map_texture);
00189  glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
00190               checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
00191               &checkImage[0][0][0]);
00192  SetMappingQuality(); // THIS IS NEEDED -see function
00193  glBindTexture(GL_TEXTURE_2D,g_bump_texture);
00194  glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
00195               checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
00196               &checkImage[0][0][0]);
00197  SetMappingQuality(); // THIS IS NEEDED -see function
00198  strcpy(movie_file,gszRootDir); strcat(movie_file,"movie.bmp");
00199  if((movie_image=LoadMAP(movie_file,&movie_image_x,&movie_image_y)) != NULL){
00200    glBindTexture(GL_TEXTURE_2D,g_movie_texture);
00201    glTexImage2D(GL_TEXTURE_2D,0,3,
00202                           movie_image_x,movie_image_y,
00203                           0,GL_RGB,GL_UNSIGNED_BYTE,
00204                           (GLvoid *)movie_image);
00205    SetMappingQuality(); // THIS IS NEEDED -see function
00206    X__Free(movie_image);
00207  }
00208  glBindTexture(GL_TEXTURE_2D,0);
00209 }
00210 
00211 void PrepareStereo(double dfLeftBorder, double dfRightBorder, 
00212     double dfBottomBorder, double dfTopBorder, double dfNearBorder, 
00213     double dfFarBorder, double dfTargetPlane, double dfCameraToTargetDistance, 
00214     double dfStereoMagnitudeAdj, double dfParallaxBalanceAdj, 
00215     double dfEyePosition){
00216     double dfXRange, dfYRange;
00217     double dfXMidpoint, dfYMidpoint;
00218     double dfCameraPlane;
00219     double dfNearClipDistance, dfFarClipDistance;
00220     double dfStereoCameraOffset;
00221     double dfFrustumAsymmetry;
00222     double n_over_d;
00223     double FrustumTop, FrustumBottom, FrustumLeft, FrustumRight;
00224 
00225     // the X & Y axis ranges, in the target Z plane
00226     dfXRange = dfRightBorder - dfLeftBorder;
00227     dfYRange = dfTopBorder - dfBottomBorder;  
00228 
00229     // midpoints of the X & Y axis ranges
00230     dfXMidpoint = (dfRightBorder + dfLeftBorder) / 2.0;  
00231     dfYMidpoint = (dfTopBorder + dfBottomBorder) / 2.0;  
00232 
00233     // convert clipping plane positions to distances in front of camera
00234     dfCameraPlane = dfTargetPlane + dfCameraToTargetDistance;
00235     dfNearClipDistance = dfCameraPlane - dfNearBorder;
00236     dfFarClipDistance  = dfCameraPlane - dfFarBorder;
00237 
00238     // Determine the stereoscopic camera offset. A good rule of thumb is 
00239     //      for the overall camera separation to equal about 7% of the 
00240     //      window's X-axis range in the XY-plane of the target 
00241     //      ("target" being mid-object or the center of interest in the 
00242     //      scene). 
00243     dfStereoCameraOffset = dfXRange * STEREO_MAGNITUDE_CONSTANT * 
00244         dfStereoMagnitudeAdj;
00245     dfStereoCameraOffset /= 2.0;  // offset each camera by half the overall sep
00246     dfStereoCameraOffset *= dfEyePosition; 
00247             
00248     // Determine the amount by which the projection frustum will be made
00249     //      asymmetrical in order to affect a nice parallax balance between
00250     //      negative parallax (popping out of the display) and positive 
00251     //      parallax (residing behind the display surface). With no frustum
00252     //      asymmetry, everything resides in negative parallax.
00253     dfFrustumAsymmetry = -dfStereoCameraOffset * dfParallaxBalanceAdj;
00254 
00255     // since glFrustum() maps the window borders based on the near clipping 
00256     //      plane rather than the target plane, X and Y range values need 
00257     //      to be adjusted by the ratio of those two distances
00258     n_over_d = dfNearClipDistance / dfCameraToTargetDistance;
00259     dfXRange *= n_over_d;
00260     dfYRange *= n_over_d;
00261     dfFrustumAsymmetry *= n_over_d;
00262             
00263     // determine the shape of the projection frustum; note that if 
00264     //      FrustumRight doesn't equal -FrustumLeft, that makes this an
00265     //      asymmetric frustum projection
00266     FrustumTop = dfYRange / 2.0;
00267     FrustumBottom = -dfYRange / 2.0;
00268     FrustumRight = (dfXRange / 2.0) + dfFrustumAsymmetry;
00269     FrustumLeft = (-dfXRange / 2.0) + dfFrustumAsymmetry;
00270 
00271     // glMatrixMode(GL_PROJECTION) needs to have been called already
00272 
00273     glLoadIdentity();  // obtain a vanilla trans matrix to modify
00274 
00275     // this matrix transformation performs the actual persp projection
00276     glFrustum (FrustumLeft, FrustumRight, FrustumBottom, FrustumTop, 
00277         dfNearClipDistance, dfFarClipDistance);
00278 
00279     // this matrix transformation does two things: Translates the stereo 
00280     //      camera towards the left (left camera) or the right (right 
00281     //      camera), and also offsets the entire geometry such that the 
00282     //      virtual camera is at (0.0, 0.0, 0.0) where glFrustum() expects 
00283     //      it to be
00284     glTranslated (-dfXMidpoint - dfStereoCameraOffset, -dfYMidpoint, 
00285         -dfCameraPlane);
00286 }
00287 
00288 GLvoid drawScene(HWND hWnd,BOOL shaded){
00289  HDC hDC;
00290  if (bStereoDraw){
00291     glFlush ();
00292     glDrawBuffer (GL_BACK);
00293     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00294     glDrawBuffer (GL_BACK_LEFT);
00295     glMatrixMode (GL_PROJECTION);
00296     glLoadIdentity ();
00297         glTranslated (0.0, 0.0, 2.0);
00298           PrepareStereo(-3.2, 3.2, -2.4, 2.4, 8.0, -8.0,//3.0, -3.0, // X,Y,Z coord range
00299                         1.0, 14.5,//1.75, 14.5, //Z-coord of zero-parallax "target", camera-target dist
00300                         STEREO_MAGNITUDE_ADJUSTMENT, PARALLAX_BALANCE_ADJUSTMENT, 
00301                         -1.0);  // left eye position
00302     glMatrixMode (GL_MODELVIEW);
00303     glLoadIdentity ();
00304     glRotatef(up_angle,1.0,0.0,0.0);
00305     glRotatef(round_angle,0.0,1.0,0.0);
00306     glScalef(scale_view,scale_view,scale_view);
00307     glCallList(1);
00308     if(bDrawMapping)DrawProjectMapRectangle();
00309     glPopMatrix ();
00310     glClear (GL_DEPTH_BUFFER_BIT);
00311     glFlush ();
00312     glDrawBuffer (GL_BACK_RIGHT);
00313     glMatrixMode (GL_PROJECTION);    
00314         glLoadIdentity ();
00315         glTranslated (0.0, 0.0, 2.0);
00316         PrepareStereo(-3.2, 3.2, -2.4, 2.4, 8.0, -8.0,//3.0, -3.0, // X,Y,Z coord range
00317             1.0, 14.5,//1.75, 14.5, //Z-coord of zero-parallax "target", camera-target dist
00318             STEREO_MAGNITUDE_ADJUSTMENT, PARALLAX_BALANCE_ADJUSTMENT, 
00319             1.0);  // right eye position
00320     glMatrixMode (GL_MODELVIEW);
00321     glCallList(1);
00322     if(bDrawMapping)DrawProjectMapRectangle();
00323     glPopMatrix ();
00324      glFinish();
00325      hDC = wglGetCurrentDC();
00326     SwapBuffers(hDC);
00327  }
00328  else{
00329    glDrawBuffer(GL_BACK);
00330    // glDrawBuffer(GL_FRONT);
00331    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00332    if(flat)glShadeModel(GL_FLAT);
00333    else    glShadeModel(GL_SMOOTH);
00334    glPushMatrix();
00335    glLoadIdentity();
00336    glTranslatef(0.0, 0.0, -5.0);
00337    glRotatef(up_angle,1.0,0.0,0.0);
00338    glRotatef(round_angle,0.0,1.0,0.0);
00339    glScalef(scale_view,scale_view,scale_view);
00340    glCallList(1);
00341    if(bDrawMapping)DrawProjectMapRectangle();
00342    glPopMatrix();
00343    glFinish();
00344    hDC = wglGetCurrentDC();
00345    SwapBuffers(hDC);
00346  }
00347  return;
00348 }
00349 
00350 GLvoid resize(HWND hWnd){
00351  RECT    rect;
00352  GLfloat aspect;
00353  GetClientRect(hWnd, &rect);
00354  glViewport(0, 0, rect.right, rect.bottom);
00355  /* don't paint here */
00356  oldrect.right = rect.right;
00357  oldrect.bottom = rect.bottom;
00358  glMatrixMode(GL_PROJECTION);
00359  glLoadIdentity();
00360  aspect = (GLfloat) oldrect.right / oldrect.bottom;
00361  gluPerspective( 45.0, aspect, near_plane, far_plane);
00362  glMatrixMode( GL_MODELVIEW );
00363  glLoadIdentity();
00364 }
00365 
00366 void DrawProjectMapRectangle(void){
00367  long i;
00368  GLfloat x1,y1,z1,x2,y2,z2,scale,dscale=0.05;
00369  point dx,dy,d;
00370  if(nImaps > 0 && current_map < nImaps){
00371    glPushMatrix();
00372    i=current_map;
00373    scale=4.0/TVsizeX;
00374    VECSUB(iMap[i].X,iMap[i].P,dx)
00375    VECSUB(iMap[i].Y,iMap[i].P,dy)
00376    VECSUM(iMap[i].X,dy,d)
00377    // Transparent
00378    glEnable(GL_BLEND);
00379    glDepthMask(GL_FALSE);
00380    glBlendFunc(GL_SRC_ALPHA,GL_ONE);
00381    glColor4f(1.0, 1.0, 1.0,0.3);
00382    glBegin(GL_QUADS);
00383    x1=((GLfloat)(iMap[i].P[0]-TVpointX-TVsizeX/2))*scale;
00384    y1=((GLfloat)(iMap[i].P[1]-TVpointY-TVsizeY/2))*scale;
00385    z1=((GLfloat)(iMap[i].P[2]-TVpointZ-TVsizeZ/2))*scale;
00386    glVertex3f(x1,z1,-y1);
00387    x1=((GLfloat)(iMap[i].X[0]-TVpointX-TVsizeX/2))*scale;
00388    y1=((GLfloat)(iMap[i].X[1]-TVpointY-TVsizeY/2))*scale;
00389    z1=((GLfloat)(iMap[i].X[2]-TVpointZ-TVsizeZ/2))*scale;
00390    glVertex3f(x1,z1,-y1);
00391    x1=((GLfloat)(d[0]-TVpointX-TVsizeX/2))*scale;
00392    y1=((GLfloat)(d[1]-TVpointY-TVsizeY/2))*scale;
00393    z1=((GLfloat)(d[2]-TVpointZ-TVsizeZ/2))*scale;
00394    glVertex3f(x1,z1,-y1);
00395    x1=((GLfloat)(iMap[i].Y[0]-TVpointX-TVsizeX/2))*scale;
00396    y1=((GLfloat)(iMap[i].Y[1]-TVpointY-TVsizeY/2))*scale;
00397    z1=((GLfloat)(iMap[i].Y[2]-TVpointZ-TVsizeZ/2))*scale;
00398    glVertex3f(x1,z1,-y1);
00399    glEnd();
00400    glDepthMask(GL_TRUE);
00401    glDisable(GL_BLEND);
00402    //end transparent
00403    glLineWidth(4.0);
00404    glBegin(GL_LINES);
00405    glColor3f(0.0, 1.0, 0.0);
00406    x1=((GLfloat)(iMap[i].Y[0]-TVpointX-TVsizeX/2))*scale;
00407    y1=((GLfloat)(iMap[i].Y[1]-TVpointY-TVsizeY/2))*scale;
00408    z1=((GLfloat)(iMap[i].Y[2]-TVpointZ-TVsizeZ/2))*scale;
00409    x2=((GLfloat)(iMap[i].P[0]-TVpointX-TVsizeX/2))*scale;
00410    y2=((GLfloat)(iMap[i].P[1]-TVpointY-TVsizeY/2))*scale;
00411    z2=((GLfloat)(iMap[i].P[2]-TVpointZ-TVsizeZ/2))*scale;
00412    glVertex3f(x1,z1,-y1);
00413    glVertex3f(x2,z2,-y2);
00414    x1=((GLfloat)(iMap[i].X[0]-TVpointX-TVsizeX/2))*scale;
00415    y1=((GLfloat)(iMap[i].X[1]-TVpointY-TVsizeY/2))*scale;
00416    z1=((GLfloat)(iMap[i].X[2]-TVpointZ-TVsizeZ/2))*scale;
00417    glVertex3f(x2,z2,-y2);
00418    glVertex3f(x1,z1,-y1);
00419    x2=((GLfloat)(d[0]-TVpointX-TVsizeX/2))*scale;
00420    y2=((GLfloat)(d[1]-TVpointY-TVsizeY/2))*scale;
00421    z2=((GLfloat)(d[2]-TVpointZ-TVsizeZ/2))*scale;
00422    glEnd();
00423    glLineWidth(1.0);
00424    glBegin(GL_LINES);
00425    glVertex3f(x1,z1,-y1);
00426    glVertex3f(x2,z2,-y2);
00427    x1=((GLfloat)(iMap[i].Y[0]-TVpointX-TVsizeX/2))*scale;
00428    y1=((GLfloat)(iMap[i].Y[1]-TVpointY-TVsizeY/2))*scale;
00429    z1=((GLfloat)(iMap[i].Y[2]-TVpointZ-TVsizeZ/2))*scale;
00430    glVertex3f(x2,z2,-y2);
00431    glVertex3f(x1,z1,-y1);
00432    glEnd();
00433    VECSCALE(dscale,(GLfloat)dx,dx)
00434    VECSCALE(dscale,(GLfloat)dy,dy)
00435    glBegin(GL_LINE_LOOP);
00436    x1=((GLfloat)(iMap[i].P[0]-dx[0]-dy[0]-TVpointX-TVsizeX/2))*scale;
00437    y1=((GLfloat)(iMap[i].P[1]-dx[1]-dy[1]-TVpointY-TVsizeY/2))*scale;
00438    z1=((GLfloat)(iMap[i].P[2]-dx[2]-dy[2]-TVpointZ-TVsizeZ/2))*scale;
00439    glVertex3f(x1,z1,-y1);
00440    x1=((GLfloat)(iMap[i].P[0]+dx[0]-dy[0]-TVpointX-TVsizeX/2))*scale;
00441    y1=((GLfloat)(iMap[i].P[1]+dx[1]-dy[1]-TVpointY-TVsizeY/2))*scale;
00442    z1=((GLfloat)(iMap[i].P[2]+dx[2]-dy[2]-TVpointZ-TVsizeZ/2))*scale;
00443    glVertex3f(x1,z1,-y1);
00444    x1=((GLfloat)(iMap[i].P[0]+dx[0]+dy[0]-TVpointX-TVsizeX/2))*scale;
00445    y1=((GLfloat)(iMap[i].P[1]+dx[1]+dy[1]-TVpointY-TVsizeY/2))*scale;
00446    z1=((GLfloat)(iMap[i].P[2]+dx[2]+dy[2]-TVpointZ-TVsizeZ/2))*scale;
00447    glVertex3f(x1,z1,-y1);
00448    x1=((GLfloat)(iMap[i].P[0]-dx[0]+dy[0]-TVpointX-TVsizeX/2))*scale;
00449    y1=((GLfloat)(iMap[i].P[1]-dx[1]+dy[1]-TVpointY-TVsizeY/2))*scale;
00450    z1=((GLfloat)(iMap[i].P[2]-dx[2]+dy[2]-TVpointZ-TVsizeZ/2))*scale;
00451    glVertex3f(x1,z1,-y1);
00452    glEnd();
00453    glBegin(GL_LINE_LOOP);
00454    x1=((GLfloat)(iMap[i].Y[0]-dx[0]-dy[0]-TVpointX-TVsizeX/2))*scale;
00455    y1=((GLfloat)(iMap[i].Y[1]-dx[1]-dy[1]-TVpointY-TVsizeY/2))*scale;
00456    z1=((GLfloat)(iMap[i].Y[2]-dx[2]-dy[2]-TVpointZ-TVsizeZ/2))*scale;
00457    glVertex3f(x1,z1,-y1);
00458    x1=((GLfloat)(iMap[i].Y[0]+dx[0]-dy[0]-TVpointX-TVsizeX/2))*scale;
00459    y1=((GLfloat)(iMap[i].Y[1]+dx[1]-dy[1]-TVpointY-TVsizeY/2))*scale;
00460    z1=((GLfloat)(iMap[i].Y[2]+dx[2]-dy[2]-TVpointZ-TVsizeZ/2))*scale;
00461    glVertex3f(x1,z1,-y1);
00462    x1=((GLfloat)(iMap[i].Y[0]+dy[0]-TVpointX-TVsizeX/2))*scale;
00463    y1=((GLfloat)(iMap[i].Y[1]+dy[1]-TVpointY-TVsizeY/2))*scale;
00464    z1=((GLfloat)(iMap[i].Y[2]+dy[2]-TVpointZ-TVsizeZ/2))*scale;
00465    glVertex3f(x1,z1,-y1);
00466    glEnd();
00467    VECSCALE(0.5,(GLfloat)dx,dx)
00468    VECSCALE(0.5,(GLfloat)dy,dy)
00469    glBegin(GL_LINE_LOOP);
00470    x1=((GLfloat)(iMap[i].X[0]-dx[0]-dy[0]-TVpointX-TVsizeX/2))*scale;
00471    y1=((GLfloat)(iMap[i].X[1]-dx[1]-dy[1]-TVpointY-TVsizeY/2))*scale;
00472    z1=((GLfloat)(iMap[i].X[2]-dx[2]-dy[2]-TVpointZ-TVsizeZ/2))*scale;
00473    glVertex3f(x1,z1,-y1);
00474    x1=((GLfloat)(iMap[i].X[0]+dx[0]-dy[0]-TVpointX-TVsizeX/2))*scale;
00475    y1=((GLfloat)(iMap[i].X[1]+dx[1]-dy[1]-TVpointY-TVsizeY/2))*scale;
00476    z1=((GLfloat)(iMap[i].X[2]+dx[2]-dy[2]-TVpointZ-TVsizeZ/2))*scale;
00477    glVertex3f(x1,z1,-y1);
00478    x1=((GLfloat)(iMap[i].X[0]+dx[0]+dy[0]-TVpointX-TVsizeX/2))*scale;
00479    y1=((GLfloat)(iMap[i].X[1]+dx[1]+dy[1]-TVpointY-TVsizeY/2))*scale;
00480    z1=((GLfloat)(iMap[i].X[2]+dx[2]+dy[2]-TVpointZ-TVsizeZ/2))*scale;
00481    glVertex3f(x1,z1,-y1);
00482    x1=((GLfloat)(iMap[i].X[0]-dx[0]+dy[0]-TVpointX-TVsizeX/2))*scale;
00483    y1=((GLfloat)(iMap[i].X[1]-dx[1]+dy[1]-TVpointY-TVsizeY/2))*scale;
00484    z1=((GLfloat)(iMap[i].X[2]-dx[2]+dy[2]-TVpointZ-TVsizeZ/2))*scale;
00485    glVertex3f(x1,z1,-y1);
00486    glEnd();
00487    glLineWidth(1.0);
00488    glPopMatrix();
00489  }
00490  return;
00491 }
00492 
00493 void DrawModelEdges(void){
00494  GLfloat x,y,z,scale;
00495  edge *ep;
00496  vertex *v1,*v2;
00497  int i;
00498  if(Nedge == 0 && Nnurbs == 0)return;
00499  glPushMatrix();
00500  if(bThickWire)glLineWidth(2.0);
00501  else          glLineWidth(1.0);
00502  glBegin(GL_LINES);
00503  glColor3f(gwRed,gwGreen,gwBlue);
00504  scale=4.0/TVsizeX;
00505  ep=MainEp; if(Nedge > 0)for(i=0;i<Nedge;i++){
00506    v1=(MainVp+ep->V[0]);
00507    v2=(MainVp+ep->V[1]);
00508    x=((GLfloat)(v1->xyz[0]-TVpointX-TVsizeX/2))*scale;
00509    y=((GLfloat)(v1->xyz[1]-TVpointY-TVsizeY/2))*scale;
00510    z=((GLfloat)(v1->xyz[2]-TVpointZ-TVsizeZ/2))*scale;
00511    glVertex3f(x,z,-y);
00512    x=((GLfloat)(v2->xyz[0]-TVpointX-TVsizeX/2))*scale;
00513    y=((GLfloat)(v2->xyz[1]-TVpointY-TVsizeY/2))*scale;
00514    z=((GLfloat)(v2->xyz[2]-TVpointZ-TVsizeZ/2))*scale;
00515    glVertex3f(x,z,-y);
00516    ep++;
00517  }
00518  glEnd();
00519  glLineWidth(1.0);
00520  DrawGlNurbs(GLU_OUTLINE_PATCH);
00521  glPopMatrix();
00522 }
00523 
00524 #if 0
00525 TextureWithAlpha(long x, long y, unsigned char *pin){  // no border
00526   unsigned char *pout,*p;
00527   long i,j;
00528   pout=X__Malloc(x*y*4); p=pout;
00529   for(i=0;i<y;i++)for(j=0;j<x;j++){
00530     *p++ = *pin++;
00531     *p++ = *pin++;
00532     *p++ = *pin++;
00533     *p++ = 0;
00534   }
00535   glTexImage2D(GL_TEXTURE_2D,0,3,x,y,0,GL_RGBA,GL_UNSIGNED_BYTE,(GLvoid *)pout);
00536   X__Free(pout);
00537 }
00538 #elif 0
00539 TextureWithAlpha(long x, long y, unsigned char *pin){   // border
00540   unsigned char *pout,*p;
00541   long i,j;
00542   pout=X__Malloc((x+2)*(y+2)*4); p=pout; memset(pout,255,(x+2)*(y+2)*4);
00543   p += (x+3)*4;
00544   for(i=0;i<y;i++){
00545     for(j=0;j<x;j++){
00546      *p++ = *pin++;
00547      *p++ = *pin++;
00548      *p++ = *pin++;
00549      *p++ = 0;
00550     }
00551     p += 2*4;
00552   }
00553   glTexImage2D(GL_TEXTURE_2D,0,3,x+2,y+2,1,GL_RGBA,GL_UNSIGNED_BYTE,(GLvoid *)pout);
00554   X__Free(pout);
00555 }
00556 #endif
00557 
00558 void Make3dDisplayList(void){
00559  GLfloat x,y,z,scale,n[3],color[4],*spec_color,
00560          glos_color[]={1.0,1.0,1.0,1.0},
00561          dark_color[]={0.0,0.0,0.0,1.0},
00562          black[]={0.1,0.1,0.1,1.0},
00563          dull[]={0.0},
00564          shiny[]={100.0},dot;
00565  face *fp;
00566  vertex *v,*v1,*v2,*v0;
00567  normal *nv;
00568  int i,j,k,m,Vi,V[3];
00569  if(Nface == 0 && Nnurbs == 0){
00570    if(listID > 0){glDeleteLists(1,1);listID=0;}
00571    return;
00572  }
00573  if(Nvert > 0){
00574    if((nv=(normal *)X__Malloc(sizeof(normal)*Nvert)) == NULL){
00575      return;
00576    }
00577    for(i=0;i<Nvert;i++)nv[i][0]=nv[i][1]=nv[i][2]=0.0;
00578  }
00579  fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++){  // calculate the surface normals
00580    V[0]=fp->V[0]; V[1]=fp->V[1]; V[2]=fp->V[2];
00581    v0=(MainVp+V[0]); v1=(MainVp+V[1]); v2=(MainVp+V[2]);
00582    if(inview(v0) || inview(v1) || inview(v2)){
00583      if(Normalize(v0->xyz,v1->xyz,v2->xyz,n)){
00584        for(j=0;j<3;j++){
00585          dot=DOT(nv[V[j]],n);
00586          if(fabs(dot) < 1.e-10){
00587            VECCOPY(n,nv[V[j]])
00588          }
00589          else if(dot >  0.5){
00590            VECSUM(nv[V[j]],n,nv[V[j]])
00591 //           normalise(nv[V[j]]);
00592          }
00593          else if(dot < -0.5){
00594            VECSUB(nv[V[j]],n,nv[V[j]])
00595 //           normalise(nv[V[j]]);
00596          }
00597        }
00598      }
00599    }
00600    fp++;
00601  }
00602  if(Nvert > 0)for(i=0;i<Nvert;i++)normalise(nv[i]);
00603 
00604  if(listID > 0){glDeleteLists(1,1);listID=0;}
00605  glNewList(1,GL_COMPILE);
00606  
00607  //UseShaderProgram(1);  ///
00608 
00609  color[3]=1.0; color[0]=1.0; color[1]=1.0; color[2]=1.0;
00610  scale=4.0/TVsizeX;
00611  glEnable(GL_LIGHTING);
00612  // first draw the polygon with basic attributes only
00613  glEnable(GL_COLOR_MATERIAL);
00614  glBegin(GL_TRIANGLES);
00615  glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,shiny);
00616  glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,glos_color);
00617  fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++,fp++){
00618    if(Mapped && fp->imagemap >= 0)continue; // dont draw maps or
00619    if(fp->material  >= 0)continue;          // materials in this pass
00620    v0=(MainVp+fp->V[0]); v1=(MainVp+fp->V[1]); v2=(MainVp+fp->V[2]);
00621    if(inview(v0) || inview(v1) || inview(v2)){
00622        color[0]=(GLfloat)fp->color[0]/255.0;
00623        color[1]=(GLfloat)fp->color[1]/255.0;
00624        color[2]=(GLfloat)fp->color[2]/255.0;
00625        glColor4fv(color);
00626        //glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,color);
00627        if(Normalize(v0->xyz,v1->xyz,v2->xyz,n)){
00628          for(j=0;j<3;j++){
00629            Vi=fp->V[j]; v=(MainVp+Vi);
00630            x=((GLfloat)(v->xyz[0]-TVpointX-TVsizeX/2))*scale;
00631            y=((GLfloat)(v->xyz[1]-TVpointY-TVsizeY/2))*scale;
00632            z=((GLfloat)(v->xyz[2]-TVpointZ-TVsizeZ/2))*scale;
00633            if(fp->bSmooth){ /* smoothed */
00634              dot=DOT(nv[Vi],n);
00635              if(fabs(dot) < 0.5)glNormal3f(n[0],n[2],-n[1]);
00636              else if(dot  < 0.0)glNormal3f(-nv[Vi][0],-nv[Vi][2], nv[Vi][1]);
00637              else               glNormal3f( nv[Vi][0], nv[Vi][2],-nv[Vi][1]);
00638            }
00639            else{/* not smoothed */
00640              glNormal3f( n[0], n[2],-n[1]);
00641            }
00642            glVertex3f(x,z,-y);
00643          }
00644        }
00645    }
00646  }
00647  glEnd();
00648  glDisable(GL_COLOR_MATERIAL);
00649 
00650  //UseShaderProgram(0);  ///
00651 
00652  DrawGlNurbs(GLU_FILL);
00653 
00654  if(Mapped && Nface > 0){
00655    BOOL refmap;
00656    int brushID;
00657    vector mN,mX,mY,mP;
00658    GLfloat alpha[3],beta[3];
00659    GLfloat bc[4];
00660    //color[0]=1.0; color[1]=1.0; color[2]=1.0; color[3]=1.0;  // modulate colour - peank white
00661    color[0]=0.5; color[1]=0.5; color[2]=0.5; color[3]=1.0;  // modulate colour
00662    glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,color);
00663    spec_color=glos_color;
00664    glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,spec_color);
00665    glColor4f(color[0],color[1],color[2],color[3]);
00666    if(Nface > 0 && nImaps > 0)for(k=0;k<nImaps;k++){       // loop over all maps
00667      GetMapNormal(k,mP,mX,mY,mN);
00668      if(glMapList != NULL && k < NglMapList){
00670 
00671        if(glMapList[k].pixelsB != NULL){
00672 glActiveTexture(GL_TEXTURE1); //RSFx
00673          glBindTexture(GL_TEXTURE_2D,g_bump_texture);
00674          glTexImage2D(GL_TEXTURE_2D,0,3,
00675                           glMapList[k].xB,glMapList[k].yB,
00676                           0,GL_RGB,GL_UNSIGNED_BYTE,
00677                           (GLvoid *)glMapList[k].pixelsB);
00678 glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);  // for reflection
00679 glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
00680 glEnable(GL_TEXTURE_GEN_S);
00681 glEnable(GL_TEXTURE_GEN_T);
00682 #if 1
00683 {static GLfloat mixColour[4]={0.0,0.0,0.0,0.0};
00684 glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
00685 glTexEnvf(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_INTERPOLATE);
00686 glTexEnvf(GL_TEXTURE_ENV,GL_SRC0_RGB,GL_TEXTURE);
00687 glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);
00688 glTexEnvf(GL_TEXTURE_ENV,GL_SRC1_RGB,GL_PREVIOUS);
00689 glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND1_RGB,GL_SRC_COLOR);
00690 mixColour[3]=0.5;
00691 glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,mixColour);
00692 glTexEnvf(GL_TEXTURE_ENV,GL_SRC2_RGB,GL_CONSTANT);
00693 glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND2_RGB,GL_SRC_ALPHA);
00694 }
00695 #endif
00696 glActiveTexture(GL_TEXTURE0);
00697        }
00698 
00700        refmap=FALSE;
00701        if(glMapList[k].bMovie)glBindTexture(GL_TEXTURE_2D,g_movie_texture);
00702        else if(glMapList[k].bMovieR){
00703          glBindTexture(GL_TEXTURE_2D,g_movie_texture);
00704          glEnable(GL_TEXTURE_GEN_S);
00705          glEnable(GL_TEXTURE_GEN_T);
00706          refmap=TRUE;
00707        }
00708        else if(glMapList[k].pixelsR != NULL){
00709          glBindTexture(GL_TEXTURE_2D,g_map_texture);
00710          glTexImage2D(GL_TEXTURE_2D,0,3,
00711                           glMapList[k].xR,glMapList[k].yR,
00712                           0,GL_RGB,GL_UNSIGNED_BYTE,
00713                           (GLvoid *)glMapList[k].pixelsR);
00714          glEnable(GL_TEXTURE_GEN_S);
00715          glEnable(GL_TEXTURE_GEN_T);
00716          refmap=TRUE;
00717        }
00718        else if(glMapList[k].pixels != NULL){
00719          glBindTexture(GL_TEXTURE_2D,g_map_texture);
00721          glTexImage2D(GL_TEXTURE_2D,0,3,
00722                           glMapList[k].x,glMapList[k].y,
00723                           0,GL_RGB,GL_UNSIGNED_BYTE,
00724                           (GLvoid *)glMapList[k].pixels);
00725        }
00726        else glBindTexture(GL_TEXTURE_2D,g_check_texture);
00727      }
00728      else glBindTexture(GL_TEXTURE_2D,g_check_texture);
00729      if(!refmap){
00730        if(iMap[k].bTiled){
00731          if(iMap[k].Map == PLANE_MOZIAC || iMap[k].Map == CYLINDER_MOZIAC){
00732            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT);
00733            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT);
00734          }
00735          else{
00736            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00737            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00738          }
00739        }
00740        else{
00741          glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR,bc);
00742          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
00743          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
00744        } 
00745        if(iMap[k].bShaded) glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
00746        else                glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
00747      }
00748      // loop over all materials to get the border colour
00749      // any basic colour attributes will just appear as a grey border
00750      m = -1; 
00751      matloop:
00752      if(m >= 0){for(j=0;j<3;j++)bc[j]=(GLfloat)iMat[m].mcolour1[j]/255.0; bc[3]=1.0;}
00753      else      {bc[0]=bc[1]=bc[2]=0.5; bc[3]=1.0;}
00754      glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR,bc);
00755 
00756      if(m == -1)glEnable(GL_COLOR_MATERIAL);
00757 
00758      glBegin(GL_TRIANGLES);
00759      fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++,fp++){
00760        if(fp->imagemap < 0)continue; /* if not mapped */
00761        if((m >= 0 && fp->material != m) || (m == -1 && fp->material >= 0))continue; /* not this material */
00762        brushID=fp->imagemap;
00763        if(brushID != k)continue;         /* skip if not this map */
00764 
00765        if(m == -1)glColor3ub(fp->color[0],fp->color[1],fp->color[2]);
00766 
00767        v0=(MainVp+fp->V[0]); v1=(MainVp+fp->V[1]); v2=(MainVp+fp->V[2]);
00768        if(inview(v0) || inview(v1) || inview(v2)){
00769          if(Normalize(v0->xyz,v1->xyz,v2->xyz,n)){
00770            for(j=0;j<3;j++){
00771              Vi=fp->V[j]; v=(MainVp+Vi);
00772              if(fp->gp == TRUE){  // use face mapping coordinates
00773                alpha[j] = (GLfloat)(fp->x[j]); 
00774                beta[j]  = (GLfloat)(fp->y[j]); 
00775              }
00776              else if(iMap[k].Map == MAP_BY_VERTEX){
00777                alpha[j]=(GLfloat)v->x;
00778                beta[j]=(GLfloat)v->y;
00779              }
00780              else if(iMap[k].Map == MAP_SPHERICAL)
00781                   GetMappingCoordS(k,mN,mX,mY,mP,v->xyz,&(alpha[j]),&(beta[j]));
00782              else if(iMap[k].Map == CYLINDER || iMap[k].Map == CYLINDER_MOZIAC)
00783                   GetMappingCoordC(k,mN,mX,mY,mP,v->xyz,&(alpha[j]),&(beta[j]));
00784              else GetMappingCoordP(k,mN,mX,mY,mP,v->xyz,&(alpha[j]),&(beta[j]));
00785            }
00786            if(!fp->gp && (iMap[k].Map == CYLINDER || iMap[k].Map == CYLINDER_MOZIAC || iMap[k].Map == MAP_SPHERICAL)){
00787              FixUpMapEdge(alpha);
00788            }
00789            for(j=0;j<3;j++){
00790              Vi=fp->V[j]; v=(MainVp+Vi);
00791              x=((GLfloat)(v->xyz[0]-TVpointX-TVsizeX/2))*scale;
00792              y=((GLfloat)(v->xyz[1]-TVpointY-TVsizeY/2))*scale;
00793              z=((GLfloat)(v->xyz[2]-TVpointZ-TVsizeZ/2))*scale;
00794              if(fp->bSmooth){ /* smoothed */
00795                dot=DOT(nv[Vi],n);
00796                if(fabs(dot) < 0.5)glNormal3f(n[0],n[2],-n[1]);
00797                else if(dot  < 0.0)glNormal3f(-nv[Vi][0],-nv[Vi][2], nv[Vi][1]);
00798                else               glNormal3f( nv[Vi][0], nv[Vi][2],-nv[Vi][1]);
00799              }
00800              else{/* not smoothed */
00801                glNormal3f( n[0], n[2],-n[1]);
00802              }
00803              if(!refmap){
00804                if(!fp->gp && (iMap[k].Map == CYLINDER || iMap[k].Map == CYLINDER_MOZIAC))alpha[j] *= 360.0/(GLfloat)iMap[k].Angle;
00805                glTexCoord2f(alpha[j],beta[j]);
00806 
00808 //               glMultiTexCoord2f(GL_TEXTURE1,alpha[j],beta[j]);
00809 
00810              }
00811              glVertex3f(x,z,-y);
00812            }
00813          }
00814        }
00815      }
00816      glEnd();
00817 
00818      if(m == -1)glDisable(GL_COLOR_MATERIAL);
00819      m++;
00820      if(nMats > 0 && m >= 0 && m < nMats)goto matloop;
00821 
00822      if(refmap){
00823        glDisable(GL_TEXTURE_GEN_S);
00824        glDisable(GL_TEXTURE_GEN_T);
00825      }
00826      else{
00827        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00828        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00829      }
00830      glBindTexture(GL_TEXTURE_2D,0);
00831 
00832      if(glMapList[k].pixelsB != NULL){
00833 glActiveTexture(GL_TEXTURE1); //RSFx
00834      glBindTexture(GL_TEXTURE_2D,0);
00835 glActiveTexture(GL_TEXTURE0); //RSFx
00836      }
00837 
00838 
00839    }
00840  }
00841 
00842  if(nMats > 0 && Nface > 0){ // render the materials
00843    int pass;
00844    color[0]=1.0; color[1]=1.0; color[2]=1.0;
00845    for(pass=0;pass<2;pass++) // render transparency last
00846    for(k=0;k<nMats;k++){
00847      if(pass == 1 && iMat[k].transp > 0)continue;
00848      if(pass == 1 && iMat[k].transp > 0)continue;
00849      for(i=0;i<3;i++)color[i]=(GLfloat)iMat[k].mcolour1[i]/255.0;
00850      // set gl properites for this face
00851      glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,shiny);
00852      glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,glos_color);
00853      if(iMat[k].transp > 0){ // Set transparent blending
00854        glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,dull);
00855        glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,dark_color);
00856        for(i=0;i<3;i++)color[i] *= 0.3;
00857        glEnable(GL_BLEND);
00858        glDepthMask(GL_FALSE);
00859        glBlendFunc(GL_SRC_ALPHA,GL_ONE);
00860      }
00861      glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,color);
00862 
00863 //     UseShaderProgram(1);   ///////////////////////
00864      glBegin(GL_TRIANGLES);
00865      fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++,fp++){
00866        if(fp->material != k || (Mapped && fp->imagemap >= 0) || fp->material < 0)continue; //skip
00867        v0=(MainVp+fp->V[0]); v1=(MainVp+fp->V[1]); v2=(MainVp+fp->V[2]);
00868        if(inview(v0) || inview(v1) || inview(v2)){
00869          if(Normalize(v0->xyz,v1->xyz,v2->xyz,n)){
00870            for(j=0;j<3;j++){
00871              Vi=fp->V[j]; v=(MainVp+Vi);
00872              x=((GLfloat)(v->xyz[0]-TVpointX-TVsizeX/2))*scale;
00873              y=((GLfloat)(v->xyz[1]-TVpointY-TVsizeY/2))*scale;
00874              z=((GLfloat)(v->xyz[2]-TVpointZ-TVsizeZ/2))*scale;
00875              if(iMat[k].bSmooth){ /* smoothed */
00876                dot=DOT(nv[Vi],n);
00877                if(fabs(dot) < 0.5)glNormal3f(n[0],n[2],-n[1]);
00878                else if(dot  < 0.0)glNormal3f(-nv[Vi][0],-nv[Vi][2], nv[Vi][1]);
00879                else               glNormal3f( nv[Vi][0], nv[Vi][2],-nv[Vi][1]);
00880              }
00881              else{/* not smoothed */
00882                glNormal3f( n[0], n[2],-n[1]);
00883              }
00884              glVertex3f(x,z,-y);
00885            }
00886          }
00887        }
00888      }
00889      glEnd();
00890 //     UseShaderProgram(0);   ///////////////////////
00891 
00892      // any material attributes that need to be undone ?
00893      if(iMat[k].transp > 0){ // Set transparent blending
00894        glDepthMask(GL_TRUE);
00895        glDisable(GL_BLEND);
00896      }
00897    }
00898  }
00899 
00900  glDisable(GL_LIGHTING);
00901  bThickWire=TRUE;
00902  if(bOverlayWire)DrawModelEdges();
00903  bThickWire=FALSE;
00904 
00905  glEndList();
00906  listID=1;
00907 
00908  X__Free(nv);
00909  return;
00910 }
00911 
00912 static void DrawGlNurbs(GLfloat drawtype){
00913  GLUnurbsObj *theNurb;
00914  GLfloat *sknots,*tknots,*ctlarray;
00915  nurbs *np;
00916  GLfloat w,xp,yp,zp,scale;
00917  long i,j,k;
00918  vector4 *p1;
00919  if(Nnurbs == 0 || MainNp == NULL)return;
00920  if(drawtype == GLU_FILL && bNurbsWireOnly)drawtype=GLU_OUTLINE_POLYGON;
00921  scale=4.0/TVsizeX;
00922  np=MainNp; while(np != NULL){
00923    if(!(np->properties.hidden) && (theNurb = gluNewNurbsRenderer()) != 0){
00924      sknots=(GLfloat *)X__Malloc(sizeof(GLfloat)*(np->numU+np->orderU));
00925      tknots=(GLfloat *)X__Malloc(sizeof(GLfloat)*(np->numV+np->orderV));
00926      if(sknots != NULL)for(j=0;j<np->numU+np->orderU;j++){ //knotsU
00927        sknots[j]=(GLfloat)np->kvU[j];
00928      }
00929      if(tknots != NULL)for(i=0;i<np->numV+np->orderV;i++){ //knotsV
00930        tknots[i]=(GLfloat)np->kvV[i];
00931      }
00932      ctlarray=(GLfloat *)X__Malloc(sizeof(GLfloat)*(4*np->numV*np->numU));
00933      if(ctlarray != NULL){
00934        k=0;
00935        for(j=0;j<np->numU;j++)
00936        for(i=0;i<np->numV;i++){
00937          p1 = &(np->points[i][j]);
00938          w=(GLfloat)(1.0/p1->w);
00939          xp=(GLfloat)((p1->x)*w);
00940          yp=(GLfloat)((p1->y)*w);
00941          zp=(GLfloat)((p1->z)*w);
00942          xp = (xp-(GLfloat)(TVpointX+TVsizeX/2))*scale;
00943          yp = (yp-(GLfloat)(TVpointY+TVsizeY/2))*scale;
00944          zp = (zp-(GLfloat)(TVpointZ+TVsizeZ/2))*scale;
00945          w=(GLfloat)(p1->w);
00946          *(ctlarray+(k++)) =  xp*w;
00947          *(ctlarray+(k++)) =  zp*w;
00948          *(ctlarray+(k++)) = -yp*w;
00949          *(ctlarray+(k++)) =  w;
00950        }
00951        if(drawtype == GLU_FILL)glEnable(GL_AUTO_NORMAL);
00952        gluBeginSurface(theNurb);
00953        glColor3f((GLfloat)(np->properties.colour[0])/255.0,
00954                  (GLfloat)(np->properties.colour[1])/255.0,
00955                  (GLfloat)(np->properties.colour[2])/255.0);
00956        if(drawtype == GLU_OUTLINE_POLYGON){
00957          gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_DOMAIN_DISTANCE);
00958          gluNurbsProperty(theNurb,GLU_U_STEP,5);
00959          gluNurbsProperty(theNurb,GLU_V_STEP,5);
00960        }
00961        else{
00962          gluNurbsProperty(theNurb,GLU_SAMPLING_TOLERANCE,50.0);
00963          gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_PATH_LENGTH);
00964        }
00965 //gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON);
00966 //gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_OUTLINE_PATCH);
00967 //gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
00968        gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, drawtype);
00969        gluNurbsSurface(theNurb,
00970             np->numU+np->orderU, sknots,
00971             np->numV+np->orderV, tknots,
00972             4 * np->numV,
00973             4,
00974             ctlarray,
00975             np->orderU, np->orderV,
00976             GL_MAP2_VERTEX_4);
00977        gluEndSurface(theNurb);
00978        if(drawtype == GLU_FILL)glDisable(GL_AUTO_NORMAL);
00979      }
00980      if(sknots != NULL)X__Free(sknots);
00981      if(tknots != NULL)X__Free(tknots);
00982      if(ctlarray != NULL)X__Free(ctlarray);
00983      gluDeleteNurbsRenderer(theNurb);
00984    }
00985    np=np->last;
00986  }
00987  return;
00988 }
00989 
00991 
00992 #define TOL 1000.0
00993 
00994 static BOOL normalise(GLfloat *v){
00995  GLfloat n,nn;
00996  n= (GLfloat)((v[0]*v[0]) + (v[1]*v[1]) + (v[2]*v[2]));
00997  if(n < 1.e-10)return FALSE;
00998  nn=sqrt(n);
00999  n = 1.0 / nn;
01000  VECSCALE(n,v,v)
01001  return TRUE;
01002 }
01003 
01004 static BOOL Normalize(point x,point y,point z,GLfloat *n){
01005  GLfloat dz[3],dy[3];
01006  VECSUB((GLfloat)y,(GLfloat)x,dy)
01007  VECSUB((GLfloat)z,(GLfloat)x,dz)
01008  CROSS(dy,dz,n)
01009  if(normalise(n))return TRUE;
01010  return FALSE;
01011 }
01012 
01013 #define HIDDEN 2
01014 
01015 static BOOL inview(vertex  *vp){
01016  if(vp->status == HIDDEN)return 0;
01017  // enlarge the size of view
01018  if( ((vp->xyz[0] > TVpointX-2*TVsizeX) && (vp->xyz[0] < TVpointX+3*TVsizeX))
01019   && ((vp->xyz[1] > TVpointY-2*TVsizeX) && (vp->xyz[1] < TVpointY+3*TVsizeY))
01020   && ((vp->xyz[2] > TVpointZ-2*TVsizeX) && (vp->xyz[2] < TVpointZ+3*TVsizeZ))
01021    )return TRUE;
01022  return FALSE;
01023 }
01024 
01025 static BOOL same_color(unsigned char *color){
01026  static unsigned char lastcolor[3]={0,0,0};
01027  if(labs((long)(color[0]) - (long)(lastcolor[0])) > 2 ||
01028     labs((long)(color[1]) - (long)(lastcolor[1])) > 2 ||
01029     labs((long)(color[2]) - (long)(lastcolor[2])) > 2){
01030    VECCOPY(color,lastcolor)
01031    return FALSE;
01032  }
01033  return TRUE;
01034 }
01035 
01036 static void GetMapNormal(int k, vector mP, vector mX, vector mY,
01037                          vector mN){
01038  GLfloat n[3];
01039  if(iMap[k].Map == CYLINDER || 
01040     iMap[k].Map == MAP_SPHERICAL || 
01041     iMap[k].Map == CYLINDER_MOZIAC){
01042    VECCOPY((double)iMap[k].P,mP)
01043    VECSUB((double)iMap[k].X,mP,mX)
01044    VECSUB((double)iMap[k].Y,mP,mY)
01045    CROSS(mY,mX,mN)
01046  }
01047  else{                                              /* arranged this way to */
01048    VECCOPY((double)iMap[k].Y,mP)                    /* have map with origin */
01049    VECSUB((double)iMap[k].X,(double)iMap[k].P,mX)   /* at bottom left       */
01050    VECSUB((double)iMap[k].P,mP,mY)
01051    CROSS(mX,mY,mN)
01052  }
01053  VECCOPY((GLfloat)mN,n)
01054  if(!normalise(n))MessageBeep(MB_OK);
01055  VECCOPY((double)n,mN)
01056  return;
01057 }
01058 
01059 static void GetMappingCoordP(int id, vector n, vector x, vector y, vector p0,
01060                              long *pv,
01061                              GLfloat *a, GLfloat *b){
01062  vector v1,p;
01063  GLfloat mu,det,ve1,ve2,ve3,vp1,vp2,vp3,p1,p2,p3;
01064  VECSUB(p0,(double)pv,v1)
01065  mu=DOT(n,v1);
01066  VECSCALE(mu,n,v1)
01067  VECSUM((double)pv,v1,p)
01068  ve1=x[0]; ve2=x[1]; ve3=x[2];
01069  vp1=y[0]; vp2=y[1]; vp3=y[2];
01070  p1=p[0]-p0[0];
01071  p2=p[1]-p0[1];
01072  p3=p[2]-p0[2];
01073  det=ve1*vp2-vp1*ve2;
01074  if(det > TOL || det < -TOL)  /* e-10 appears not to work */
01075    {  *a=( vp2*p1-vp1*p2)/det;
01076       *b=(-ve2*p1+ve1*p2)/det;
01077       goto HIT;
01078    }
01079  det=ve1*vp3-vp1*ve3;
01080  if(det > TOL || det < -TOL)
01081    {  *a=( vp3*p1-vp1*p3)/det;
01082       *b=(-ve3*p1+ve1*p3)/det;
01083       goto HIT;
01084    }
01085  det=ve2*vp3-vp2*ve3;
01086  if(det > TOL || det < -TOL)
01087    {  *a=( vp3*p2-vp2*p3)/det;
01088       *b=(-ve3*p2+ve2*p3)/det;
01089       goto HIT;
01090    }
01091  *a = *b = 0.0;
01092  HIT:
01093  return;
01094 }
01095 
01096 #define RTD 0.159154943
01097 
01098 static void GetMappingCoordC(int id, vector n, vector x, vector y, vector p0,
01099                 long *pv,
01100                 GLfloat *a, GLfloat *b){
01101  GLfloat theta,nn;
01102  GLfloat p1[3],p2[3],q[3];
01103  VECSUB((GLfloat)p0,(GLfloat)pv,p1)
01104  *b=DOT(p1,y)/DOT(y,y);
01105  VECSCALE(*b,y,p2)
01106  VECSUB(p1,p2,q)
01107  normalise(q);
01108  nn=DOT(q,(GLfloat)n);
01109  if     (nn >  1.0)nn =  1.0;
01110  else if(nn < -1.0)nn = -1.0;
01111  theta=acos(nn)*RTD;
01112  CROSS(q,n,p1)
01113  if(DOT(p1,y) <= 0.0){
01114    if(theta <= 0.25) *a = (0.25 - theta);
01115    else  *a = (1.25 - theta);
01116  }
01117  else    *a = (0.25 + theta);
01118 // *a *= 360.0/(GLfloat)iMap[id].Angle; // needs to be applied after the edge fix up !!!!
01119  *b = *b + 1.0;
01120  return;
01121 }
01122 
01123 
01124 void GetMappingCoordS(int id, vector n, vector dx, vector dy, vector p0, long *pv,
01125                 GLfloat *a, GLfloat * b){
01126   GLfloat x[3],z[3],r[3],p[3];
01127   VECCOPY((GLfloat)pv,p)
01128   VECCOPY((GLfloat)dx,x)
01129   normalise(x);
01130   VECSCALE(-1.0,(GLfloat)dy,z)
01131   normalise(z);
01132   VECSUB(p,p0,r)
01133   normalise(r);
01134   *b = -acos(DOT(r,z))*0.3183;              /*  theta/pi                    */
01135   *a = -atan2(DOT(r,n),DOT(r,x))*0.1592;    /*  phi/(2 pi)    0   < a < 0.5 */
01136   if(*a < 0.0) *a = 1.0 + *a;              /*                0.5 < a < 1.0 */
01137   *b = *b + 1.0; 
01138   return;
01139 }
01140 
01141 static void FixUpMapEdge(GLfloat a[]){
01142  if(a[0] < MAPDELTA){if(a[1] >= 1.0-MAPDELTA)a[1] -= 1.0; if(a[2] >= 1.0-MAPDELTA)a[2] -= 1.0; return;}
01143  if(a[1] < MAPDELTA){if(a[2] >= 1.0-MAPDELTA)a[2] -= 1.0; if(a[0] >= 1.0-MAPDELTA)a[0] -= 1.0; return;}
01144  if(a[2] < MAPDELTA){if(a[0] >= 1.0-MAPDELTA)a[0] -= 1.0; if(a[1] >= 1.0-MAPDELTA)a[1] -= 1.0; return;}
01145 }
01146 
01147 
01148 //glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,mc);
01149 //         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
01150 //         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
01151 //         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
01152 //         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
01153 //{
01154 //static float CC[4]={0.0,1.0,0.0,0.4};
01155 //glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
01156 //glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,CC);
01157 //glTexEnvf(GL_TEXTURE_ENV,GL_SRC2_RGB,GL_CONSTANT);
01158 //glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND2_RGB,GL_SRC_ALPHA);
01159 //}

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