gldesign1.c

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

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