00001 
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;  
00018 GLuint g_map_texture;
00019 GLuint g_ref_texture;    
00020 GLuint g_bump_texture;   
00021 GLuint g_tran_texture;
00022 GLuint g_movie_texture;  
00023 GLuint g_env_texture;    
00024 GLuint g_env3D_texture;  
00025 GLuint g_envB_texture;   
00026 GLuint g_envN_texture;   
00027 GLuint g_noise_texture;  
00028 GLuint g_sky_texture;    
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;                                                    
00039 static HGLRC m_hGLRCWnd;                                                
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 
00058 static GLuint g_frameBuffer       = 0;
00059 static GLuint g_depthRenderBuffer = 0;
00060 static GLuint g_colorRenderBuffer = 0;
00061 
00062 
00063 
00064 
00065 GLuint g_framebufferTexture = -1;
00066 GLuint g_frameBuffer2=0;
00067 GLuint g_depthRenderBuffer2=0;
00068 
00069 
00070 
00071 int RENDERBUFFER_WIDTH  = 2048;    
00072 int RENDERBUFFER_HEIGHT = 2048;
00073 int TEXTUREBUFFER_WIDTH  = 2048;  
00074 int TEXTUREBUFFER_HEIGHT = 2048;
00075 
00076 
00077 
00078 
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 
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);  
00103  }
00104  else if(bDrawToPbuffer){
00105    wglMakeCurrent( m_PBuffer.hDC, m_PBuffer.hGLRC );
00106    printGCinfo("Pbuffer output");
00107    r=RenderGLtoWGL(frame,ppGL);  
00108    wglMakeCurrent( m_hDCWnd, m_hGLRCWnd );
00109  }
00110  else{
00111    r=RenderGLtoFBO(frame,ppGL);  
00112  }
00113  return r;
00114 }
00115 
00116 static long RenderGLtoFBO(long frame, BOOL ppGL){
00117  int  i,aa;
00118  GLfloat accu;
00119  
00120  glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, g_frameBuffer );
00121  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 
00122                               GL_RENDERBUFFER_EXT, g_colorRenderBuffer );
00123  
00124  
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    
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(); 
00141    
00142    
00143    
00144    
00145    
00146    
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); 
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){ 
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); 
00197  glReadPixels(0,0,RENDERBUFFER_WIDTH,RENDERBUFFER_HEIGHT,GL_RGBA,GL_UNSIGNED_BYTE,RenderBufferCopy);
00198  
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  
00209  
00210  if(bLoaded){ 
00211    DestroyWindow(g_hWnd);
00212    CloseGlWindow();
00213  }
00214  bFillDepthBuffer=bCopyToDepthBuffer; 
00215  
00216  
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){ 
00245      bDrawToFBO=TRUE; bDrawToPbuffer=FALSE;
00246      RENDERBUFFER_WIDTH=Xres; RENDERBUFFER_HEIGHT=Yres;
00247      
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 {  
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  
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  
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  
00314  
00315  
00316  
00317  memset(RenderBufferCopy,64,RENDERBUFFER_WIDTH*RENDERBUFFER_HEIGHT*4);
00318 
00319  gl2Initialize();
00320  if(bDrawToPbuffer){   
00321    InitPBuffer();
00322    wglMakeCurrent( m_PBuffer.hDC, m_PBuffer.hGLRC );
00323  } 
00324  ShadersInit(gszHomeDir,FALSE);
00325  if(bDrawToFBO){
00326    
00327    glGenFramebuffersEXT(1, &g_frameBuffer);
00328    glGenRenderbuffersEXT( 1, &g_colorRenderBuffer );  
00329    glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, g_colorRenderBuffer );
00330    glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_RGBA8, RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT ); 
00331    
00332    
00333    
00334    
00335    
00336    
00337    
00338    
00339    
00340    glGenRenderbuffersEXT( 1, &g_depthRenderBuffer );  
00341    glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, g_depthRenderBuffer );
00342    
00343    glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT );  
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    
00349    }
00350    status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
00351    switch( status )     {
00352      case GL_FRAMEBUFFER_COMPLETE_EXT:
00353                         
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    
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                         
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);  
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    
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);  
00416  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
00417  glShadeModel(GL_SMOOTH);
00418  
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(); 
00425  
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); 
00430  SetMappingQuality(); 
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(); 
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(); 
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  
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(); 
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(); 
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(); 
00480    X__Free(envB_image);
00481  }
00482  strcpy(envN_file,gszHomeDir); strcat(envN_file,"noise.bmp"); 
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); 
00490    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
00491 
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  
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    
00556    glDeleteRenderbuffersEXT(1, &g_colorRenderBuffer );
00557    
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  
00583  
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,      
00593                 
00594                 WGL_SUPPORT_OPENGL_ARB, TRUE,       
00595                 WGL_DOUBLE_BUFFER_ARB, FALSE,       
00596                 WGL_RED_BITS_ARB, 8,                
00597                 WGL_GREEN_BITS_ARB, 8,              
00598                 WGL_BLUE_BITS_ARB, 8,               
00599                 WGL_DEPTH_BITS_ARB, 24,             
00600     WGL_ACCUM_BITS_ARB, 16,             
00601     WGL_STENCIL_BITS_ARB, 1,
00602     0                                   
00603  };
00604  int iPixelFormat;
00605  unsigned int iFormatCount;
00606  int pBufRequirements [] =      {
00607                 
00608                 
00609                 
00610                 
00611                 0
00612  };
00613  wglChoosePixelFormatARB( 
00614                 hPrimaryDevCtx,                     
00615                 (const int*) pPixFmtRequirements,   
00616                 NULL,                               
00617                 1,                                  
00618                 &iPixelFormat,                      
00619                 &iFormatCount );                    
00620  if( iFormatCount == 0 )return FALSE;
00621         
00622         
00623  m_PBuffer.hPBuffer = wglCreatePbufferARB( 
00624         hPrimaryDevCtx,                     
00625                 iPixelFormat,                       
00626                 RENDERBUFFER_WIDTH,                 
00627                 RENDERBUFFER_HEIGHT,                
00628                 pBufRequirements );                 
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  
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 
00665 
00666    if((temp=(GLfloat *)malloc(ResolutionX*ResolutionY*sizeof(GLfloat))) == NULL)return;
00667    a=FrontDepthGL;
00668    dv=BackDepthGL-FrontDepthGL;
00669    s=1.0/DepthScalingGL;
00670    
00671    gluScaleImage(GL_DEPTH_COMPONENT,TEXTUREBUFFER_WIDTH,TEXTUREBUFFER_HEIGHT,GL_FLOAT,DepthBufferCopy,
00672                ResolutionX,ResolutionY,GL_FLOAT,temp);
00673    
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 
00680      }
00681 
00682    }
00683    free(temp);
00684  }
00685 }
00686 
00687 static void SetMappingQuality(void){
00688  glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
00689  
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){ 
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;    
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){ 
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          
00747          
00748          
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 
00766 
00767 
00768 
00769 
00770 
00771 
00772 
00773 
00774 
00775 
00776 
00777 
00778 
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 
00806 
00807 
00808 
00809 
00810 
00811 
00812 
00813 
00814 
00815 
00816 
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;                                                                                       
00906         ZeroMemory (&dmScreenSettings, sizeof (DEVMODE));                                       
00907         dmScreenSettings.dmSize                         = sizeof (DEVMODE);                             
00908         dmScreenSettings.dmPelsWidth            = width;                                                
00909         dmScreenSettings.dmPelsHeight           = height;                                               
00910         dmScreenSettings.dmBitsPerPel           = bitsPerPixel;                                 
00911         dmScreenSettings.dmFields                       = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
00912         if (ChangeDisplaySettings (&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)        {
00913                 return FALSE;                                                                                                   
00914         }
00915         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  
00928  
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  
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; 
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 }