00001
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "stdopengl.h"
00029
00030 #ifdef NL_OS_WINDOWS
00031
00032 #define WIN32_LEAN_AND_MEAN
00033 #include <windows.h>
00034 #include <windowsx.h>
00035 #include <string>
00036
00037
00038 #else // NL_OS_UNIX
00039
00040 #include <GL/glx.h>
00041
00042 #endif // NL_OS_UNIX
00043
00044 #include <vector>
00045 #include <GL/gl.h>
00046
00047 #include "nel/3d/viewport.h"
00048 #include "nel/3d/scissor.h"
00049 #include "nel/3d/u_driver.h"
00050 #include "3d/vertex_buffer.h"
00051 #include "3d/light.h"
00052 #include "3d/primitive_block.h"
00053 #include "nel/misc/rect.h"
00054 #include "nel/misc/di_event_emitter.h"
00055 #include "driver_opengl_vertex_buffer_hard.h"
00056
00057
00058 using namespace std;
00059 using namespace NLMISC;
00060
00061
00062
00063
00064
00065 #define NL3D_DRV_VERTEXARRAY_AGP_INIT_SIZE (16384*1024)
00066
00067
00068
00069 #ifdef NL_OS_WINDOWS
00070
00071 BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved)
00072 {
00073 if (fdwReason == DLL_PROCESS_ATTACH)
00074 {
00075
00076
00077 }
00078 return true;
00079 }
00080 #endif
00081
00082
00083 namespace NL3D
00084 {
00085
00086 #ifdef NL_OS_WINDOWS
00087 uint CDriverGL::_Registered=0;
00088 #endif // NL_OS_WINDOWS
00089
00090
00091 const uint32 CDriverGL::ReleaseVersion = 0x8;
00092
00093 #ifdef NL_OS_WINDOWS
00094
00095 __declspec(dllexport) IDriver* NL3D_createIDriverInstance ()
00096 {
00097 return new CDriverGL;
00098 }
00099
00100 __declspec(dllexport) uint32 NL3D_interfaceVersion ()
00101 {
00102 return IDriver::InterfaceVersion;
00103 }
00104
00105 static void GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
00106 {
00107 if(message == WM_SIZE)
00108 {
00109 RECT rect;
00110 if (driver != NULL)
00111 {
00112 GetClientRect (driver->_hWnd, &rect);
00113
00114
00115 driver->_WindowWidth = rect.right-rect.left;
00116 driver->_WindowHeight = rect.bottom-rect.top;
00117 }
00118 }
00119
00120 if (driver->_EventEmitter.getNumEmitters() > 0)
00121 {
00122 CWinEventEmitter *we = NLMISC::safe_cast<CWinEventEmitter *>(driver->_EventEmitter.getEmitter(0));
00123
00124 we->setHWnd((uint32)hWnd);
00125 we->processMessage ((uint32)hWnd, message, wParam, lParam);
00126 }
00127 }
00128
00129 static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
00130 {
00131
00132 CDriverGL *pDriver=(CDriverGL*)GetWindowLong (hWnd, GWL_USERDATA);
00133 if (pDriver != NULL)
00134 {
00135 GlWndProc (pDriver, hWnd, message, wParam, lParam);
00136 }
00137 return DefWindowProc(hWnd, message, wParam, lParam);
00138 }
00139
00140 #elif defined (NL_OS_UNIX)
00141
00142 extern "C"
00143 {
00144 IDriver* NL3D_createIDriverInstance ()
00145 {
00146 return new CDriverGL;
00147 }
00148
00149 uint32 NL3D_interfaceVersion ()
00150 {
00151 return IDriver::InterfaceVersion;
00152 }
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 #endif // NL_OS_UNIX
00169
00170
00171
00172 CDriverGL::CDriverGL()
00173 {
00174 _OffScreen = false;
00175
00176 #ifdef NL_OS_WINDOWS
00177 _PBuffer = NULL;
00178 _hWnd = NULL;
00179 _hRC = NULL;
00180 _hDC = NULL;
00181 _NeedToRestaureGammaRamp = false;
00182 #elif defined (NL_OS_UNIX) // NL_OS_WINDOWS
00183
00184 cursor = None;
00185
00186 #ifdef XF86VIDMODE
00187
00188 memset(&_OldScreenMode, 0, sizeof(_OldScreenMode));
00189 #endif //XF86VIDMODE
00190
00191 #endif // NL_OS_UNIX
00192
00193 _FullScreen= false;
00194
00195 _CurrentMaterial=NULL;
00196 _Initialized = false;
00197
00198 _FogEnabled= false;
00199 _CurrentFogColor[0]= 0;
00200 _CurrentFogColor[1]= 0;
00201 _CurrentFogColor[2]= 0;
00202 _CurrentFogColor[3]= 0;
00203
00204
00205 _LightSetupDirty= false;
00206 _ModelViewMatrixDirty= false;
00207 _RenderSetupDirty= false;
00208
00209
00210 _CurrentGlNormalize= false;
00211 _ForceNormalize= false;
00212
00213 _AGPVertexArrayRange= NULL;
00214 _VRAMVertexArrayRange= NULL;
00215 _CurrentVertexArrayRange= NULL;
00216 _CurrentVertexBufferHard= NULL;
00217 _NVCurrentVARPtr= NULL;
00218 _NVCurrentVARSize= 0;
00219 _SupportVBHard= false;
00220 _SlowUnlockVBHard= false;
00221 _MaxVerticesByVBHard= 0;
00222
00223 _AllocatedTextureMemory= 0;
00224
00225 _ForceDXTCCompression= false;
00226 _ForceTextureResizePower= 0;
00227
00228 _SumTextureMemoryUsed = false;
00229
00230 _NVTextureShaderEnabled = false;
00231
00232
00233
00234 uint i;
00235 _MaterialAllTextureTouchedFlag= 0;
00236 for(i=0; i < IDRV_MAT_MAXTEXTURES; i++)
00237 {
00238 _MaterialAllTextureTouchedFlag|= IDRV_TOUCHED_TEX[i];
00239 _CurrentTexAddrMode[i] = GL_NONE;
00240 }
00241
00242
00243 _UserTexMatEnabled = 0;
00244
00245
00246 _LastVertexSetupIsLightMap= false;
00247 for(i=0; i < IDRV_MAT_MAXTEXTURES; i++)
00248 _LightMapUVMap[i]= -1;
00249
00250 _LightMapLUT.resize(NL3D_DRV_MAX_LIGHTMAP);
00251
00252 _LightMapLastStageEnv.Env.OpAlpha= CMaterial::Replace;
00253 _LightMapLastStageEnv.Env.SrcArg0Alpha= CMaterial::Texture;
00254 _LightMapLastStageEnv.Env.OpArg0Alpha= CMaterial::SrcAlpha;
00255
00256 _ProjMatDirty = true;
00257
00258 std::fill(_StageSupportEMBM, _StageSupportEMBM + IDRV_MAT_MAXTEXTURES, false);
00259
00261
00262 }
00263
00264
00265
00266 CDriverGL::~CDriverGL()
00267 {
00268 release();
00269 }
00270
00271
00272 bool CDriverGL::init()
00273 {
00274 #ifdef WIN32
00275 WNDCLASS wc;
00276
00277 if (!_Registered)
00278 {
00279 memset(&wc,0,sizeof(wc));
00280 wc.style = CS_HREDRAW | CS_VREDRAW ;
00281 wc.lpfnWndProc = (WNDPROC)WndProc;
00282 wc.cbClsExtra = 0;
00283 wc.cbWndExtra = 0;
00284 wc.hInstance = GetModuleHandle(NULL);
00285 wc.hIcon = NULL;
00286 wc.hCursor = LoadCursor(NULL,IDC_ARROW);
00287 wc.hbrBackground = WHITE_BRUSH;
00288 wc.lpszClassName = "NLClass";
00289 wc.lpszMenuName = NULL;
00290 if ( !RegisterClass(&wc) )
00291 {
00292 return false;
00293 }
00294 _Registered=1;
00295 }
00296
00297
00298 HDC dc = CreateDC ("DISPLAY", NULL, NULL, NULL);
00299 if (dc)
00300 {
00301 _NeedToRestaureGammaRamp = GetDeviceGammaRamp (dc, _GammaRampBackuped) != FALSE;
00302
00303
00304 ReleaseDC (NULL, dc);
00305 }
00306 else
00307 {
00308 nlwarning ("(CDriverGL::init): can't create DC");
00309 }
00310
00311 #endif
00312 return true;
00313 }
00314
00315
00316
00317 ModeList CDriverGL::enumModes()
00318 {
00319 ModeList ML;
00320 #ifdef NL_OS_WINDOWS
00321 DEVMODE devmode;
00322 sint n;
00323 GfxMode Mode;
00324
00325 n=0;
00326 while( EnumDisplaySettings(NULL, n, &devmode) )
00327 {
00328 Mode.Windowed=false;
00329 Mode.Width=(uint16)devmode.dmPelsWidth;
00330 Mode.Height=(uint16)devmode.dmPelsHeight;
00331 Mode.Depth=(uint8)devmode.dmBitsPerPel;
00332 ML.push_back(Mode);
00333 n++;
00334 }
00335 #endif // NL_OS_WINDOWS
00336 return ML;
00337 }
00338
00339
00340
00341 void CDriverGL::disableHardwareVertexProgram()
00342 {
00343 _Extensions.DisableHardwareVertexProgram= true;
00344 }
00345
00346 void CDriverGL::disableHardwareVertexArrayAGP()
00347 {
00348 _Extensions.DisableHardwareVertexArrayAGP= true;
00349 }
00350
00351 void CDriverGL::disableHardwareTextureShader()
00352 {
00353 _Extensions.DisableHardwareTextureShader= true;
00354 }
00355
00356
00357
00358 bool CDriverGL::setDisplay(void *wnd, const GfxMode &mode) throw(EBadDisplay)
00359 {
00360 uint width = mode.Width;
00361 uint height = mode.Height;
00362
00363 #ifdef NL_OS_WINDOWS
00364
00365
00366
00367
00368 int pf;
00369
00370 _OffScreen = mode.OffScreen;
00371
00372
00373 _PBuffer = NULL;
00374 _hWnd = NULL;
00375 _WindowWidth = _WindowHeight = 0;
00376 _hRC = NULL;
00377 _hDC = NULL;
00378
00379
00380 if (_OffScreen)
00381 {
00382
00383
00384 ULONG WndFlags=WS_OVERLAPPEDWINDOW+WS_CLIPCHILDREN+WS_CLIPSIBLINGS;
00385 WndFlags&=~WS_VISIBLE;
00386 RECT WndRect;
00387 WndRect.left=0;
00388 WndRect.top=0;
00389 WndRect.right=width;
00390 WndRect.bottom=height;
00391 AdjustWindowRect(&WndRect,WndFlags,FALSE);
00392 HWND tmpHWND = CreateWindow( "NLClass",
00393 "",
00394 WndFlags,
00395 CW_USEDEFAULT,CW_USEDEFAULT,
00396 WndRect.right,WndRect.bottom,
00397 NULL,
00398 NULL,
00399 GetModuleHandle(NULL),
00400 NULL);
00401 if (!tmpHWND)
00402 {
00403 nlwarning ("CDriverGL::setDisplay: CreateWindow failed");
00404 return false;
00405 }
00406
00407
00408 RECT rc;
00409 SetRect (&rc, 0, 0, width, height);
00410 _WindowWidth = width;
00411 _WindowHeight = height;
00412 AdjustWindowRectEx (&rc, GetWindowStyle (_hWnd), GetMenu (_hWnd) != NULL, GetWindowExStyle (_hWnd));
00413 SetWindowPos (_hWnd, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
00414
00415
00416 HDC tempHDC = GetDC(tmpHWND);
00417
00418 _Depth=GetDeviceCaps(tempHDC,BITSPIXEL);
00419
00420
00421 memset(&_pfd,0,sizeof(_pfd));
00422 _pfd.nSize = sizeof(_pfd);
00423 _pfd.nVersion = 1;
00424 _pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
00425 _pfd.iPixelType = PFD_TYPE_RGBA;
00426 _pfd.cColorBits = (char)_Depth;
00427
00428
00429 if(_Depth<=16)
00430 {
00431 _pfd.cDepthBits = 16;
00432 }
00433 else
00434 {
00435 _pfd.cDepthBits = 24;
00436 _pfd.cAlphaBits = 8;
00437 }
00438 _pfd.iLayerType = PFD_MAIN_PLANE;
00439 pf=ChoosePixelFormat(tempHDC,&_pfd);
00440 if (!pf)
00441 {
00442 nlwarning ("CDriverGL::setDisplay: ChoosePixelFormat failed");
00443 DestroyWindow (tmpHWND);
00444 return false;
00445 }
00446 if ( !SetPixelFormat(tempHDC,pf,&_pfd) )
00447 {
00448 nlwarning ("CDriverGL::setDisplay: SetPixelFormat failed");
00449 DestroyWindow (tmpHWND);
00450 return false;
00451 }
00452
00453
00454 HGLRC tempGLRC = wglCreateContext(tempHDC);
00455 if (tempGLRC == NULL)
00456 {
00457 DWORD error = GetLastError ();
00458 nlwarning ("CDriverGL::setDisplay: wglCreateContext failed: 0x%x", error);
00459 DestroyWindow (tmpHWND);
00460 _PBuffer = NULL;
00461 _hWnd = NULL;
00462 _hRC = NULL;
00463 _hDC = NULL;
00464 return false;
00465 }
00466
00467
00468 if (!wglMakeCurrent(tempHDC,tempGLRC))
00469 {
00470 DWORD error = GetLastError ();
00471 nlwarning ("CDriverGL::setDisplay: wglMakeCurrent failed: 0x%x", error);
00472 wglDeleteContext (tempGLRC);
00473 DestroyWindow (tmpHWND);
00474 _PBuffer = NULL;
00475 _hWnd = NULL;
00476 _hRC = NULL;
00477 _hDC = NULL;
00478 return false;
00479 }
00480
00481
00482 registerWGlExtensions (_Extensions, tempHDC);
00483
00484 HDC hdc = wglGetCurrentDC ();
00485 if (hdc == NULL)
00486 {
00487 DWORD error = GetLastError ();
00488 nlwarning ("CDriverGL::setDisplay: wglGetCurrentDC failed: 0x%x", error);
00489 DestroyWindow (tmpHWND);
00490 _PBuffer = NULL;
00491 _hWnd = NULL;
00492 _hRC = NULL;
00493 _hDC = NULL;
00494 return false;
00495 }
00496
00497
00498
00499 int iattributes[2*20];
00500 float fattributes[2*20];
00501 int nfattribs = 0;
00502 int niattribs = 0;
00503
00504
00505
00506 for ( int a = 0; a < 2*20; a++ )
00507 {
00508 iattributes[a] = 0;
00509 fattributes[a] = 0;
00510 }
00511
00512
00513
00514 iattributes[2*niattribs ] = WGL_DRAW_TO_PBUFFER_ARB;
00515 iattributes[2*niattribs+1] = true;
00516 niattribs++;
00517
00518
00519 iattributes[2*niattribs ] = WGL_DEPTH_BITS_ARB;
00520 iattributes[2*niattribs+1] = 24;
00521 niattribs++;
00522
00523
00524 iattributes[2*niattribs ] = WGL_RED_BITS_ARB;
00525 iattributes[2*niattribs+1] = 8;
00526 niattribs++;
00527 iattributes[2*niattribs ] = WGL_GREEN_BITS_ARB;
00528 iattributes[2*niattribs+1] = 8;
00529 niattribs++;
00530 iattributes[2*niattribs ] = WGL_BLUE_BITS_ARB;
00531 iattributes[2*niattribs+1] = 8;
00532 niattribs++;
00533 iattributes[2*niattribs ] = WGL_ALPHA_BITS_ARB;
00534 iattributes[2*niattribs+1] = 8;
00535 niattribs++;
00536
00537
00538
00539 int pformat[20];
00540 unsigned int nformats;
00541 if ( !wglChoosePixelFormatARB ( hdc, iattributes, fattributes,
00542 20, pformat, &nformats ) )
00543 {
00544 nlwarning ( "pbuffer creation error: Couldn't find a suitable pixel format.\n" );
00545 wglDeleteContext (tempGLRC);
00546 DestroyWindow (tmpHWND);
00547 return false;
00548 }
00549
00550
00551
00552
00553 int iattributes2[1] = {0};
00554
00555 _PBuffer = wglCreatePbufferARB( hdc, pformat[0], width, height, iattributes2 );
00556 if (_PBuffer == NULL)
00557 {
00558 DWORD error = GetLastError ();
00559 nlwarning ("CDriverGL::setDisplay: wglCreatePbufferARB failed: 0x%x", error);
00560 wglDeleteContext (tempGLRC);
00561 DestroyWindow (tmpHWND);
00562 _PBuffer = NULL;
00563 _hWnd = NULL;
00564 _hRC = NULL;
00565 _hDC = NULL;
00566 return false;
00567 }
00568
00569
00570 if ( !wglQueryPbufferARB( _PBuffer, WGL_PBUFFER_WIDTH_ARB, (int*)&width ) )
00571 {
00572 DWORD error = GetLastError ();
00573 nlwarning ("CDriverGL::setDisplay: wglQueryPbufferARB failed: 0x%x", error);
00574 wglDeleteContext (tempGLRC);
00575 DestroyWindow (tmpHWND);
00576 _PBuffer = NULL;
00577 _hWnd = NULL;
00578 _hRC = NULL;
00579 _hDC = NULL;
00580 return false;
00581 }
00582 if ( !wglQueryPbufferARB( _PBuffer, WGL_PBUFFER_HEIGHT_ARB, (int*)&height ) )
00583 {
00584 DWORD error = GetLastError ();
00585 nlwarning ("CDriverGL::setDisplay: wglQueryPbufferARB failed: 0x%x", error);
00586 wglDeleteContext (tempGLRC);
00587 DestroyWindow (tmpHWND);
00588 _PBuffer = NULL;
00589 _hWnd = NULL;
00590 _hRC = NULL;
00591 _hDC = NULL;
00592 return false;
00593 }
00594 _WindowWidth = width;
00595 _WindowHeight = height;
00596
00597
00598
00599 _hDC = wglGetPbufferDCARB( _PBuffer );
00600 if (_hDC == NULL)
00601 {
00602 DWORD error = GetLastError ();
00603 nlwarning ("CDriverGL::setDisplay: wglGetPbufferDCARB failed: 0x%x", error);
00604 wglDestroyPbufferARB( _PBuffer );
00605 wglDeleteContext (tempGLRC);
00606 DestroyWindow (tmpHWND);
00607 _PBuffer = NULL;
00608 _hWnd = NULL;
00609 _hRC = NULL;
00610 _hDC = NULL;
00611 return false;
00612 }
00613
00614
00615
00616
00617 _hRC = wglCreateContext( _hDC );
00618 if (_hRC == NULL)
00619 {
00620 DWORD error = GetLastError ();
00621 nlwarning ("CDriverGL::setDisplay: wglCreateContext failed: 0x%x", error);
00622 wglReleasePbufferDCARB( _PBuffer, _hDC );
00623 wglDestroyPbufferARB( _PBuffer );
00624 wglDeleteContext (tempGLRC);
00625 DestroyWindow (tmpHWND);
00626 _PBuffer = NULL;
00627 _hWnd = NULL;
00628 _hRC = NULL;
00629 _hDC = NULL;
00630 return false;
00631 }
00632
00633
00634 _Depth = GetDeviceCaps (_hDC, BITSPIXEL);
00635
00636
00637 if (!wglDeleteContext (tempGLRC))
00638 {
00639 DWORD error = GetLastError ();
00640 nlwarning ("CDriverGL::setDisplay: wglDeleteContext failed: 0x%x", error);
00641 }
00642
00643
00644 if (!DestroyWindow (tmpHWND))
00645 nlwarning ("CDriverGL::setDisplay: DestroyWindow failed");
00646
00647
00648
00649
00650 if (!wglMakeCurrent(_hDC,_hRC))
00651 {
00652 DWORD error = GetLastError ();
00653 nlwarning ("CDriverGL::setDisplay: wglMakeCurrent failed: 0x%x", error);
00654 wglDeleteContext (_hRC);
00655 wglReleasePbufferDCARB( _PBuffer, _hDC );
00656 wglDestroyPbufferARB( _PBuffer );
00657 DestroyWindow (tmpHWND);
00658 _PBuffer = NULL;
00659 _hWnd = NULL;
00660 _hRC = NULL;
00661 _hDC = NULL;
00662 return false;
00663 }
00664 }
00665 else
00666 {
00667 _FullScreen= false;
00668 if (wnd)
00669 {
00670 _hWnd=(HWND)wnd;
00671 _DestroyWindow=false;
00672 }
00673 else
00674 {
00675 ULONG WndFlags;
00676 RECT WndRect;
00677
00678
00679 _DestroyWindow=true;
00680
00681 if(mode.Windowed)
00682 WndFlags=WS_OVERLAPPEDWINDOW+WS_CLIPCHILDREN+WS_CLIPSIBLINGS;
00683 else
00684 {
00685 WndFlags=WS_POPUP;
00686
00687 _FullScreen= true;
00688 DEVMODE devMode;
00689 _OldScreenMode.dmSize= sizeof(DEVMODE);
00690 _OldScreenMode.dmDriverExtra= 0;
00691 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &_OldScreenMode);
00692 _OldScreenMode.dmFields= DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY ;
00693
00694 devMode.dmSize= sizeof(DEVMODE);
00695 devMode.dmDriverExtra= 0;
00696 devMode.dmFields= DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
00697 devMode.dmPelsWidth= width;
00698 devMode.dmPelsHeight= height;
00699 devMode.dmBitsPerPel= mode.Depth;
00700 ChangeDisplaySettings(&devMode, CDS_FULLSCREEN);
00701 }
00702 WndRect.left=0;
00703 WndRect.top=0;
00704 WndRect.right=width;
00705 WndRect.bottom=height;
00706 AdjustWindowRect(&WndRect,WndFlags,FALSE);
00707 _hWnd = CreateWindow( "NLClass",
00708 "",
00709 WndFlags,
00710 CW_USEDEFAULT,CW_USEDEFAULT,
00711 WndRect.right,WndRect.bottom,
00712 NULL,
00713 NULL,
00714 GetModuleHandle(NULL),
00715 NULL);
00716 if (!_hWnd)
00717 {
00718 return false;
00719 }
00720
00721 SetWindowLong (_hWnd, GWL_USERDATA, (LONG)this);
00722
00723
00724 RECT rc;
00725 SetRect (&rc, 0, 0, width, height);
00726 AdjustWindowRectEx (&rc, GetWindowStyle (_hWnd), GetMenu (_hWnd) != NULL, GetWindowExStyle (_hWnd));
00727 SetWindowPos (_hWnd, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
00728
00729 ShowWindow(_hWnd,SW_SHOW);
00730 }
00731
00732
00733 RECT clientRect;
00734 GetClientRect (_hWnd, &clientRect);
00735 _WindowWidth = clientRect.right-clientRect.left;
00736 _WindowHeight = clientRect.bottom-clientRect.top;
00737
00738 _hDC=GetDC(_hWnd);
00739 wglMakeCurrent(_hDC,NULL);
00740 _Depth=GetDeviceCaps(_hDC,BITSPIXEL);
00741
00742 memset(&_pfd,0,sizeof(_pfd));
00743 _pfd.nSize = sizeof(_pfd);
00744 _pfd.nVersion = 1;
00745 _pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
00746 _pfd.iPixelType = PFD_TYPE_RGBA;
00747 _pfd.cColorBits = (char)_Depth;
00748
00749 if(_Depth<=16)
00750 {
00751 _pfd.cDepthBits = 16;
00752 }
00753 else
00754 {
00755 _pfd.cDepthBits = 24;
00756 _pfd.cAlphaBits = 8;
00757 }
00758 _pfd.iLayerType = PFD_MAIN_PLANE;
00759 pf=ChoosePixelFormat(_hDC,&_pfd);
00760 if (!pf)
00761 {
00762 return false;
00763 }
00764
00765 if ( !SetPixelFormat(_hDC,pf,&_pfd) )
00766 {
00767 return false;
00768 }
00769 _hRC=wglCreateContext(_hDC);
00770 wglMakeCurrent(_hDC,_hRC);
00771 }
00772
00774 while (_EventEmitter.getNumEmitters() != 0)
00775 {
00776 _EventEmitter.removeEmitter(_EventEmitter.getEmitter(_EventEmitter.getNumEmitters() - 1));
00777 }
00778 NLMISC::CWinEventEmitter *we = new NLMISC::CWinEventEmitter;
00779
00780 _EventEmitter.addEmitter(we, true );
00782
00783 {
00784 NLMISC::CDIEventEmitter *diee = NLMISC::CDIEventEmitter::create(GetModuleHandle(NULL), _hWnd, we);
00785 if (diee)
00786 {
00787 _EventEmitter.addEmitter(diee, true);
00788 }
00789 }
00790 catch(EDirectInput &e)
00791 {
00792 nlinfo(e.what());
00793 }
00794
00795 #elif defined(NL_OS_UNIX) // NL_OS_WINDOWS
00796
00797 dpy = XOpenDisplay(NULL);
00798 if (dpy == NULL)
00799 {
00800 nlerror ("XOpenDisplay failed on '%s'",getenv("DISPLAY"));
00801 }
00802 else
00803 {
00804 nldebug("XOpenDisplay on '%s' OK", getenv("DISPLAY"));
00805 }
00806
00807 int sAttribList[] =
00808 {
00809 GLX_RGBA,
00810 GLX_DOUBLEBUFFER,
00811
00812 GLX_DEPTH_SIZE, 16,
00813 GLX_RED_SIZE, 4,
00814 GLX_GREEN_SIZE, 4,
00815 GLX_BLUE_SIZE, 4,
00816
00817 None
00818 };
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833 XVisualInfo *visual_info = glXChooseVisual (dpy, DefaultScreen(dpy), sAttribList);
00834
00835 if(visual_info == NULL)
00836 {
00837 nlerror("glXChooseVisual() failed");
00838 }
00839 else
00840 {
00841 nldebug("glXChooseVisual OK");
00842 }
00843
00844 ctx = glXCreateContext (dpy, visual_info, None, GL_TRUE);
00845
00846 if(ctx == NULL)
00847 {
00848 nlerror("glXCreateContext() failed");
00849 }
00850 else
00851 {
00852 nldebug("glXCreateContext() OK");
00853 }
00854
00855 Colormap cmap = XCreateColormap (dpy, RootWindow(dpy, DefaultScreen(dpy)), visual_info->visual, AllocNone);
00856
00857 XSetWindowAttributes attr;
00858 attr.colormap = cmap;
00859 attr.background_pixel = BlackPixel(dpy, DefaultScreen(dpy));
00860
00861 #ifdef XF86VIDMODE
00862
00863
00864
00865 if (mode.Windowed)
00866 {
00867 attr.override_redirect = False;
00868 }
00869 else
00870 {
00871 attr.override_redirect = True;
00872 }
00873 #else
00874 attr.override_redirect = False;
00875 #endif
00876
00877 int attr_flags = CWOverrideRedirect | CWColormap | CWBackPixel;
00878
00879 win = XCreateWindow (dpy, RootWindow(dpy, DefaultScreen(dpy)), 0, 0, width, height, 0, visual_info->depth, InputOutput, visual_info->visual, attr_flags, &attr);
00880
00881 if(!win)
00882 {
00883 nlerror("XCreateWindow() failed");
00884 }
00885 else
00886 {
00887 nldebug("XCreateWindow() OK");
00888 }
00889
00890 XSizeHints size_hints;
00891 size_hints.x = 0;
00892 size_hints.y = 0;
00893 size_hints.width = width;
00894 size_hints.height = height;
00895 size_hints.flags = PSize | PMinSize | PMaxSize;
00896 size_hints.min_width = width;
00897 size_hints.min_height = height;
00898 size_hints.max_width = width;
00899 size_hints.max_height = height;
00900
00901 XTextProperty text_property;
00902 char *title="NeL window";
00903 XStringListToTextProperty(&title, 1, &text_property);
00904
00905 XSetWMProperties (dpy, win, &text_property, &text_property, 0, 0, &size_hints, 0, 0);
00906 glXMakeCurrent (dpy, win, ctx);
00907 XMapRaised (dpy, win);
00908
00909 XSelectInput (dpy, win,
00910 KeyPressMask|
00911 KeyReleaseMask|
00912 ButtonPressMask|
00913 ButtonReleaseMask|
00914 PointerMotionMask
00915 );
00916
00917 XMapWindow(dpy, win);
00918
00919 _EventEmitter.init (dpy, win);
00920
00921
00922
00923
00924 #ifdef XF86VIDMODE
00925 if (!mode.Windowed)
00926 {
00927
00928
00929
00930 XResizeWindow(dpy,win,width,height);
00931 XMapRaised(dpy,win);
00932 XRaiseWindow(dpy, win);
00933
00934
00935 if ((XGrabPointer(dpy, win, True, 0,
00936 GrabModeAsync, GrabModeAsync,
00937 win, None, CurrentTime) != GrabSuccess) ||
00938 (XGrabKeyboard(dpy, win, True,
00939 GrabModeAsync, GrabModeAsync, CurrentTime) != 0) )
00940 {
00941
00942
00943 nlerror("Unable to grab keyboard and mouse\n");
00944 }
00945 else
00946 {
00947
00948 memset(&_OldScreenMode, 0, sizeof(_OldScreenMode));
00949 XF86VidModeGetModeLine(dpy,
00950 DefaultScreen(dpy),
00951 &_OldDotClock,
00952 &_OldScreenMode);
00953
00954 XF86VidModeGetViewPort(dpy,
00955 DefaultScreen(dpy),
00956 &_OldX,
00957 &_OldY);
00958
00959
00960 XF86VidModeModeInfo **modes;
00961 int nmodes;
00962 if (XF86VidModeGetAllModeLines(dpy,
00963 DefaultScreen(dpy),
00964 &nmodes,&modes))
00965 {
00966 int mode_index = -1;
00967 for (int i = 0; i < nmodes; i++)
00968 {
00969 nldebug("Available mode - %dx%d\n",width,height);
00970 if( (modes[i]->hdisplay == width) &&
00971 (modes[i]->vdisplay == height))
00972 {
00973 mode_index = i;
00974 }
00975 }
00976
00977 if (mode_index != -1)
00978 {
00979 if(XF86VidModeSwitchToMode(dpy,
00980 DefaultScreen(dpy),
00981 modes[mode_index]))
00982 {
00983 nlinfo("Switching to mode %dx%d,\n",width,
00984 height);
00985 XF86VidModeSetViewPort(dpy,DefaultScreen(dpy),0, 0);
00986 _FullScreen = true;
00987 }
00988 }
00989 else
00990 {
00991
00992
00993
00994 nlerror("Couldn't find an appropriate mode %dx%d\n",
00995 width,
00996 height);
00997 }
00998 }
00999 }
01000 }
01001
01002 #endif // XF86VIDMODE
01003
01004 #endif // NL_OS_UNIX
01005
01006
01007
01008
01009
01010 NL3D::registerGlExtensions (_Extensions);
01011 #ifdef NL_OS_WINDOWS
01012 NL3D::registerWGlExtensions (_Extensions, _hDC);
01013 #endif // ifdef NL_OS_WINDOWS
01014
01015
01016
01017 if(!_Extensions.ARBMultiTexture)
01018 {
01019 nlwarning("Missing Required GL extension: GL_ARB_multitexture. Update your driver");
01020 throw EBadDisplay("Missing Required GL extension: GL_ARB_multitexture. Update your driver");
01021 }
01022 if(!_Extensions.EXTTextureEnvCombine)
01023 {
01024 nlwarning("Missing Important GL extension: GL_EXT_texture_env_combine => All envcombine are setup to GL_MODULATE!!!");
01025 }
01026
01027
01028
01029 _DriverGLStates.init(_Extensions.ARBTextureCubeMap);
01030
01031
01032
01033
01034 glViewport(0,0,width,height);
01035 glMatrixMode(GL_PROJECTION);
01036 glLoadIdentity();
01037 glOrtho(0,width,height,0,-1.0f,1.0f);
01038 glMatrixMode(GL_MODELVIEW);
01039 glLoadIdentity();
01040 glDisable(GL_AUTO_NORMAL);
01041 glDisable(GL_COLOR_MATERIAL);
01042 glEnable(GL_DITHER);
01043 glDisable(GL_FOG);
01044 glDisable(GL_LINE_SMOOTH);
01045 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
01046 glEnable(GL_DEPTH_TEST);
01047 glDisable(GL_NORMALIZE);
01048 _CurrentGlNormalize= false;
01049 _ForceNormalize= false;
01050
01051 _DriverGLStates.forceDefaults(inlGetNumTextStages());
01052
01053 _PZBCameraPos= CVector::Null;
01054
01055 if (_NVTextureShaderEnabled)
01056 {
01057 enableNVTextureShader(false);
01058 }
01059
01060
01061 if(_Extensions.EXTSeparateSpecularColor)
01062 {
01063 glLightModeli((GLenum)GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT);
01064 }
01065
01066 _VertexProgramEnabled= false;
01067 _LastSetupGLArrayVertexProgram= false;
01068
01069
01070
01071 _SupportVBHard= false;
01072 _SlowUnlockVBHard= false;
01073 _MaxVerticesByVBHard= 0;
01074
01075 if(_Extensions.NVVertexArrayRange)
01076 {
01077 _AGPVertexArrayRange= new CVertexArrayRangeNVidia(this);
01078 _VRAMVertexArrayRange= new CVertexArrayRangeNVidia(this);
01079 _SupportVBHard= true;
01080 _MaxVerticesByVBHard= _Extensions.NVVertexArrayRangeMaxVertex;
01081 }
01082
01083 else if(_Extensions.ATIVertexArrayObject)
01084 {
01085 _AGPVertexArrayRange= new CVertexArrayRangeATI(this);
01086 _VRAMVertexArrayRange= new CVertexArrayRangeATI(this);
01087 _SupportVBHard= true;
01088
01089 _SlowUnlockVBHard= true;
01090
01091 _MaxVerticesByVBHard= 32767;
01092 }
01093
01094
01095 _CurrentVertexArrayRange= NULL;
01096 _CurrentVertexBufferHard= NULL;
01097 _NVCurrentVARPtr= NULL;
01098 _NVCurrentVARSize= 0;
01099 if(_SupportVBHard)
01100 {
01101
01102 initVertexArrayRange(NL3D_DRV_VERTEXARRAY_AGP_INIT_SIZE, 0);
01103
01104
01105 if( _AGPVertexArrayRange->sizeAllocated()==0 )
01106 {
01107
01108 resetVertexArrayRange();
01109
01110
01111 delete _AGPVertexArrayRange;
01112 delete _VRAMVertexArrayRange;
01113 _AGPVertexArrayRange= NULL;
01114 _VRAMVertexArrayRange= NULL;
01115
01116
01117 _SupportVBHard= false;
01118 _SlowUnlockVBHard= false;
01119 _MaxVerticesByVBHard= 0;
01120 }
01121 }
01122
01123
01124
01125 initEMBM();
01126
01127
01128
01129
01130 for(sint stage=0;stage<inlGetNumTextStages(); stage++)
01131 {
01132
01133 _CurrentTexture[stage]= NULL;
01134 _CurrentTextureInfoGL[stage]= NULL;
01135
01136
01137
01138 CMaterial::CTexEnv env;
01139 env.ConstantColor.set(255,255,255,255);
01140 forceActivateTexEnvMode(stage, env);
01141 forceActivateTexEnvColor(stage, env);
01142
01143
01144 _CurrentTexEnvSpecial[stage]= TexEnvSpecialDisabled;
01145
01146 resetTextureShaders();
01147 }
01148
01149
01150 int numLight;
01151 glGetIntegerv (GL_MAX_LIGHTS, &numLight);
01152 _MaxDriverLight=(uint)numLight;
01153 if (_MaxDriverLight>MaxLight)
01154 _MaxDriverLight=MaxLight;
01155
01156
01157 for (uint i=0; i<MaxLight; i++)
01158 _LightEnable[i]=false;
01159
01160
01161 _PPLExponent = 1.f;
01162 _PPLightDiffuseColor = NLMISC::CRGBA::White;
01163 _PPLightSpecularColor = NLMISC::CRGBA::White;
01164
01165
01166
01167
01168 glEnable(GL_LIGHT0);
01169
01170 _Initialized = true;
01171
01172 _ForceDXTCCompression= false;
01173 _ForceTextureResizePower= 0;
01174
01175
01176 _AllocatedTextureMemory= 0;
01177 _TextureUsed.clear();
01178 _PrimitiveProfileIn.reset();
01179 _PrimitiveProfileOut.reset();
01180 _NbSetupMaterialCall= 0;
01181 _NbSetupModelMatrixCall= 0;
01182
01183
01184 checkForPerPixelLightingSupport();
01185
01186
01187 if (!_Extensions.NVVertexProgram && _Extensions.EXTVertexShader)
01188 {
01189 _EVSPositionHandle = nglBindParameterEXT(GL_CURRENT_VERTEX_EXT);
01190 _EVSNormalHandle = nglBindParameterEXT(GL_CURRENT_NORMAL);
01191 _EVSColorHandle = nglBindParameterEXT(GL_CURRENT_COLOR);
01192 if (!_EVSPositionHandle || !_EVSNormalHandle || !_EVSColorHandle)
01193 {
01194 nlwarning("Unable to bind input parameters for use with EXT_vertex_shader, vertex program support is disabled");
01195 _Extensions.EXTVertexShader = false;
01196 }
01197 else
01198 {
01199
01200 for(uint k = 0; k < 8; ++k)
01201 {
01202 _EVSTexHandle[k] = nglBindTextureUnitParameterEXT(GL_TEXTURE0_ARB + k, GL_CURRENT_TEXTURE_COORDS);
01203 }
01204
01205
01206
01207
01208
01209
01210
01211
01212 _EVSConstantHandle = nglGenSymbolsEXT(GL_VECTOR_EXT, GL_INVARIANT_EXT, GL_FULL_RANGE_EXT, 97);
01213
01214 if (_EVSConstantHandle == 0)
01215 {
01216 nlwarning("Unable to allocate constants for EXT_vertex_shader, vertex program support is disabled");
01217 _Extensions.EXTVertexShader = false;
01218 }
01219 }
01220 }
01221
01222 return true;
01223 }
01224
01225
01226 void CDriverGL::resetTextureShaders()
01227 {
01228 if (_Extensions.NVTextureShader)
01229 {
01230 glEnable(GL_TEXTURE_SHADER_NV);
01231 for (uint stage = 0; stage < (uint) inlGetNumTextStages(); ++stage)
01232 {
01233 _DriverGLStates.activeTextureARB(stage);
01234 if (stage != 0)
01235 {
01236 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + stage - 1);
01237 }
01238 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
01239 _CurrentTexAddrMode[stage] = GL_NONE;
01240 }
01241 glDisable(GL_TEXTURE_SHADER_NV);
01242 _NVTextureShaderEnabled = false;
01243 }
01244 }
01245
01246
01247
01248 emptyProc CDriverGL::getWindowProc()
01249 {
01250 #ifdef NL_OS_WINDOWS
01251 return (emptyProc)GlWndProc;
01252 #else // NL_OS_WINDOWS
01253 return NULL;
01254 #endif // NL_OS_WINDOWS
01255 }
01256
01257
01258
01259 bool CDriverGL::activate()
01260 {
01261 #ifdef NL_OS_WINDOWS
01262 HGLRC hglrc=wglGetCurrentContext();
01263 if (hglrc!=_hRC)
01264 {
01265 wglMakeCurrent(_hDC,_hRC);
01266 }
01267 #elif defined (NL_OS_UNIX)
01268 GLXContext nctx=glXGetCurrentContext();
01269 if (nctx != NULL && nctx!=ctx)
01270 {
01271 glXMakeCurrent(dpy, win,ctx);
01272 }
01273 #endif // NL_OS_WINDOWS
01274 return true;
01275 }
01276
01277
01278
01279 bool CDriverGL::isTextureExist(const ITexture&tex)
01280 {
01281 bool result;
01282
01283
01284 std::string name;
01285 getTextureShareName (tex, name);
01286
01287 {
01288 CSynchronized<TTexDrvInfoPtrMap>::CAccessor access(&_SyncTexDrvInfos);
01289 TTexDrvInfoPtrMap &rTexDrvInfos = access.value();
01290 result = (rTexDrvInfos.find(name) != rTexDrvInfos.end());
01291 }
01292 return result;
01293 }
01294
01295
01296
01297 bool CDriverGL::clear2D(CRGBA rgba)
01298 {
01299 glClearColor((float)rgba.R/255.0f,(float)rgba.G/255.0f,(float)rgba.B/255.0f,(float)rgba.A/255.0f);
01300 glClear(GL_COLOR_BUFFER_BIT);
01301 return true;
01302 }
01303
01304
01305
01306 bool CDriverGL::clearZBuffer(float zval)
01307 {
01308 glClearDepth(zval);
01309 _DriverGLStates.enableZWrite(true);
01310 glClear(GL_DEPTH_BUFFER_BIT);
01311 return true;
01312 }
01313
01314
01315
01316 void CDriverGL::setColorMask (bool bRed, bool bGreen, bool bBlue, bool bAlpha)
01317 {
01318 glColorMask (bRed, bGreen, bBlue, bAlpha);
01319 }
01320
01321
01322
01323
01324 bool CDriverGL::swapBuffers()
01325 {
01326
01327
01328
01329 if(_CurrentVertexBufferHard)
01330 {
01331
01332 _CurrentVertexBufferHard->lock();
01333 _CurrentVertexBufferHard->unlock();
01334
01335 _CurrentVertexBufferHard->disable();
01336 }
01337
01338
01339
01340 set<IVertexBufferHardGL*>::iterator itVBHard= _VertexBufferHardSet.Set.begin();
01341 while(itVBHard != _VertexBufferHardSet.Set.end() )
01342 {
01343
01344 if((*itVBHard)->NVidiaVertexBufferHard)
01345 {
01346 CVertexBufferHardGLNVidia *vbHardNV= static_cast<CVertexBufferHardGLNVidia*>(*itVBHard);
01347
01348 vbHardNV->finishFence();
01349 vbHardNV->GPURenderingAfterFence= false;
01350 }
01351 itVBHard++;
01352 }
01353
01354
01355
01356
01357 static CVertexBuffer dummyVB;
01358 static bool dummyVBinit= false;
01359 if(!dummyVBinit)
01360 {
01361
01362 dummyVB.setVertexFormat(CVertexBuffer::PositionFlag|CVertexBuffer::NormalFlag|
01363 CVertexBuffer::PrimaryColorFlag|CVertexBuffer::SecondaryColorFlag|
01364 CVertexBuffer::TexCoord0Flag|CVertexBuffer::TexCoord1Flag|
01365 CVertexBuffer::TexCoord2Flag|CVertexBuffer::TexCoord3Flag
01366 );
01367
01368 dummyVB.setNumVertices(10);
01369 }
01370
01371 activeVertexBuffer(dummyVB);
01372
01373
01374 #ifdef NL_OS_WINDOWS
01375 if (_EventEmitter.getNumEmitters() > 1)
01376 {
01377
01378 NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1))->poll();
01379 }
01380 #endif
01381
01382
01383 #ifdef NL_OS_WINDOWS
01384 SwapBuffers(_hDC);
01385 #else // NL_OS_WINDOWS
01386 glXSwapBuffers(dpy, win);
01387 #endif // NL_OS_WINDOWS
01388
01389
01390
01391
01392
01393 for(sint stage=0;stage<inlGetNumTextStages(); stage++)
01394 {
01395
01396 _CurrentTexture[stage]= NULL;
01397 _CurrentTextureInfoGL[stage]= NULL;
01398
01399
01400
01401 CMaterial::CTexEnv env;
01402 env.ConstantColor.set(255,255,255,255);
01403 forceActivateTexEnvMode(stage, env);
01404 forceActivateTexEnvColor(stage, env);
01405 }
01406
01407
01408
01409
01410
01411 _DriverGLStates.forceDefaults(inlGetNumTextStages());
01412 if (_NVTextureShaderEnabled)
01413 {
01414 glDisable(GL_TEXTURE_SHADER_NV);
01415 _NVTextureShaderEnabled = false;
01416 }
01417 _CurrentMaterial= NULL;
01418
01419
01420
01421 _PrimitiveProfileIn.reset();
01422 _PrimitiveProfileOut.reset();
01423 _NbSetupMaterialCall= 0;
01424 _NbSetupModelMatrixCall= 0;
01425
01426
01427 _TextureUsed.clear();
01428
01429 return true;
01430 }
01431
01432
01433
01434 bool CDriverGL::release()
01435 {
01436
01437 if (!_Initialized) return true;
01438
01439
01440 IDriver::release();
01441
01442
01443
01444
01445
01446 resetVertexArrayRange();
01447
01448
01449 delete _AGPVertexArrayRange;
01450 delete _VRAMVertexArrayRange;
01451 _AGPVertexArrayRange= NULL;
01452 _VRAMVertexArrayRange= NULL;
01453
01454 #ifdef NL_OS_WINDOWS
01455
01456
01457
01458
01459 if (_OffScreen)
01460 {
01461 if (_PBuffer)
01462 {
01463 wglDeleteContext( _hRC );
01464 wglReleasePbufferDCARB( _PBuffer, _hDC );
01465 wglDestroyPbufferARB( _PBuffer );
01466 }
01467 }
01468 else
01469 {
01470 if (_hRC)
01471 wglDeleteContext(_hRC);
01472 if (_hWnd&&_hDC)
01473 {
01474 ReleaseDC(_hWnd,_hDC);
01475 if (_DestroyWindow)
01476 DestroyWindow (_hWnd);
01477 }
01478
01479 if(_FullScreen)
01480 {
01481 ChangeDisplaySettings(&_OldScreenMode, 0);
01482 _FullScreen= false;
01483 }
01484 }
01485
01486 _hRC=NULL;
01487 _hDC=NULL;
01488 _hWnd=NULL;
01489 _PBuffer = NULL;
01490
01491
01492 if (_NeedToRestaureGammaRamp)
01493 {
01494 HDC dc = CreateDC ("DISPLAY", NULL, NULL, NULL);
01495 if (dc)
01496 {
01497 if (!SetDeviceGammaRamp (dc, _GammaRampBackuped))
01498 nlwarning ("(CDriverGL::release): SetDeviceGammaRamp failed");
01499
01500
01501 ReleaseDC (NULL, dc);
01502 }
01503 else
01504 {
01505 nlwarning ("(CDriverGL::release): can't create DC");
01506 }
01507 }
01508
01509 #elif defined (NL_OS_UNIX)// NL_OS_WINDOWS
01510
01511 #ifdef XF86VIDMODE
01512 if(_FullScreen)
01513 {
01514 XF86VidModeModeInfo info;
01515 nlinfo("Switching back to original mode \n");
01516
01517
01518
01519 memcpy((XF86VidModeModeLine *)((char *)&info + sizeof(info.dotclock)),&_OldScreenMode, sizeof(XF86VidModeModeLine));
01520 info.dotclock = _OldDotClock;
01521
01522 nlinfo("Mode is %dx%d,\n",info.hdisplay,info.vdisplay);
01523 XF86VidModeSwitchToMode(dpy,DefaultScreen(dpy),&info);
01524 nlinfo("Switching viewporr to %d,%d,\n",_OldX, _OldY);
01525 XF86VidModeSetViewPort(dpy,DefaultScreen(dpy),_OldX,_OldY);
01526
01527 XUngrabKeyboard(dpy, CurrentTime);
01528 }
01529 #endif // XF86VIDMODE
01530
01531 #endif // NL_OS_UNIX
01532
01533
01534
01535 _Initialized= false;
01536
01537 return true;
01538 }
01539
01540
01541
01542 IDriver::TMessageBoxId CDriverGL::systemMessageBox (const char* message, const char* title, IDriver::TMessageBoxType type, TMessageBoxIcon icon)
01543 {
01544 #ifdef NL_OS_WINDOWS
01545 switch (::MessageBox (NULL, message, title, ((type==retryCancelType)?MB_RETRYCANCEL:
01546 (type==yesNoCancelType)?MB_YESNOCANCEL:
01547 (type==okCancelType)?MB_OKCANCEL:
01548 (type==abortRetryIgnoreType)?MB_ABORTRETRYIGNORE:
01549 (type==yesNoType)?MB_YESNO|MB_ICONQUESTION:MB_OK)|
01550
01551 ((icon==handIcon)?MB_ICONHAND:
01552 (icon==questionIcon)?MB_ICONQUESTION:
01553 (icon==exclamationIcon)?MB_ICONEXCLAMATION:
01554 (icon==asteriskIcon)?MB_ICONASTERISK:
01555 (icon==warningIcon)?MB_ICONWARNING:
01556 (icon==errorIcon)?MB_ICONERROR:
01557 (icon==informationIcon)?MB_ICONINFORMATION:
01558 (icon==stopIcon)?MB_ICONSTOP:0)))
01559 {
01560 case IDOK:
01561 return okId;
01562 case IDCANCEL:
01563 return cancelId;
01564 case IDABORT:
01565 return abortId;
01566 case IDRETRY:
01567 return retryId;
01568 case IDIGNORE:
01569 return ignoreId;
01570 case IDYES:
01571 return yesId;
01572 case IDNO:
01573 return noId;
01574 }
01575 nlstop;
01576 #else // NL_OS_WINDOWS
01577
01578 IDriver::systemMessageBox (message, title, type, icon);
01579 #endif // NL_OS_WINDOWS
01580 return okId;
01581 }
01582
01583
01584
01585 void CDriverGL::setupViewport (const class CViewport& viewport)
01586 {
01587 #ifdef NL_OS_WINDOWS
01588 if (_hWnd == NULL) return;
01589
01590
01591 int clientWidth = _WindowWidth;
01592 int clientHeight = _WindowHeight;
01593
01594 #else // NL_OS_WINDOWS
01595
01596 XWindowAttributes win_attributes;
01597 if (!XGetWindowAttributes(dpy, win, &win_attributes))
01598 throw EBadDisplay("Can't get window attributes.");
01599
01600
01601 int clientWidth=win_attributes.width;
01602 int clientHeight=win_attributes.height;
01603
01604 #endif // NL_OS_WINDOWS
01605
01606
01607 float x;
01608 float y;
01609 float width;
01610 float height;
01611 viewport.getValues (x, y, width, height);
01612
01613
01614 int ix=(int)((float)clientWidth*x);
01615 clamp (ix, 0, clientWidth);
01616 int iy=(int)((float)clientHeight*y);
01617 clamp (iy, 0, clientHeight);
01618 int iwidth=(int)((float)clientWidth*width);
01619 clamp (iwidth, 0, clientWidth-ix);
01620 int iheight=(int)((float)clientHeight*height);
01621 clamp (iheight, 0, clientHeight-iy);
01622 glViewport (ix, iy, iwidth, iheight);
01623 }
01624
01625
01626
01627
01628 void CDriverGL::setupScissor (const class CScissor& scissor)
01629 {
01630
01631 float x= scissor.X;
01632 float width= scissor.Width;
01633 float height= scissor.Height;
01634
01635 if(x==0 && x==0 && width==1 && height==1)
01636 {
01637 glDisable(GL_SCISSOR_TEST);
01638 }
01639 else
01640 {
01641 #ifdef NL_OS_WINDOWS
01642
01643 float y= scissor.Y;
01644
01645 if (_hWnd)
01646 {
01647
01648 int clientWidth = _WindowWidth;
01649 int clientHeight = _WindowHeight;
01650
01651
01652 int ix0=(int)floor((float)clientWidth * x + 0.5f);
01653 clamp (ix0, 0, clientWidth);
01654 int iy0=(int)floor((float)clientHeight* y + 0.5f);
01655 clamp (iy0, 0, clientHeight);
01656
01657 int ix1=(int)floor((float)clientWidth * (x+width) + 0.5f );
01658 clamp (ix1, 0, clientWidth);
01659 int iy1=(int)floor((float)clientHeight* (y+height) + 0.5f );
01660 clamp (iy1, 0, clientHeight);
01661
01662
01663 int iwidth= ix1 - ix0;
01664 clamp (iwidth, 0, clientWidth);
01665 int iheight= iy1 - iy0;
01666 clamp (iheight, 0, clientHeight);
01667
01668 glScissor (ix0, iy0, iwidth, iheight);
01669 glEnable(GL_SCISSOR_TEST);
01670 }
01671 #endif // NL_OS_WINDOWS
01672 }
01673 }
01674
01675
01676
01677
01678
01679 void CDriverGL::showCursor(bool b)
01680 {
01681 #ifdef NL_OS_WINDOWS
01682 ShowCursor(b);
01683 #elif defined (NL_OS_UNIX)
01684
01685 if (b)
01686 {
01687 if (cursor != None)
01688 {
01689 XFreeCursor(dpy, cursor);
01690 cursor = None;
01691 }
01692 XUndefineCursor(dpy, win);
01693 }
01694 else
01695 {
01696 if (cursor == None)
01697 {
01698 char bm_no_data[] = { 0,0,0,0, 0,0,0,0 };
01699 Pixmap pixmap_no_data = XCreateBitmapFromData (dpy, win, bm_no_data, 8, 8);
01700 XColor black;
01701 memset(&black, 0, sizeof (XColor));
01702 black.flags = DoRed | DoGreen | DoBlue;
01703 cursor = XCreatePixmapCursor (dpy, pixmap_no_data, pixmap_no_data, &black, &black, 0, 0);
01704 XFreePixmap(dpy, pixmap_no_data);
01705 }
01706 XDefineCursor(dpy, win, cursor);
01707 }
01708 #endif // NL_OS_UNIX
01709 }
01710
01711
01712
01713
01714 void CDriverGL::setMousePos(float x, float y)
01715 {
01716 #ifdef NL_OS_WINDOWS
01717 if (_hWnd)
01718 {
01719
01720 POINT pt;
01721 pt.x = (int)((float)(_WindowWidth)*x);
01722 pt.y = (int)((float)(_WindowHeight)*(1.0f-y));
01723 ClientToScreen (_hWnd, &pt);
01724 SetCursorPos(pt.x, pt.y);
01725 }
01726 #elif defined (NL_OS_UNIX)
01727 XWindowAttributes xwa;
01728 XGetWindowAttributes (dpy, win, &xwa);
01729 int x1 = (int)(x * (float) xwa.width);
01730 int y1 = (int)((1.0f - y) * (float) xwa.height);
01731 XWarpPointer (dpy, None, win, None, None, None, None, x1, y1);
01732 #endif // NL_OS_UNIX
01733 }
01734
01735
01736 void CDriverGL::getWindowSize(uint32 &width, uint32 &height)
01737 {
01738 #ifdef NL_OS_WINDOWS
01739
01740 if (_OffScreen)
01741 {
01742 if (_PBuffer)
01743 {
01744 wglQueryPbufferARB( _PBuffer, WGL_PBUFFER_WIDTH_ARB, (int*)&width );
01745 wglQueryPbufferARB( _PBuffer, WGL_PBUFFER_HEIGHT_ARB, (int*)&height );
01746 }
01747 }
01748 else
01749 {
01750 if (_hWnd)
01751 {
01752 width = (uint32)(_WindowWidth);
01753 height = (uint32)(_WindowHeight);
01754 }
01755 }
01756 #elif defined (NL_OS_UNIX)
01757 XWindowAttributes xwa;
01758 XGetWindowAttributes (dpy, win, &xwa);
01759 width = (uint32) xwa.width;
01760 height = (uint32) xwa.height;
01761 #endif // NL_OS_UNIX
01762 }
01763
01764
01765
01766 bool CDriverGL::isActive()
01767 {
01768 #ifdef NL_OS_WINDOWS
01769 return (IsWindow(_hWnd) != 0);
01770 #elif defined (NL_OS_UNIX)
01771 return true;
01772 #endif // NL_OS_UNIX
01773 }
01774
01775 uint8 CDriverGL::getBitPerPixel ()
01776 {
01777 return _Depth;
01778 }
01779
01780 const char *CDriverGL::getVideocardInformation ()
01781 {
01782 static char name[1024];
01783
01784 if (!_Initialized) return "OpenGL isn't initialized";
01785
01786 const char *vendor = (const char *) glGetString (GL_VENDOR);
01787 const char *renderer = (const char *) glGetString (GL_RENDERER);
01788 const char *version = (const char *) glGetString (GL_VERSION);
01789
01790 smprintf(name, 1024, "%s / %s / %s", vendor, renderer, version);
01791 return name;
01792 }
01793
01794
01795 void CDriverGL::setCapture (bool b)
01796 {
01797 #ifdef NL_OS_WINDOWS
01798
01799 if (b)
01800 {
01801 RECT client;
01802 GetClientRect (_hWnd, &client);
01803 POINT pt1,pt2;
01804 pt1.x = client.left;
01805 pt1.y = client.top;
01806 ClientToScreen (_hWnd, &pt1);
01807 pt2.x = client.right;
01808 pt2.y = client.bottom;
01809 ClientToScreen (_hWnd, &pt2);
01810 client.bottom = pt2.y;
01811 client.top = pt1.y;
01812 client.left = pt1.x;
01813 client.right = pt2.x;
01814 ClipCursor (&client);
01815 }
01816 else
01817 ClipCursor (NULL);
01818
01819
01820
01821
01822
01823
01824
01825
01826 #elif defined (NL_OS_UNIX)
01827
01828 #endif // NL_OS_UNIX
01829 }
01830
01831
01832 bool CDriverGL::clipRect(NLMISC::CRect &rect)
01833 {
01834
01835 uint32 width, height;
01836 getWindowSize(width, height);
01837
01838 sint32 xr=rect.right() ,yr=rect.bottom();
01839
01840 clamp((sint32&)rect.X, (sint32)0, (sint32)width);
01841 clamp((sint32&)rect.Y, (sint32)0, (sint32)height);
01842 clamp((sint32&)xr, (sint32)rect.X, (sint32)width);
01843 clamp((sint32&)yr, (sint32)rect.Y, (sint32)height);
01844 rect.Width= xr-rect.X;
01845 rect.Height= yr-rect.Y;
01846
01847 return rect.Width>0 && rect.Height>0;
01848 }
01849
01850
01851
01852 void CDriverGL::getBufferPart (CBitmap &bitmap, NLMISC::CRect &rect)
01853 {
01854 bitmap.reset();
01855
01856 if(clipRect(rect))
01857 {
01858 bitmap.resize(rect.Width, rect.Height, CBitmap::RGBA);
01859 vector<uint8> &d = bitmap.getPixels ();
01860 glReadPixels (rect.X, rect.Y, rect.Width, rect.Height, GL_RGBA, GL_UNSIGNED_BYTE, &(d[0]));
01861 }
01862 }
01863
01864
01865 void CDriverGL::getZBufferPart (std::vector<float> &zbuffer, NLMISC::CRect &rect)
01866 {
01867 zbuffer.clear();
01868
01869 if(clipRect(rect))
01870 {
01871 zbuffer.resize(rect.Width*rect.Height);
01872 glPixelTransferf(GL_DEPTH_SCALE, 1.0f) ;
01873 glPixelTransferf(GL_DEPTH_BIAS, 0.f) ;
01874 glReadPixels (rect.X, rect.Y, rect.Width, rect.Height, GL_DEPTH_COMPONENT , GL_FLOAT, &(zbuffer[0]));
01875 }
01876 }
01877
01878
01879 void CDriverGL::getZBuffer (std::vector<float> &zbuffer)
01880 {
01881 CRect rect(0,0);
01882 getWindowSize(rect.Width, rect.Height);
01883 getZBufferPart(zbuffer, rect);
01884 }
01885
01886 void CDriverGL::getBuffer (CBitmap &bitmap)
01887 {
01888 CRect rect(0,0);
01889 getWindowSize(rect.Width, rect.Height);
01890 getBufferPart(bitmap, rect);
01891 }
01892
01893 bool CDriverGL::fillBuffer (CBitmap &bitmap)
01894 {
01895 CRect rect(0,0);
01896 getWindowSize(rect.Width, rect.Height);
01897 if( rect.Width!=bitmap.getWidth() || rect.Height!=bitmap.getHeight() || bitmap.getPixelFormat()!=CBitmap::RGBA )
01898 return false;
01899
01900 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
01901 glDrawPixels (rect.Width, rect.Height, GL_RGBA, GL_UNSIGNED_BYTE, &(bitmap.getPixels()[0]) );
01902
01903 return true;
01904 }
01905
01906
01907 void CDriverGL::copyFrameBufferToTexture(ITexture *tex,
01908 uint32 level,
01909 uint32 offsetx,
01910 uint32 offsety,
01911 uint32 x,
01912 uint32 y,
01913 uint32 width,
01914 uint32 height
01915 )
01916 {
01917 nlassert(!tex->isTextureCube());
01918 bool compressed = false;
01919 getGlTextureFormat(*tex, compressed);
01920 nlassert(!compressed);
01921
01922 setupTexture(*tex);
01923 CTextureDrvInfosGL* gltext = (CTextureDrvInfosGL*)(ITextureDrvInfos*)(tex->TextureDrvShare->DrvTexture);
01924 _DriverGLStates.activeTextureARB(0);
01925
01926 _DriverGLStates.setTextureMode(CDriverGLStates::Texture2D);
01927 glBindTexture(GL_TEXTURE_2D, gltext->ID);
01928 glCopyTexSubImage2D(GL_TEXTURE_2D, level, offsetx, offsety, x, y, width, height);
01929
01930 _DriverGLStates.setTextureMode(CDriverGLStates::TextureDisabled);
01931 _CurrentTexture[0] = NULL;
01932 _CurrentTextureInfoGL[0] = NULL;
01933 }
01934
01935
01936 void CDriverGL::setPolygonMode (TPolygonMode mode)
01937 {
01938 IDriver::setPolygonMode (mode);
01939
01940
01941 switch (_PolygonMode)
01942 {
01943 case Filled:
01944 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
01945 break;
01946 case Line:
01947 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
01948 break;
01949 case Point:
01950 glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
01951 break;
01952 }
01953 }
01954
01955
01956 bool CDriverGL::fogEnabled()
01957 {
01958 return _FogEnabled;
01959 }
01960
01961 void CDriverGL::enableFog(bool enable)
01962 {
01963 _FogEnabled= enable;
01964 if(enable)
01965 glEnable(GL_FOG);
01966 else
01967 glDisable(GL_FOG);
01968 }
01969
01970 void CDriverGL::setupFog(float start, float end, CRGBA color)
01971 {
01972 glFogf(GL_FOG_MODE, GL_LINEAR);
01973 glFogf(GL_FOG_START, start);
01974 glFogf(GL_FOG_END, end);
01975
01976 _CurrentFogColor[0]= color.R/255.0f;
01977 _CurrentFogColor[1]= color.G/255.0f;
01978 _CurrentFogColor[2]= color.B/255.0f;
01979 _CurrentFogColor[3]= color.A/255.0f;
01980
01981 glFogfv(GL_FOG_COLOR, _CurrentFogColor);
01982
01985 if (_Extensions.EXTVertexShader && !_Extensions.NVVertexProgram)
01986 {
01987
01988 if (start != end)
01989 {
01990 setConstant(96, 1.f / (start - end), - end / (start - end), 0, 0);
01991 }
01992 else
01993 {
01994 setConstant(96, 0.f, 0, 0, 0);
01995 }
01996 }
01997 }
01998
01999
02000
02001
02002 void CDriverGL::profileRenderedPrimitives(CPrimitiveProfile &pIn, CPrimitiveProfile &pOut)
02003 {
02004 pIn= _PrimitiveProfileIn;
02005 pOut= _PrimitiveProfileOut;
02006 }
02007
02008
02009
02010 uint32 CDriverGL::profileAllocatedTextureMemory()
02011 {
02012 return _AllocatedTextureMemory;
02013 }
02014
02015
02016
02017 uint32 CDriverGL::profileSetupedMaterials() const
02018 {
02019 return _NbSetupMaterialCall;
02020 }
02021
02022
02023
02024 uint32 CDriverGL::profileSetupedModelMatrix() const
02025 {
02026 return _NbSetupModelMatrixCall;
02027 }
02028
02029
02030
02031 void CDriverGL::enableUsedTextureMemorySum (bool enable)
02032 {
02033 if (enable)
02034 nlinfo ("PERFORMANCE INFO: enableUsedTextureMemorySum has been set to true in CDriverGL\n");
02035 _SumTextureMemoryUsed=enable;
02036 }
02037
02038
02039
02040 uint32 CDriverGL::getUsedTextureMemory() const
02041 {
02042
02043 uint32 memory=0;
02044
02045
02046 set<CTextureDrvInfosGL*>::iterator ite=_TextureUsed.begin();
02047 while (ite!=_TextureUsed.end())
02048 {
02049
02050 CTextureDrvInfosGL* gltext;
02051 gltext= (*ite);
02052
02053
02054 memory+=gltext->TextureMemory;
02055
02056
02057 ite++;
02058 }
02059
02060
02061 return memory;
02062 }
02063
02064
02065
02066 bool CDriverGL::supportTextureShaders() const
02067 {
02068
02069 return _Extensions.NVTextureShader;
02070 }
02071
02072
02073 bool CDriverGL::isTextureAddrModeSupported(CMaterial::TTexAddressingMode mode) const
02074 {
02075 if (_Extensions.NVTextureShader)
02076 {
02077
02078 return true;
02079 }
02080 else
02081 {
02082 return false;
02083 }
02084 }
02085
02086
02087 void CDriverGL::setMatrix2DForTextureOffsetAddrMode(const uint stage, const float mat[4])
02088 {
02089 if (!supportTextureShaders()) return;
02090
02091 nlassert(stage < (uint) inlGetNumTextStages() )
02092 _DriverGLStates.activeTextureARB(stage);
02093 glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, mat);
02094 }
02095
02096
02097
02098 void CDriverGL::enableNVTextureShader(bool enabled)
02099 {
02100 if (enabled != _NVTextureShaderEnabled)
02101 {
02102
02103 if (enabled)
02104 {
02105 glEnable(GL_TEXTURE_SHADER_NV);
02106 }
02107 else
02108 {
02109 glDisable(GL_TEXTURE_SHADER_NV);
02110 }
02111 _NVTextureShaderEnabled = enabled;
02112 }
02113 }
02114
02115
02116 void CDriverGL::checkForPerPixelLightingSupport()
02117 {
02118
02119
02120
02121
02122 _SupportPerPixelShaderNoSpec = (_Extensions.NVTextureEnvCombine4 )
02123 && _Extensions.ARBTextureCubeMap
02124 && _Extensions.NbTextureStages >= 3
02125 && (_Extensions.NVVertexProgram );
02126
02127 _SupportPerPixelShader = (_Extensions.NVTextureEnvCombine4 )
02128 && _Extensions.ARBTextureCubeMap
02129 && _Extensions.NbTextureStages >= 2
02130 && (_Extensions.NVVertexProgram );
02131 }
02132
02133
02134 bool CDriverGL::supportPerPixelLighting(bool specular) const
02135 {
02136 return specular ? _SupportPerPixelShader : _SupportPerPixelShaderNoSpec;
02137 }
02138
02139
02140 void CDriverGL::setPerPixelLightingLight(CRGBA diffuse, CRGBA specular, float shininess)
02141 {
02142 _PPLExponent = shininess;
02143 _PPLightDiffuseColor = diffuse;
02144 _PPLightSpecularColor = specular;
02145 }
02146
02147
02148 NLMISC::IMouseDevice *CDriverGL::enableLowLevelMouse(bool enable)
02149 {
02150 #ifdef NL_OS_WINDOWS
02151 if (_EventEmitter.getNumEmitters() < 2) return NULL;
02152 NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
02153 if (enable)
02154 {
02155 try
02156 {
02157 NLMISC::IMouseDevice *md = diee->getMouseDevice();
02158 return md;
02159 }
02160 catch (EDirectInput &)
02161 {
02162 return NULL;
02163 }
02164 }
02165 else
02166 {
02167 diee->releaseMouse();
02168 return NULL;
02169 }
02170 #else
02171 return NULL;
02172 #endif
02173 }
02174
02175
02176 NLMISC::IKeyboardDevice *CDriverGL::enableLowLevelKeyboard(bool enable)
02177 {
02178 #ifdef NL_OS_WINDOWS
02179 if (_EventEmitter.getNumEmitters() < 2) return NULL;
02180 NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
02181 if (enable)
02182 {
02183 try
02184 {
02185 NLMISC::IKeyboardDevice *md = diee->getKeyboardDevice();
02186 return md;
02187 }
02188 catch (EDirectInput &)
02189 {
02190 return NULL;
02191 }
02192 }
02193 else
02194 {
02195 diee->releaseKeyboard();
02196 return NULL;
02197 }
02198 #else
02199 return NULL;
02200 #endif
02201 }
02202
02203
02204 NLMISC::IInputDeviceManager *CDriverGL::getLowLevelInputDeviceManager()
02205 {
02206 #ifdef NL_OS_WINDOWS
02207 if (_EventEmitter.getNumEmitters() < 2) return NULL;
02208 NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
02209 return diee;
02210 #else
02211 return NULL;
02212 #endif
02213 }
02214
02215
02216 bool CDriverGL::supportBlendConstantColor() const
02217 {
02218 return _Extensions.EXTBlendColor;
02219 }
02220
02221 void CDriverGL::setBlendConstantColor(NLMISC::CRGBA col)
02222 {
02223
02224 _CurrentBlendConstantColor= col;
02225
02226
02227 if(!_Extensions.EXTBlendColor)
02228 return;
02229 static const float OO255= 1.0f/255;
02230 nglBlendColorEXT(col.R*OO255, col.G*OO255, col.B*OO255, col.A*OO255);
02231 }
02232
02233 NLMISC::CRGBA CDriverGL::getBlendConstantColor() const
02234 {
02235 return _CurrentBlendConstantColor;
02236 }
02237
02238
02239 sint CDriverGL::getNbTextureStages() const
02240 {
02241 return inlGetNumTextStages();
02242 }
02243
02244
02245
02246 void CDriverGL::refreshProjMatrixFromGL()
02247 {
02248 if (!_ProjMatDirty) return;
02249 float mat[16];
02250 glGetFloatv(GL_PROJECTION_MATRIX, mat);
02251 _GLProjMat.set(mat);
02252 _ProjMatDirty = false;
02253 }
02254
02255
02256
02257 bool CDriverGL::setMonitorColorProperties (const CMonitorColorProperties &properties)
02258 {
02259 #ifdef NL_OS_WINDOWS
02260
02261
02262 HDC dc = CreateDC ("DISPLAY", NULL, NULL, NULL);
02263 if (dc)
02264 {
02265
02266 WORD ramp[256*3];
02267
02268
02269 uint c;
02270 for( c=0; c<3; c++ )
02271 {
02272 uint i;
02273 for( i=0; i<256; i++ )
02274 {
02275
02276 float value = (float)i / 256;
02277
02278
02279 value = (float) max (0.0f, (value-0.5f) * (float) pow (3.f, properties.Contrast[c]) + 0.5f );
02280
02281
02282 value = (float) pow (value, (properties.Gamma[c]>0) ? 1 - 3 * properties.Gamma[c] / 4 : 1 - properties.Gamma[c] );
02283
02284
02285 value = value + properties.Luminosity[c] / 2.f;
02286 ramp[i+(c<<8)] = min (65535, max (0, (int)(value * 65535)));
02287 }
02288 }
02289
02290
02291 bool result = SetDeviceGammaRamp (dc, ramp) != FALSE;
02292
02293
02294 ReleaseDC (NULL, dc);
02295
02296
02297 return result;
02298 }
02299 else
02300 {
02301 nlwarning ("(CDriverGL::setMonitorColorProperties): can't create DC");
02302 return false;
02303 }
02304
02305 #else
02306
02307 nlwarning ("CDriverGL::setMonitorColorProperties not implemented");
02308 return false;
02309
02310 #endif
02311 }
02312
02313
02314 bool CDriverGL::supportEMBM() const
02315 {
02316
02317 return _Extensions.ATIEnvMapBumpMap;
02318 }
02319
02320
02321 bool CDriverGL::isEMBMSupportedAtStage(uint stage) const
02322 {
02323 nlassert(supportEMBM());
02324 nlassert(stage < IDRV_MAT_MAXTEXTURES)
02325 return _StageSupportEMBM[stage];
02326
02327 }
02328
02329
02330 void CDriverGL::setEMBMMatrix(const uint stage,const float mat[4])
02331 {
02332 nlassert(supportEMBM());
02333 nlassert(stage < IDRV_MAT_MAXTEXTURES);
02334
02335 if (_Extensions.ATIEnvMapBumpMap)
02336 {
02337 _DriverGLStates.activeTextureARB(stage);
02338 nglTexBumpParameterfvATI(GL_BUMP_ROT_MATRIX_ATI, const_cast<float *>(mat));
02339 }
02340 }
02341
02342
02343 void CDriverGL::initEMBM()
02344 {
02345 if (supportEMBM())
02346 {
02347 std::fill(_StageSupportEMBM, _StageSupportEMBM + IDRV_MAT_MAXTEXTURES, false);
02348 if (_Extensions.ATIEnvMapBumpMap)
02349 {
02350
02351 GLint numEMBMUnits;
02352 nglGetTexBumpParameterivATI(GL_BUMP_NUM_TEX_UNITS_ATI, &numEMBMUnits);
02353 std::vector<GLint> EMBMUnits(numEMBMUnits);
02354
02355 nglGetTexBumpParameterivATI(GL_BUMP_TEX_UNITS_ATI, &EMBMUnits[0]);
02356 uint k;
02357 for(k = 0; k < (EMBMUnits.size() - 1); ++k)
02358 {
02359 uint stage = EMBMUnits[k] - GL_TEXTURE0_ARB;
02360 if (stage < (IDRV_MAT_MAXTEXTURES - 1))
02361 {
02362 _StageSupportEMBM[k] = true;
02363 }
02364 }
02365
02366 for(k = 0; k < IDRV_MAT_MAXTEXTURES - 1; ++k)
02367 {
02368 if (_StageSupportEMBM[k])
02369 {
02370
02371 _DriverGLStates.activeTextureARB(k);
02372 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
02373 glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + k + 1);
02374 }
02375 }
02376 _DriverGLStates.activeTextureARB(0);
02377 }
02378 }
02379 }
02380
02381 }