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 }