rendergl.C

Go to the documentation of this file.
00001 // File rendergl.c
00002 
00003 #define MODULE_RENDERGL
00004 
00005 #include "render.h"
00006 #include "..\shaders\shaders.h"
00007 
00008 #include <gl/glaux.h>
00009 
00010 #include "..\gl2.h"
00011 
00012 #define checkImageWidth  64
00013 #define checkImageHeight 64
00014 
00015 extern char gszHomeDir[];
00016 
00017 GLuint g_check_texture;  // default texture when no maps can be found
00018 GLuint g_map_texture;
00019 GLuint g_ref_texture;    // reflection map texture
00020 GLuint g_bump_texture;   // bump map texture
00021 GLuint g_tran_texture;
00022 GLuint g_movie_texture;  // default movie texture - this should just be an ordinary texture
00023 GLuint g_env_texture;    // material environmental reflection texture
00024 GLuint g_env3D_texture;  // material environmental reflection texture for 3D shaders
00025 GLuint g_envB_texture;   // material bump texture
00026 GLuint g_envN_texture;   // 2D noise texture
00027 GLuint g_noise_texture;  // 3D noise texture
00028 GLuint g_sky_texture;    // sky_texture for mapped skies
00029 
00030 GLubyte checkImage[checkImageWidth][checkImageHeight][3];
00031 GLint DlistID=0;
00032 double DepthScalingGL,FrontDepthGL,BackDepthGL;
00033 
00034 static HWND   g_hWnd = NULL;
00035 static HDC    g_hDC  = NULL;
00036 static HGLRC  g_hRC  = NULL;
00037 
00038 static HDC m_hDCWnd;                                                    // copy of main window's device context
00039 static HGLRC m_hGLRCWnd;                                                // copy of main window's render context
00040 
00041 struct PBuffer  {
00042   HPBUFFERARB  hPBuffer;
00043   HDC          hDC;
00044   HGLRC        hGLRC;
00045 } m_PBuffer;
00046 
00047 
00048 static BOOL   bDrawToScreen=FALSE,bDrawToFBO=FALSE,bDrawToPbuffer=TRUE;
00049 static BOOL   bFillDepthBuffer=FALSE;
00050 static BOOL   bLoaded=FALSE;
00051 static BOOL   bAntiAliased=FALSE;
00052 static int    nAAsamples=1;
00053 
00054 static int g_nWindowWidth;
00055 static int g_nWindowHeight;
00056 
00057 // Framebuffer for RenderBuffer
00058 static GLuint g_frameBuffer       = 0;
00059 static GLuint g_depthRenderBuffer = 0;
00060 static GLuint g_colorRenderBuffer = 0;
00061 //static GLuint g_accumRenderBuffer = 0;
00062 //static GLuint g_stencilRenderBuffer = 0;
00063 
00064 // FrameBuffer for TextureBuffer
00065 GLuint g_framebufferTexture = -1;
00066 GLuint g_frameBuffer2=0;
00067 GLuint g_depthRenderBuffer2=0;
00068 
00069 //int RENDERBUFFER_WIDTH  = 1280;   //OK on FX1100 6800 7600 and X1950
00070 //int RENDERBUFFER_HEIGHT = 1024;
00071 int RENDERBUFFER_WIDTH  = 2048;    // OK on FX1100 6800 and Radeon x1950
00072 int RENDERBUFFER_HEIGHT = 2048;
00073 int TEXTUREBUFFER_WIDTH  = 2048;  // Must be power of 2 on ATI 
00074 int TEXTUREBUFFER_HEIGHT = 2048;
00075 //int RENDERBUFFER_WIDTH  = 4096;  // MAXIMUM on nVidia & ATI
00076 //int RENDERBUFFER_HEIGHT = 4096;
00077 //int TEXTUREBUFFER_WIDTH  = 4096;  
00078 //int TEXTUREBUFFER_HEIGHT = 4096;
00079 
00080 static char ClassName[] = "OFX:RENDER:OGL:CLASS";
00081 static WNDCLASSEX winClass; 
00082 static unsigned char *RenderBufferCopy=NULL;
00083 static GLfloat *DepthBufferCopy=NULL;
00084 //static unsigned char *RenderBufferAccu=NULL;
00085 
00086 static HWND SetupRenderOpenGL(HWND);
00087 static BOOL InitPBuffer(void);
00088 static void printGCinfo(char *text);
00089 static LRESULT CALLBACK XWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
00090 static void SetMappingQuality(void);
00091 static void makeCheckImageMap(int id);
00092 static long RenderGLtoWGL(long, BOOL );
00093 static long RenderGLtoFBO(long, BOOL );
00094 static void WriteBitmap(long nx, long ny, unsigned char *S, long f, BOOL b32);
00095 static void CopyToDepthBuffer(void);
00096 
00097 
00098 long RenderGL(long frame, BOOL ppGL){
00099  long r;
00100  if(bDrawToScreen){
00101    printGCinfo("Screen output");
00102    r=RenderGLtoWGL(frame,ppGL);  // Screen
00103  }
00104  else if(bDrawToPbuffer){
00105    wglMakeCurrent( m_PBuffer.hDC, m_PBuffer.hGLRC );
00106    printGCinfo("Pbuffer output");
00107    r=RenderGLtoWGL(frame,ppGL);  // Pbuffer
00108    wglMakeCurrent( m_hDCWnd, m_hGLRCWnd );
00109  }
00110  else{
00111    r=RenderGLtoFBO(frame,ppGL);  // FBO
00112  }
00113  return r;
00114 }
00115 
00116 static long RenderGLtoFBO(long frame, BOOL ppGL){
00117  int  i,aa;
00118  GLfloat accu;
00119  // bind to and clear the renderbuffer in which the images will be accumulated.
00120  glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, g_frameBuffer );
00121  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 
00122                               GL_RENDERBUFFER_EXT, g_colorRenderBuffer );
00123  //glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,  // Don't bother with depth buffer
00124  //GL_RENDERBUFFER_EXT, g_depthRenderBuffer );                                 // on this framebuffer (not needed) 
00125  glViewport( 0, 0, RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT );
00126  glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
00127  glClear(GL_COLOR_BUFFER_BIT);
00128  glFlush();
00129  DlistID=0;
00130  accu=1.0;
00131  printGCinfo("Renderbuffer output");
00132  for(aa=0;aa<nAAsamples;aa++){ 
00133    // Render the Scene into a texture attached to a framebuffer
00134    glBindFramebufferEXT( GL_FRAMEBUFFER_EXT,g_frameBuffer2);
00135    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, g_framebufferTexture,0);
00136    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT,g_depthRenderBuffer2);
00137    if(aa == 0)printGCinfo("FBO output texture");
00138    RenderCameraView(TRUE,bAntiAliased,aa,nAAsamples,(GLfloat)RENDERBUFFER_WIDTH/(GLfloat)RENDERBUFFER_HEIGHT);
00139    glFlush();
00140    if(aa == nAAsamples-1 && DepthBufferCopy != NULL)CopyToDepthBuffer(); // Copy to DepthBuffer if required
00141    // copy Texturebuffer to renderbuffer depth buffer _ will need scaled????
00142    //   
00143    // Render an orthogonal polygon into a renderbuffer attached to a framebuffer
00144    // this does not need a depth buffer. 
00145    // For Anti-aliasing, simulate the use of an accumulation buffer (not available for
00146    // FB0s) by blending the texture.
00147    glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, g_frameBuffer );
00148    glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 
00149                 GL_RENDERBUFFER_EXT, g_colorRenderBuffer );
00150    glMatrixMode(GL_PROJECTION);
00151    glLoadIdentity();
00152    glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0);
00153    glMatrixMode( GL_MODELVIEW );
00154    glLoadIdentity();
00155    glViewport( 0, 0, RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT );
00156    glEnable(GL_BLEND);
00157    glBlendColor(0.0,0.0,0.0,accu); accu *= 0.5;
00158    glBlendFunc(GL_CONSTANT_ALPHA,GL_ONE_MINUS_CONSTANT_ALPHA);
00159    glDepthMask(GL_FALSE);
00160    glBindTexture( GL_TEXTURE_2D, g_framebufferTexture);
00161    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
00162    glColor4f(1.0,1.0,1.0,1.0);
00163    glBegin(GL_QUADS);
00164    glTexCoord2f(0.0,0.0); glVertex3f(0.0,0.0,-1.0); 
00165    glTexCoord2f(1.0,0.0); glVertex3f(1.0,0.0,-1.0); 
00166    glTexCoord2f(1.0,1.0); glVertex3f(1.0,1.0,-1.0);
00167    glTexCoord2f(0.0,1.0); glVertex3f(0.0,1.0,-1.0);
00168    glEnd();
00169    glDepthMask(GL_TRUE);
00170    glBindTexture( GL_TEXTURE_2D,0);
00171    glDisable(GL_BLEND);
00172  }
00173  if(DlistID > 0){glDeleteLists(1,1);DlistID=0;}
00174  glFlush();
00175  if(ppGL)PostProcessRenderGL(frame); // Render any postprocesses
00176  glReadPixels(0,0,RENDERBUFFER_WIDTH,RENDERBUFFER_HEIGHT,GL_RGBA,GL_UNSIGNED_BYTE,RenderBufferCopy);
00177  glFlush(); 
00178  glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
00179  return 1;
00180 }
00181 
00182 static long RenderGLtoWGL(long frame, BOOL ppGL){ // Render to window context - Screen or Pbuffer
00183  int  i,aa;
00184  DlistID=0;
00185  if(nAAsamples > 1)glClear(GL_ACCUM_BUFFER_BIT); 
00186  for(aa=0;aa<nAAsamples;aa++){ 
00187    glClearColor(0.0,0.0,0.0,1.0);
00188    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00189    RenderCameraView(TRUE,bAntiAliased,aa,nAAsamples,(GLfloat)RENDERBUFFER_WIDTH/(GLfloat)RENDERBUFFER_HEIGHT);
00190    glFlush();
00191    if(nAAsamples > 1)glAccum(GL_ACCUM,1.0/(GLfloat)nAAsamples);
00192  }
00193  if(DlistID > 0){glDeleteLists(1,1);DlistID=0;}
00194  if(nAAsamples > 1)glAccum(GL_RETURN,1.0);
00195  glFlush();
00196  if(ppGL)PostProcessRenderGL(frame); // Render any scene postprocessing
00197  glReadPixels(0,0,RENDERBUFFER_WIDTH,RENDERBUFFER_HEIGHT,GL_RGBA,GL_UNSIGNED_BYTE,RenderBufferCopy);
00198  //{static int c; WriteBitmap(RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT,RenderBufferCopy,c++,TRUE);}
00199  if(DepthBufferCopy != NULL)CopyToDepthBuffer(); 
00200  return 1;
00201 }
00202 
00203 HWND SetUpGlWindow(HANDLE hInstance, HWND hWndParent, long Xres, long Yres, 
00204                    BOOL bFullScreen, BOOL bUseFBO, BOOL bCopyToDepthBuffer, long AAlias){
00205  HWND hParentLocal;
00206  DWORD windowStyle;
00207  DWORD windowExtendedStyle = WS_EX_APPWINDOW;
00208  //if(debug != NULL)fprintf(debug,"HW started AA=%ld Fullscreen=%d UseFBO=%ld Res=(%ld %ld)\n",AAlias,bFullScreen,bUseFBO, Xres,Yres);
00209  // bFullScreen=FALSE; bUseFBO=TRUE;  // for testing
00210  if(bLoaded){ // Release the window and re-create
00211    DestroyWindow(g_hWnd);
00212    CloseGlWindow();
00213  }
00214  bFillDepthBuffer=bCopyToDepthBuffer; 
00215  //bFillDepthBuffer=FALSE; //  slows things down when on 
00216  //AAlias=0; // use for testing only
00217  if(AAlias == 0){bAntiAliased=FALSE; nAAsamples=1;}
00218  else           {bAntiAliased=TRUE;  nAAsamples=AAlias;}
00219  winClass.lpszClassName = ClassName;
00220  winClass.cbSize        = sizeof(WNDCLASSEX);
00221  winClass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
00222  winClass.lpfnWndProc   = XWindowProc;
00223  winClass.hInstance     = hInstance;
00224  winClass.hIcon        = LoadIcon(hInstance, (LPCTSTR)"showicon");
00225  winClass.hIconSm          = LoadIcon(hInstance, (LPCTSTR)"showicon");
00226  winClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
00227  winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
00228  winClass.lpszMenuName  = NULL;
00229  winClass.cbClsExtra    = 0;
00230  winClass.cbWndExtra    = 0;
00231  if( !RegisterClassEx(&winClass) )return NULL;
00232  if(bFullScreen){
00233    bDrawToScreen=TRUE;  bDrawToFBO=FALSE; bDrawToPbuffer=FALSE;
00234    windowStyle = WS_POPUP;                              
00235    windowExtendedStyle |= WS_EX_TOPMOST;
00236    hParentLocal=HWND_DESKTOP;
00237    g_nWindowHeight=min(Yres,GetSystemMetrics(SM_CYSCREEN));
00238    g_nWindowWidth=min(Xres,GetSystemMetrics(SM_CXSCREEN));
00239    TEXTUREBUFFER_WIDTH=RENDERBUFFER_WIDTH=g_nWindowWidth;  
00240    TEXTUREBUFFER_HEIGHT=RENDERBUFFER_HEIGHT=g_nWindowHeight;
00241 }
00242  else{
00243    bDrawToScreen=FALSE;
00244    if(bUseFBO){ // frame buffer
00245      bDrawToFBO=TRUE; bDrawToPbuffer=FALSE;
00246      RENDERBUFFER_WIDTH=Xres; RENDERBUFFER_HEIGHT=Yres;
00247      // Note texturebuffer dimensions must be power of 2 on ATI
00248      TEXTUREBUFFER_WIDTH=TEXTUREBUFFER_HEIGHT=2048;
00249      if(Xres <= 1024)TEXTUREBUFFER_WIDTH=1024;  else if(Xres > 3500)TEXTUREBUFFER_WIDTH=4096;
00250      if(Yres <= 1024)TEXTUREBUFFER_HEIGHT=1024; else if(Yres > 3500)TEXTUREBUFFER_HEIGHT=4096;
00251    }
00252    else {  // pixel buffer
00253      bDrawToFBO=FALSE;  bDrawToPbuffer=TRUE;
00254      RENDERBUFFER_WIDTH=TEXTUREBUFFER_WIDTH=Xres; RENDERBUFFER_HEIGHT=TEXTUREBUFFER_HEIGHT=Yres; 
00255    }
00256    windowStyle = WS_POPUP | WS_CAPTION | !WS_SYSMENU | WS_THICKFRAME;
00257    g_nWindowWidth=480; g_nWindowHeight=320+20;
00258    hParentLocal=hWndParent;
00259  }
00260  g_hWnd = CreateWindowEx(windowExtendedStyle, ClassName, "OpenFX:OpenGL Renderer",windowStyle,
00261      0, 0, g_nWindowWidth, g_nWindowHeight, hParentLocal, NULL, hInstance, NULL );
00262  if( g_hWnd == NULL )return NULL;
00263  //if(SetupRenderOpenGL(g_hWnd) == NULL)return NULL;  // now called from WM_CREATE
00264  bLoaded=TRUE;
00265  ShowWindow(g_hWnd,SW_SHOW);
00266  UpdateWindow(g_hWnd);
00267  bRenderOpenGL=TRUE;
00268  return g_hWnd;
00269 }
00270 
00271 static HWND SetupRenderOpenGL(HWND hWnd){ 
00272  unsigned char *movie_image=NULL,movie_file[256];
00273  unsigned char *env_image=NULL,env_file[256];
00274  unsigned char *envB_image=NULL,envB_file[256];
00275  unsigned char *envN_image=NULL,envN_file[256];
00276  long movie_image_x,movie_image_y;
00277  long env_image_x,env_image_y;
00278  long envB_image_x,envB_image_y;
00279  long envN_image_x,envN_image_y;
00280  GLenum status;
00281  // Setup device context
00282  PIXELFORMATDESCRIPTOR pfd;
00283  GLuint PixelFormat;
00284  memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
00285  pfd.nSize      = sizeof(PIXELFORMATDESCRIPTOR);
00286  pfd.nVersion   = 1;
00287  pfd.dwFlags    = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
00288  pfd.iPixelType = PFD_TYPE_RGBA;
00289  pfd.cColorBits = 32;
00290  pfd.cDepthBits = 32;     
00291  pfd.cAccumBits = 16;      
00292  pfd.cStencilBits = 1;    
00293  g_hDC = GetDC(hWnd);
00294  if((PixelFormat = ChoosePixelFormat( g_hDC, &pfd )) == FALSE){
00295    MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK);
00296    return NULL;
00297  }
00298  if(SetPixelFormat( g_hDC, PixelFormat, &pfd) == FALSE){
00299   MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK);
00300   return NULL;
00301  }
00302  g_hRC = wglCreateContext( g_hDC );
00303  wglMakeCurrent( g_hDC, g_hRC );
00304  m_hDCWnd = wglGetCurrentDC();
00305  m_hGLRCWnd = wglGetCurrentContext();
00306 
00307  RenderBufferCopy=NULL; DepthBufferCopy=NULL;
00308  if((RenderBufferCopy=(unsigned char *)malloc(RENDERBUFFER_WIDTH*RENDERBUFFER_HEIGHT*4)) == NULL)return NULL;
00309  if(bFillDepthBuffer && (DepthBufferCopy=(GLfloat *)malloc(TEXTUREBUFFER_WIDTH*TEXTUREBUFFER_HEIGHT*sizeof(GLfloat))) == NULL){
00310    free(RenderBufferCopy); RenderBufferCopy=NULL;
00311    return NULL;
00312  }
00313  //if((RenderBufferAccu=(unsigned char *)malloc(RENDERBUFFER_WIDTH*RENDERBUFFER_HEIGHT*4)) == NULL){
00314  //  free(RenderBufferCopy); RenderBufferCopy=NULL;
00315  //  return NULL;
00316  //}
00317  memset(RenderBufferCopy,64,RENDERBUFFER_WIDTH*RENDERBUFFER_HEIGHT*4);
00318 
00319  gl2Initialize();
00320  if(bDrawToPbuffer){   // MUST initialise shaders and lights in the context of the PBUFFER !!!
00321    InitPBuffer();
00322    wglMakeCurrent( m_PBuffer.hDC, m_PBuffer.hGLRC );
00323  } 
00324  ShadersInit(gszHomeDir,FALSE);
00325  if(bDrawToFBO){
00326    // Set up Framebuffer for normal rendering
00327    glGenFramebuffersEXT(1, &g_frameBuffer);
00328    glGenRenderbuffersEXT( 1, &g_colorRenderBuffer );  // A colour buffer
00329    glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, g_colorRenderBuffer );
00330    glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_RGBA8, RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT ); // this
00331    // An acumulation buffer for antialiasing !!!!!!!!!NOT YET available
00332    //glGenRenderbuffersEXT( 1, &g_accumRenderBuffer );
00333    //glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, g_accumRenderBuffer );
00334    //glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_RGBA8, RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT );
00335    // A stencil buffer    !!!!!!!!!NOT YET available
00336    //glGenRenderbuffersEXT( 1, &g_stencilRenderBuffer );
00337    //glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, g_stencilRenderBuffer );
00338    //glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT );
00339    // A depth buffer
00340    glGenRenderbuffersEXT( 1, &g_depthRenderBuffer );  // If need a depth buffer
00341    glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, g_depthRenderBuffer );
00342    // We dont need need a depth buffer but set one up anyway (still under test)
00343    glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT );  //this 
00344    if(debug != NULL){
00345      int fb_colours=0,fb_size=0;
00346      glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT,&fb_colours);
00347      glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT,&fb_size);
00348    //  if(debug != NULL)fprintf(debug,"First FrameBuffer Max color attachments=%ld max renderbuffer_size=%ld\n",fb_colours,fb_size);
00349    }
00350    status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
00351    switch( status )     {
00352      case GL_FRAMEBUFFER_COMPLETE_EXT:
00353                         //MessageBox(NULL,"GL_FRAMEBUFFER_COMPLETE_EXT!","SUCCESS",MB_OK|MB_ICONEXCLAMATION);
00354                         break;
00355      case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
00356        MessageBox(NULL,"GL_FRAMEBUFFER_UNSUPPORTED_EXT!","ERROR",MB_OK|MB_ICONEXCLAMATION);
00357        exit(0);
00358        break;
00359      default: return NULL;
00360    }
00361    // Set up Framebuffer for texture rendering
00362    glGenFramebuffersEXT(1, &g_frameBuffer2);
00363    glGenRenderbuffersEXT( 1, &g_depthRenderBuffer2 );  
00364    glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, g_depthRenderBuffer2 );
00365    glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT32, TEXTUREBUFFER_WIDTH, TEXTUREBUFFER_HEIGHT );  
00366    status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
00367    switch( status )     {
00368      case GL_FRAMEBUFFER_COMPLETE_EXT:
00369                         //MessageBox(NULL,"GL_FRAMEBUFFER_COMPLETE_EXT!","SUCCESS",MB_OK|MB_ICONEXCLAMATION);
00370                         break;
00371      case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
00372          MessageBox(NULL,"GL_FRAMEBUFFER_UNSUPPORTED_EXT!","ERROR",MB_OK|MB_ICONEXCLAMATION);
00373          exit(0);
00374        break;
00375      default: return NULL;
00376    }
00377    glEnable(GL_TEXTURE_2D);  // Create the texture buffer to attach to the FBO
00378    glGenTextures(1,&g_framebufferTexture );
00379    glBindTexture(GL_TEXTURE_2D, g_framebufferTexture );
00380    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 
00381               TEXTUREBUFFER_WIDTH, TEXTUREBUFFER_HEIGHT, 
00382                       0, GL_RGB, GL_UNSIGNED_BYTE, 0 );
00383    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
00384    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
00385    SetMappingQuality(); 
00386    glBindTexture(GL_TEXTURE_2D,0);
00387    // End of Framebuffers 
00388  }
00389 
00390  glActiveTexture(GL_TEXTURE3); 
00391  glEnable(GL_TEXTURE_2D);
00392  glActiveTexture(GL_TEXTURE2); 
00393  glEnable(GL_TEXTURE_2D);
00394  glActiveTexture(GL_TEXTURE1); 
00395  glEnable(GL_TEXTURE_2D);
00396  glActiveTexture(GL_TEXTURE0);
00397  glEnable(GL_TEXTURE_2D);
00398  glGenTextures( 1, &g_check_texture );
00399  glGenTextures( 1, &g_map_texture );
00400  glGenTextures( 1, &g_bump_texture );
00401  glGenTextures( 1, &g_ref_texture );
00402  glGenTextures( 1, &g_tran_texture );
00403  glGenTextures( 1, &g_movie_texture );
00404  glGenTextures( 1, &g_env_texture );
00405  glGenTextures( 1, &g_envB_texture );
00406  glGenTextures( 1, &g_envN_texture );
00407  glGenTextures( 1, &g_noise_texture );
00408  glGenTextures( 1, &g_env3D_texture );
00409  glGenTextures( 1, &g_sky_texture );
00410  
00411  glMatrixMode(GL_MODELVIEW);
00412  glLoadIdentity();
00413  glClearDepth(1.0);
00414  glEnable(GL_DEPTH_TEST);
00415  glDepthFunc(GL_LEQUAL);  // this is needed for the map blending
00416  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
00417  glShadeModel(GL_SMOOTH);
00418  // make the dummy textures for later use
00419  glBindTexture(GL_TEXTURE_2D,g_check_texture);
00420  makeCheckImageMap(0);
00421  glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
00422               checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
00423               &checkImage[0][0][0]);
00424  SetMappingQuality(); // REQUIRED 
00425  // put something in the texture - needed before making display list
00426  glBindTexture(GL_TEXTURE_2D,g_map_texture);
00427  glTexImage2D(GL_TEXTURE_2D, 0, 4, checkImageWidth,
00428               checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
00429               NULL); //&checkImage[0][0][0]);
00430  SetMappingQuality(); // THIS IS NEEDED -see function
00431  glBindTexture(GL_TEXTURE_2D,g_bump_texture);
00432  glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
00433               checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
00434               NULL);
00435  SetMappingQuality(); // THIS IS NEEDED -see function
00436  glBindTexture(GL_TEXTURE_2D,g_ref_texture);
00437  glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
00438               checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
00439               NULL);
00440  SetMappingQuality(); // THIS IS NEEDED -see function
00441  glBindTexture(GL_TEXTURE_2D,g_tran_texture);
00442  glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
00443               checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
00444               NULL);
00445  SetMappingQuality(); 
00446  glBindTexture(GL_TEXTURE_2D,g_sky_texture);
00447  glTexImage2D(GL_TEXTURE_2D, 0, 4, checkImageWidth,
00448               checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
00449               NULL);
00450  SetMappingQuality(); 
00451  // now the default textures
00452  strcpy(movie_file,gszHomeDir); strcat(movie_file,"movie.bmp");
00453  if((movie_image=LoadSystemMAP(TRUE,FALSE,movie_file,&movie_image_x,&movie_image_y)) != NULL){
00454    glBindTexture(GL_TEXTURE_2D,g_movie_texture);
00455    glTexImage2D(GL_TEXTURE_2D,0,3,
00456                           movie_image_x,movie_image_y,
00457                           0,GL_RGB,GL_UNSIGNED_BYTE,
00458                           (GLvoid *)movie_image);
00459    SetMappingQuality(); // THIS IS NEEDED -see function
00460    X__Free(movie_image);
00461  }
00462  strcpy(env_file,gszHomeDir); strcat(env_file,"genref.bmp");
00463  if((env_image=LoadSystemMAP(TRUE,FALSE,env_file,&env_image_x,&env_image_y)) != NULL){
00464    glBindTexture(GL_TEXTURE_2D,g_env_texture);
00465    glTexImage2D(GL_TEXTURE_2D,0,3,
00466                           env_image_x,env_image_y,
00467                           0,GL_RGB,GL_UNSIGNED_BYTE,
00468                           (GLvoid *)env_image);
00469    SetMappingQuality(); // THIS IS NEEDED -see function
00470    X__Free(env_image);
00471  }
00472  strcpy(envB_file,gszHomeDir); strcat(envB_file,"bumpy.bmp");
00473  if((envB_image=LoadSystemMAP(TRUE,FALSE,envB_file,&envB_image_x,&envB_image_y)) != NULL){
00474    glBindTexture(GL_TEXTURE_2D,g_envB_texture);
00475    glTexImage2D(GL_TEXTURE_2D,0,3,
00476                           envB_image_x,envB_image_y,
00477                           0,GL_RGB,GL_UNSIGNED_BYTE,
00478                           (GLvoid *)envB_image);
00479    SetMappingQuality(); // THIS IS NEEDED -see function
00480    X__Free(envB_image);
00481  }
00482  strcpy(envN_file,gszHomeDir); strcat(envN_file,"noise.bmp"); // random number generator
00483  if((envN_image=LoadSystemMAP(TRUE,FALSE,envN_file,&envN_image_x,&envN_image_y)) != NULL){
00484    glBindTexture(GL_TEXTURE_2D,g_envN_texture);
00485    glTexImage2D(GL_TEXTURE_2D,0,3,
00486                           envN_image_x,envN_image_y,
00487                           0,GL_RGB,GL_UNSIGNED_BYTE,
00488                           (GLvoid *)envN_image);
00489    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // for the RAN texture use
00490    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // nearest interpolation
00491 //   SetMappingQuality();  // gives linear interpolation
00492    X__Free(envN_image);
00493  }
00494  MakeParticleTextures();
00495  glBindTexture(GL_TEXTURE_2D,0);
00496  glDisable(GL_TEXTURE_2D);
00497  glEnable(GL_TEXTURE_3D);
00498  glBindTexture(GL_TEXTURE_3D,g_noise_texture);
00499  CreateNoise3D();
00500 
00501  strcpy(env_file,gszHomeDir); strcat(env_file,"genref.bmp");
00502  if((env_image=LoadSystemMAP(TRUE,FALSE,env_file,&env_image_x,&env_image_y)) != NULL){
00503    glBindTexture(GL_TEXTURE_3D,g_env3D_texture);
00504    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00505    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00506    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
00507    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00508    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00509    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB,env_image_x,env_image_y,1, 0, GL_RGB, 
00510                 GL_UNSIGNED_BYTE,(GLvoid *)env_image);
00511    X__Free(env_image);
00512  }
00513 
00514 
00515  glBindTexture(GL_TEXTURE_3D,0);
00516  glDisable(GL_TEXTURE_3D);
00517  glEnable(GL_TEXTURE_2D);
00518  if(bDrawToPbuffer)wglMakeCurrent( m_hDCWnd, m_hGLRCWnd );
00519  return hWnd; 
00520 }
00521 
00522 void SetUpCorrectContext(BOOL bSetup){
00523   if(bDrawToPbuffer){
00524     if(bSetup)wglMakeCurrent( m_PBuffer.hDC, m_PBuffer.hGLRC );
00525     else      wglMakeCurrent( m_hDCWnd, m_hGLRCWnd );
00526   }
00527 }
00528 
00529 void CloseGlWindow(void){
00530  if(!bLoaded)return;
00531  //MessageBox(NULL,"Window Closed",NULL,MB_OK);
00532  glDisable(GL_TEXTURE_2D);
00533  glActiveTexture(GL_TEXTURE1); 
00534  glDisable(GL_TEXTURE_2D);
00535  glActiveTexture(GL_TEXTURE2); 
00536  glDisable(GL_TEXTURE_2D);
00537  glActiveTexture(GL_TEXTURE3); 
00538  glDisable(GL_TEXTURE_2D);
00539  glDeleteTextures( 1, &g_check_texture );
00540  glDeleteTextures( 1, &g_map_texture );
00541  glDeleteTextures( 1, &g_bump_texture );
00542  glDeleteTextures( 1, &g_movie_texture );
00543  glDeleteTextures( 1, &g_env_texture );
00544  glDeleteTextures( 1, &g_envB_texture );
00545  glDeleteTextures( 1, &g_envN_texture );
00546  glDeleteTextures( 1, &g_ref_texture );
00547  glDeleteTextures( 1, &g_tran_texture );
00548  glDeleteTextures( 1, &g_sky_texture );
00549  glDeleteTextures( 1, &g_env3D_texture );
00550  glDeleteTextures( 1, &g_noise_texture );
00551  ReleaseParticleTextures();
00552  if(bDrawToFBO){
00553    glDeleteFramebuffersEXT(1,  &g_frameBuffer );
00554    glDeleteRenderbuffersEXT(1, &g_depthRenderBuffer );
00555    //glDeleteRenderbuffersEXT(1, &g_accumRenderBuffer );
00556    glDeleteRenderbuffersEXT(1, &g_colorRenderBuffer );
00557    //glDeleteRenderbuffersEXT(1, &g_stencilRenderBuffer );
00558    glDeleteTextures( 1, &g_framebufferTexture );
00559    glDeleteFramebuffersEXT(1,  &g_frameBuffer2 );
00560    glDeleteRenderbuffersEXT(1, &g_depthRenderBuffer2 );
00561  }
00562  if(bDrawToPbuffer){
00563    if( wglGetCurrentContext() == m_PBuffer.hGLRC )wglMakeCurrent( 0, 0 );
00564    wglDeleteContext( m_PBuffer.hGLRC );
00565    wglReleasePbufferDCARB( m_PBuffer.hPBuffer, m_PBuffer.hDC );
00566    wglDestroyPbufferARB( m_PBuffer.hPBuffer );
00567  }
00568  UnloadShaders();
00569  if( g_hRC != NULL ){
00570   wglMakeCurrent( NULL, NULL );
00571   wglDeleteContext( g_hRC );
00572   g_hRC = NULL;
00573  }
00574  if( g_hDC != NULL ){
00575   ReleaseDC( g_hWnd, g_hDC );
00576   g_hDC = NULL;
00577  }
00578  free(RenderBufferCopy);
00579  RenderBufferCopy=NULL;
00580  if(DepthBufferCopy != NULL)free(DepthBufferCopy);
00581  DepthBufferCopy=NULL;
00582  //free(RenderBufferAccu);
00583  //RenderBufferAccu=NULL;
00584  bLoaded=FALSE;
00585  bRenderOpenGL=FALSE;
00586  UnregisterClass( ClassName, winClass.hInstance );
00587 }
00588 
00589 static BOOL InitPBuffer(void){
00590  HDC hPrimaryDevCtx = wglGetCurrentDC();
00591  int pPixFmtRequirements[] = {
00592                 WGL_DRAW_TO_PBUFFER_ARB, TRUE,      // Enable rendering to buffer
00593                 //WGL_BIND_TO_TEXTURE_RGBA_ARB, TRUE, // Usable as a texture  // not for Anti-alias on nVidia cards // not needed anyway
00594                 WGL_SUPPORT_OPENGL_ARB, TRUE,       // Associate with OpenGL
00595                 WGL_DOUBLE_BUFFER_ARB, FALSE,       // Single-buffered
00596                 WGL_RED_BITS_ARB, 8,                // 8 bits of red minimum
00597                 WGL_GREEN_BITS_ARB, 8,              // 8 bits of green minimum 
00598                 WGL_BLUE_BITS_ARB, 8,               // 8 bits of blue minimum 
00599                 WGL_DEPTH_BITS_ARB, 24,             // 16 bits for depth minimum
00600     WGL_ACCUM_BITS_ARB, 16,             // Accumulation bits
00601     WGL_STENCIL_BITS_ARB, 1,
00602     0                                   // End of list
00603  };
00604  int iPixelFormat;
00605  unsigned int iFormatCount;
00606  int pBufRequirements [] =      {
00607                 // P-Buffer will bind to a 2D texture
00608                 //WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, // not for Anti-alias on nVidia cards
00609                 // P-Buffer will bind to a texture with format RGBA
00610                 //WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB, // not for Anti-alias on nVidia cards
00611                 0
00612  };
00613  wglChoosePixelFormatARB( 
00614                 hPrimaryDevCtx,                     // Device context to query
00615                 (const int*) pPixFmtRequirements,   // List of integer parameters
00616                 NULL,                               // List of float parameters
00617                 1,                                  // Number of formats to return
00618                 &iPixelFormat,                      // The outputted pixel format
00619                 &iFormatCount );                    // Number of outputted formats
00620  if( iFormatCount == 0 )return FALSE;
00621         // Now that we have a device context and a pixel format, we can 
00622         // create the P-Buffer.
00623  m_PBuffer.hPBuffer = wglCreatePbufferARB( 
00624         hPrimaryDevCtx,                     // Window device context
00625                 iPixelFormat,                       // Chosen pixel format
00626                 RENDERBUFFER_WIDTH,                 // P-Buffer width
00627                 RENDERBUFFER_HEIGHT,                // P-Buffer height
00628                 pBufRequirements );                 // No extra attributes
00629 
00630  if( m_PBuffer.hPBuffer == NULL )return FALSE;
00631  m_PBuffer.hDC = wglGetPbufferDCARB( m_PBuffer.hPBuffer );
00632  m_PBuffer.hGLRC = wglCreateContext( m_PBuffer.hDC );
00633  //if(debug != NULL)fprintf(debug,"Pbuffer OK\n");
00634  return TRUE;
00635 }
00636 
00637 
00638 void CopyGLtoFSB(void){
00639  int i,j;
00640  unsigned char *temp;
00641  fullscreenbuffer *f;
00642  f=FullScreenBuffer;
00643  if((temp=(unsigned char *)malloc(ResolutionX*ResolutionY*4)) == NULL)return;
00644  gluScaleImage(GL_RGBA,RENDERBUFFER_WIDTH,RENDERBUFFER_HEIGHT,GL_UNSIGNED_BYTE,RenderBufferCopy,
00645                ResolutionX,ResolutionY,GL_UNSIGNED_BYTE,temp);
00646  for(i=0,j=ResolutionY-1;i<ResolutionY;i++,j--)
00647   memcpy((f+j*ResolutionX),(temp+i*ResolutionX*4),ResolutionX*4);
00648  free(temp);
00649 }
00650 
00651 static void CopyToDepthBuffer(void){
00652  glPixelTransferf(GL_DEPTH_SCALE,10.0);
00653  glPixelTransferf(GL_DEPTH_BIAS,-9.0);
00654  glReadPixels(0,0,TEXTUREBUFFER_WIDTH,TEXTUREBUFFER_HEIGHT,GL_DEPTH_COMPONENT,GL_FLOAT,DepthBufferCopy);
00655  glPixelTransferf(GL_DEPTH_SCALE,1.0);
00656  glPixelTransferf(GL_DEPTH_BIAS,0.0);
00657 }
00658 
00659 void CopyGLtoZbuffer(void){
00660  if(bFillDepthBuffer && DepthBufferCopy != NULL){
00661    int i,j,k;
00662    double *tp,dv,s,a;
00663    GLfloat *temp,*tf,v,vs;
00664 //unsigned char *p;  // TO VIEW THE DEPTH AS A GREY SCALE  
00665 //p=(unsigned char *)(FullScreenBuffer+ResolutionX*(ResolutionY-1));  
00666    if((temp=(GLfloat *)malloc(ResolutionX*ResolutionY*sizeof(GLfloat))) == NULL)return;
00667    a=FrontDepthGL;
00668    dv=BackDepthGL-FrontDepthGL;
00669    s=1.0/DepthScalingGL;
00670    //if(debug != NULL)fprintf(debug,"Copying to zbuffer\n");
00671    gluScaleImage(GL_DEPTH_COMPONENT,TEXTUREBUFFER_WIDTH,TEXTUREBUFFER_HEIGHT,GL_FLOAT,DepthBufferCopy,
00672                ResolutionX,ResolutionY,GL_FLOAT,temp);
00673    // scale and invert for OpenFX depth buffer
00674    for(i=0,j=ResolutionY-1;i<ResolutionY;i++,j--){
00675      tp=(fszBuffer+j*ResolutionX);
00676      tf=(temp+i*ResolutionX);
00677      for(k=0;k<ResolutionX;k++){
00678        v = *tf++;  vs=(pow(v,10.0)*dv+a)*s; *tp = vs; tp++;
00679 //*p = *(p+1) = *(p+2) = (unsigned char)((1.0-pow(v,10.0))*255.0); p += 4;
00680      }
00681 //p -= ResolutionX*8;
00682    }
00683    free(temp);
00684  }
00685 }
00686 
00687 static void SetMappingQuality(void){
00688  glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
00689  // We MUST tell OGL how the map is to be applied !!!!!!!!
00690  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00691  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00692 }
00693 
00694 static void makeCheckImageMap(int id){
00695  int i, j, c;
00696  if(id == 0){ /* simple checkered map */
00697    for (i = 0; i < checkImageWidth; i++) {
00698      for (j = 0; j < checkImageHeight; j++) {
00699        c = ((((i&0x8)==0)^((j&0x8))==0))*255;
00700        checkImage[i][j][0] = (GLubyte) c;
00701        checkImage[i][j][1] = (GLubyte) c;
00702        checkImage[i][j][2] = (GLubyte) c;
00703      }
00704    }
00705  }
00706 }
00707 
00708 static LRESULT CALLBACK XWindowProc(HWND hWnd, UINT msg,WPARAM wParam,LPARAM lParam){
00709  switch( msg ){
00710    case WM_CREATE:
00711      SetupRenderOpenGL(hWnd);
00712      break;
00713    case WM_SIZE:
00714      g_nWindowWidth  = LOWORD(lParam); 
00715      g_nWindowHeight = HIWORD(lParam);
00716      break;
00717    case WM_CLOSE: break;    // cancel
00718    case WM_DESTROY: break;
00719    case WM_PAINT:{
00720        HDC hDC;
00721        PAINTSTRUCT  ps;
00722        hDC = BeginPaint(hWnd, &ps);
00723        hDC = wglGetCurrentDC();
00724        if(!bDrawToScreen && bLoaded && RenderBufferCopy != NULL){ // Render the Preview
00725          glViewport( 0, 0, g_nWindowWidth, g_nWindowHeight );
00726          glClearColor( 0.0f, 0.0f, 1.0f, 1.0f );
00727          glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00728          glMatrixMode( GL_PROJECTION );
00729          glClear( GL_DEPTH_BUFFER_BIT );
00730          glLoadIdentity();
00731          glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0);
00732          glRasterPos2f(0.0,0.0);
00733          glPixelZoom((GLfloat)g_nWindowWidth/(GLfloat)RENDERBUFFER_WIDTH,
00734                      (GLfloat)g_nWindowHeight /(GLfloat)RENDERBUFFER_HEIGHT);
00735          glMatrixMode( GL_MODELVIEW );
00736          glLoadIdentity();
00737          glDrawPixels(RENDERBUFFER_WIDTH,RENDERBUFFER_HEIGHT,GL_RGBA,GL_UNSIGNED_BYTE,RenderBufferCopy);
00738        }
00739        SwapBuffers(hDC);
00740        EndPaint(hWnd, &ps); 
00741      }
00742      break;
00743    case WM_KEYDOWN:{
00744      switch( wParam ){
00745              case VK_ESCAPE:
00746          // if(RenderBufferAccu != NULL){
00747          //   static int c=0;
00748          //   WriteBitmap(RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT,RenderBufferAccu,c++,TRUE);
00749          // }
00750          if(RenderBufferCopy != NULL){
00751            static int c=0;
00752            WriteBitmap(RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT,RenderBufferCopy,c++,TRUE);
00753          }
00754          break;
00755        }
00756      }
00757      break;
00758    default: return DefWindowProc( hWnd, msg, wParam, lParam );
00759  }
00760  return 0;
00761 }
00762 
00763 #define PI_ 3.14159265358979323846
00764 
00765 /*  accFrustum()
00766  *  The first 6 arguments are identical to the glFrustum() call.
00767  *
00768  *  pixdx and pixdy are anti-alias jitter in pixels.
00769  *  Set both equal to 0.0 for no anti-alias jitter.
00770  *  eyedx and eyedy are depth-of field jitter in pixels.
00771  *  Set both equal to 0.0 for no depth of field effects.
00772  *
00773  *  focus is distance from eye to plane in focus.
00774  *  focus must be greater than, but not equal to 0.0.
00775  *
00776  *  Note that accFrustum() calls glTranslatef().  You will
00777  *  probably want to insure that your ModelView matrix has been
00778  *  initialized to identity before calling accFrustum().
00779  */
00780 static void accFrustum(GLdouble left, GLdouble right,
00781     GLdouble bottom, GLdouble top,
00782     GLdouble znear, GLdouble zfar, GLdouble pixdx, GLdouble pixdy, 
00783     GLdouble eyedx, GLdouble eyedy, GLdouble focus)
00784 {
00785     GLdouble xwsize, ywsize; 
00786     GLdouble dx, dy;
00787     GLint viewport[4];
00788 
00789     glGetIntegerv (GL_VIEWPORT, viewport);
00790  
00791     xwsize = right - left;
00792     ywsize = top - bottom;
00793 
00794     dx = -(pixdx*xwsize/(GLdouble) viewport[2] + eyedx*znear/focus);
00795     dy = -(pixdy*ywsize/(GLdouble) viewport[3] + eyedy*znear/focus);
00796     
00797     glMatrixMode(GL_PROJECTION);
00798     glLoadIdentity();
00799     glFrustum (left + dx, right + dx, bottom + dy, top + dy, znear, zfar);
00800     glMatrixMode(GL_MODELVIEW);
00801     glLoadIdentity();
00802     glTranslatef (-eyedx, -eyedy, 0.0);
00803 }
00804 
00805 /*  accPerspective()
00806  * 
00807  *  The first 4 arguments are identical to the gluPerspective() call.
00808  *  pixdx and pixdy are anti-alias jitter in pixels. 
00809  *  Set both equal to 0.0 for no anti-alias jitter.
00810  *  eyedx and eyedy are depth-of field jitter in pixels. 
00811  *  Set both equal to 0.0 for no depth of field effects.
00812  *
00813  *  focus is distance from eye to plane in focus. 
00814  *  focus must be greater than, but not equal to 0.0.
00815  *
00816  *  Note that accPerspective() calls accFrustum().
00817  */
00818 void accPerspective(GLdouble fovy, GLdouble aspect,
00819     GLdouble znear, GLdouble zfar, GLdouble pixdx, GLdouble pixdy,
00820     GLdouble eyedx, GLdouble eyedy, GLdouble focus)
00821 {
00822     GLdouble fov2,left,right,bottom,top;
00823 
00824     fov2 = ((fovy*PI_) / 180.0) / 2.0;
00825 
00826     top = znear / (cos(fov2) / sin(fov2));
00827     bottom = -top;
00828 
00829     right = top * aspect;
00830     left = -right;
00831 
00832     accFrustum (left, right, bottom, top, znear, zfar,
00833     pixdx, pixdy, eyedx, eyedy, focus);
00834 }
00835 
00837 static char szOutFileName[255];
00838 static char bmproot[255]="c:\\bmp_";
00839 
00840 #define BFT_BITMAP 0x4d42
00841 
00842 static void FlipBits(unsigned char *S, long size){
00843   unsigned char t;
00844   int i; for(i=0;i<size/4;i++){
00845     t = *S;
00846     *S = *(S+2);
00847     S+=2; *S=t;
00848     S+=2;
00849   }
00850 }
00851 
00852 static void WriteBitmap(long nx, long ny, unsigned char *S, long f, BOOL b32){
00853  HANDLE hfbm;
00854  DWORD dwRead;
00855  BITMAPFILEHEADER hdr,*lphdr;
00856  BITMAPINFOHEADER bfi,*lpbi;
00857  long imagesize,mx;
00858  if(b32) mx=((nx*32+31)/32) * 4;
00859  else    mx=((nx*24+31)/32) * 4;
00860  sprintf(szOutFileName,"%s%0.4ld.bmp",bmproot,f);
00861  if((hfbm=CreateFile(szOutFileName,GENERIC_WRITE,FILE_SHARE_WRITE,
00862    NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,
00863    (HANDLE)NULL)) == INVALID_HANDLE_VALUE){
00864    MessageBox(NULL,szOutFileName,"File Open Fail",MB_OK);
00865    MessageBeep(MB_OK);
00866    return;
00867  }
00868  lpbi=&bfi;
00869  lpbi->biSize=sizeof(BITMAPINFOHEADER);
00870  lpbi->biWidth=(DWORD)nx;
00871  lpbi->biHeight=(DWORD)ny;
00872  lpbi->biPlanes=1;
00873  if(b32)lpbi->biBitCount=32;
00874  else   lpbi->biBitCount=24;
00875  lpbi->biCompression=BI_RGB;
00876  lpbi->biSizeImage = imagesize = (DWORD)(mx*ny);
00877  lpbi->biXPelsPerMeter=0;
00878  lpbi->biYPelsPerMeter=0;
00879  lpbi->biClrUsed=0;
00880  lpbi->biClrImportant=0;
00881  lphdr=&hdr;
00882  hdr.bfType          = BFT_BITMAP;
00883  hdr.bfSize          = (sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
00884                         + imagesize);
00885  hdr.bfReserved1     = 0;
00886  hdr.bfReserved2     = 0;
00887  hdr.bfOffBits       = (DWORD)sizeof(BITMAPFILEHEADER) + lpbi->biSize;
00888  WriteFile(hfbm,lphdr,sizeof(BITMAPFILEHEADER),&dwRead,(LPOVERLAPPED)NULL);
00889  WriteFile(hfbm,lpbi,sizeof(BITMAPINFOHEADER),&dwRead,(LPOVERLAPPED)NULL);
00890  FlipBits(S,imagesize);
00891  WriteFile(hfbm,S,imagesize,&dwRead,(LPOVERLAPPED)NULL);
00892  FlipBits(S,imagesize);
00893  if(dwRead != imagesize){
00894    MessageBeep(MB_OK);
00895    MessageBox(NULL,"Bad write",NULL,MB_OK);
00896  }
00897  if(!CloseHandle(hfbm)){
00898    MessageBeep(MB_OK);
00899    MessageBox(NULL,"Bad close",NULL,MB_OK);
00900  }
00901  return;
00902 }
00903 
00904 BOOL ChangeScreenResolution (int width, int height, int bitsPerPixel){
00905         DEVMODE dmScreenSettings;                                                                                       // Device Mode
00906         ZeroMemory (&dmScreenSettings, sizeof (DEVMODE));                                       // Make Sure Memory Is Cleared
00907         dmScreenSettings.dmSize                         = sizeof (DEVMODE);                             // Size Of The Devmode Structure
00908         dmScreenSettings.dmPelsWidth            = width;                                                // Select Screen Width
00909         dmScreenSettings.dmPelsHeight           = height;                                               // Select Screen Height
00910         dmScreenSettings.dmBitsPerPel           = bitsPerPixel;                                 // Select Bits Per Pixel
00911         dmScreenSettings.dmFields                       = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
00912         if (ChangeDisplaySettings (&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)        {
00913                 return FALSE;                                                                                                   // Display Change Failed, Return False
00914         }
00915         return TRUE;                                                                                                            // Display Change Was Successful, Return True
00916 }
00917 
00918 static void printGCinfo(char *text){
00919  int sb,db,arb,agb,abb,aab; 
00920  if(debug == NULL)return;
00921  glGetIntegerv(GL_STENCIL_BITS,&sb);
00922  glGetIntegerv(GL_DEPTH_BITS,&db);
00923  glGetIntegerv(GL_ACCUM_BLUE_BITS,&abb);
00924  glGetIntegerv(GL_ACCUM_GREEN_BITS,&agb);
00925  glGetIntegerv(GL_ACCUM_RED_BITS,&arb);
00926  glGetIntegerv(GL_ACCUM_ALPHA_BITS,&aab);
00927  //fprintf(debug,"[%s] stencil bits %ld  depth bits %ld accum-buffer %ld %ld %ld %ld bit\n",text,sb,db,arb,agb,abb,aab);
00928  //fprintf(debug,"Output RenderBufferSize size [%ld %ld]\n",RENDERBUFFER_WIDTH,RENDERBUFFER_HEIGHT);
00929 }
00930 
00931 BOOL CheckGPUhardware(HWND hwnd){
00932  BOOL bOK=TRUE;
00933  const char *p,*vn,*vv,*r;
00934  GLint naux,nlights,maxtxsize,maxviewsize[2],maxtxunits,vers;
00935  HDC hDC;
00936  HGLRC hRC;
00937  PIXELFORMATDESCRIPTOR pfd;
00938  GLuint PixelFormat;
00939  memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
00940  pfd.nSize      = sizeof(PIXELFORMATDESCRIPTOR);
00941  pfd.nVersion   = 1;
00942  pfd.dwFlags    = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
00943  pfd.iPixelType = PFD_TYPE_RGBA;
00944  pfd.cColorBits = 32;
00945  pfd.cDepthBits = 32;     
00946  pfd.cAccumBits = 16;      
00947  pfd.cStencilBits = 1;    
00948  hDC=GetDC(hwnd);
00949  if(hDC == NULL)return FALSE;
00950  if((PixelFormat = ChoosePixelFormat( hDC, &pfd )) == FALSE)return FALSE;
00951  if(SetPixelFormat(hDC,PixelFormat, &pfd) == FALSE)return FALSE;
00952  hRC = wglCreateContext(hDC);
00953  if(hRC == NULL)return FALSE;
00954  wglMakeCurrent(hDC,hRC);
00955  vv=glGetString(GL_VERSION);
00956  vers=vv[0]-48;
00957  if(vers < 2)bOK=FALSE;
00958  //if(debug != NULL)fprintf(debug,"Version %ld\n",vers);
00959  vn=glGetString(GL_VENDOR); 
00960  r=glGetString(GL_RENDERER); 
00961  p=glGetString(GL_EXTENSIONS);
00962  if(strstr(p, "ARB_fragment_program" ) == NULL ||
00963     strstr(p, "ARB_fragment_shader" ) == NULL ||
00964     strstr(p, "ARB_shader_objects" ) == NULL ||
00965     strstr(p, "ARB_vertex_program" ) == NULL ||
00966     strstr(p, "ARB_vertex_shader" ) == NULL ||
00967     strstr(p, "EXT_framebuffer_object" ) == NULL)bOK=FALSE; // no framebuffer
00968  glGetIntegerv(GL_AUX_BUFFERS,&naux);
00969  glGetIntegerv(GL_MAX_LIGHTS,&nlights);
00970  glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxtxsize);
00971  glGetIntegerv(GL_MAX_TEXTURE_UNITS,&maxtxunits);
00972  if(maxtxunits < 4)bOK=FALSE;
00973  glGetIntegerv(GL_MAX_VIEWPORT_DIMS,maxviewsize);
00974  wglMakeCurrent(NULL,NULL);
00975  wglDeleteContext(hRC);
00976  ReleaseDC(hwnd,hDC);
00977  return bOK;
00978 }

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