43 #include "../../idlib/precompiled.h"
49 #include "../../renderer/tr_local.h"
51 static void GLW_InitExtensions(
void );
80 #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
81 #define WGL_DRAW_TO_WINDOW_ARB 0x2001
82 #define WGL_DRAW_TO_BITMAP_ARB 0x2002
83 #define WGL_ACCELERATION_ARB 0x2003
84 #define WGL_NEED_PALETTE_ARB 0x2004
85 #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
86 #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
87 #define WGL_SWAP_METHOD_ARB 0x2007
88 #define WGL_NUMBER_OVERLAYS_ARB 0x2008
89 #define WGL_NUMBER_UNDERLAYS_ARB 0x2009
90 #define WGL_TRANSPARENT_ARB 0x200A
91 #define WGL_SHARE_DEPTH_ARB 0x200C
92 #define WGL_SHARE_STENCIL_ARB 0x200D
93 #define WGL_SHARE_ACCUM_ARB 0x200E
94 #define WGL_SUPPORT_GDI_ARB 0x200F
95 #define WGL_SUPPORT_OPENGL_ARB 0x2010
96 #define WGL_DOUBLE_BUFFER_ARB 0x2011
97 #define WGL_STEREO_ARB 0x2012
98 #define WGL_PIXEL_TYPE_ARB 0x2013
99 #define WGL_COLOR_BITS_ARB 0x2014
100 #define WGL_RED_BITS_ARB 0x2015
101 #define WGL_RED_SHIFT_ARB 0x2016
102 #define WGL_GREEN_BITS_ARB 0x2017
103 #define WGL_GREEN_SHIFT_ARB 0x2018
104 #define WGL_BLUE_BITS_ARB 0x2019
105 #define WGL_BLUE_SHIFT_ARB 0x201A
106 #define WGL_ALPHA_BITS_ARB 0x201B
107 #define WGL_ALPHA_SHIFT_ARB 0x201C
108 #define WGL_ACCUM_BITS_ARB 0x201D
109 #define WGL_ACCUM_RED_BITS_ARB 0x201E
110 #define WGL_ACCUM_GREEN_BITS_ARB 0x201F
111 #define WGL_ACCUM_BLUE_BITS_ARB 0x2020
112 #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
113 #define WGL_DEPTH_BITS_ARB 0x2022
114 #define WGL_STENCIL_BITS_ARB 0x2023
115 #define WGL_AUX_BUFFERS_ARB 0x2024
116 #define WGL_NO_ACCELERATION_ARB 0x2025
117 #define WGL_GENERIC_ACCELERATION_ARB 0x2026
118 #define WGL_FULL_ACCELERATION_ARB 0x2027
119 #define WGL_SWAP_EXCHANGE_ARB 0x2028
120 #define WGL_SWAP_COPY_ARB 0x2029
121 #define WGL_SWAP_UNDEFINED_ARB 0x202A
122 #define WGL_TYPE_RGBA_ARB 0x202B
123 #define WGL_TYPE_COLORINDEX_ARB 0x202C
124 #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
125 #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
126 #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
127 #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
128 #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
131 #define WGL_SAMPLE_BUFFERS_ARB 0x2041
132 #define WGL_SAMPLES_ARB 0x2042
139 bool QGL_Init(
const char *dllname );
153 hDC = GetDC( GetDesktopWindow() );
155 common->
DPrintf(
"...getting default gamma ramp: %s\n", success ?
"success" :
"failed" );
156 ReleaseDC( GetDesktopWindow(), hDC );
174 hDC = GetDC( GetDesktopWindow() );
176 common->
DPrintf (
"...restoring hardware gamma: %s\n", success ?
"success" :
"failed" );
177 ReleaseDC( GetDesktopWindow(), hDC );
189 unsigned short table[3][256];
196 for ( i = 0; i < 256; i++ ) {
197 table[0][
i] = red[
i];
198 table[1][
i] = green[
i];
199 table[2][
i] = blue[
i];
202 if ( !SetDeviceGammaRamp(
win32.
hDC, table ) ) {
203 common->
Printf(
"WARNING: SetDeviceGammaRamp failed.\n" );
230 if ( uMsg == WM_DESTROY ) {
234 if ( uMsg != WM_CREATE ) {
235 return DefWindowProc(hWnd, uMsg, wParam, lParam);
238 const static PIXELFORMATDESCRIPTOR pfd = {
239 sizeof(PIXELFORMATDESCRIPTOR),
241 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
262 pixelFormat = ChoosePixelFormat(hDC, &pfd);
263 SetPixelFormat(hDC, pixelFormat, &pfd);
264 hGLRC = qwglCreateContext(hDC);
265 qwglMakeCurrent(hDC, hGLRC);
269 wglDeleteContext(hGLRC);
270 ReleaseDC(hWnd, hDC);
272 return DefWindowProc(hWnd, uMsg, wParam, lParam);
317 static void GLW_GetWGLExtensionsWithFakeWindow(
void ) {
330 common->
FatalError(
"GLW_GetWGLExtensionsWithFakeWindow: Couldn't create fake window" );
333 HDC hDC = GetDC( hWnd );
334 HGLRC gRC = wglCreateContext( hDC );
335 wglMakeCurrent( hDC, gRC );
337 wglDeleteContext( gRC );
338 ReleaseDC( hWnd, hDC );
340 DestroyWindow( hWnd );
341 while ( GetMessage( &msg,
NULL, 0, 0 ) ) {
342 TranslateMessage( &msg );
343 DispatchMessage( &msg );
368 PIXELFORMATDESCRIPTOR
src =
370 sizeof(PIXELFORMATDESCRIPTOR),
408 FLOAT fAttributes[] = {0, 0};
417 iAttributes[5] =
TRUE;
441 src.dwFlags |= PFD_STEREO;
500 static void GLW_CreateWindowClasses(
void ) {
510 memset( &wc, 0,
sizeof( wc ) );
518 wc.hCursor = LoadCursor (
NULL,IDC_ARROW);
519 wc.hbrBackground = (
struct HBRUSH__ *)COLOR_GRAYTEXT;
523 if ( !RegisterClass( &wc ) ) {
536 wc.hCursor = LoadCursor (
NULL,IDC_ARROW);
537 wc.hbrBackground = (
struct HBRUSH__ *)COLOR_GRAYTEXT;
541 if ( !RegisterClass( &wc ) ) {
566 exstyle = WS_EX_TOPMOST;
567 stylebits = WS_POPUP|WS_VISIBLE|WS_SYSMENU;
580 r.right = parms.
width;
584 AdjustWindowRect (&r, stylebits,
FALSE);
586 w = r.right - r.left;
587 h = r.bottom - r.top;
620 common->
Printf(
"^3GLW_CreateWindow() - Couldn't create window^0\n" );
628 common->
Printf(
"...created window @ %d,%d (%dx%d)\n", x, y, w, h );
630 if ( !GLW_InitDriver( parms ) ) {
647 static void PrintCDSError(
int value ) {
649 case DISP_CHANGE_RESTART:
652 case DISP_CHANGE_BADPARAM:
655 case DISP_CHANGE_BADFLAGS:
658 case DISP_CHANGE_FAILED:
661 case DISP_CHANGE_BADMODE:
664 case DISP_CHANGE_NOTUPDATED:
697 for ( modeNum = 0 ; ; modeNum++ ) {
698 if ( !EnumDisplaySettings(
NULL, modeNum, &devmode ) ) {
709 if ( (
int)devmode.dmPelsWidth >= parms.
width
710 && (
int)devmode.dmPelsHeight >= parms.
height
711 && devmode.dmBitsPerPel == 32 ) {
721 memset( &dm, 0,
sizeof( dm ) );
722 dm.dmSize =
sizeof( dm );
724 dm.dmPelsWidth = parms.
width;
725 dm.dmPelsHeight = parms.
height;
726 dm.dmBitsPerPel = 32;
727 dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
731 dm.dmFields |= DM_DISPLAYFREQUENCY;
738 if ( ( cdsRet = ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) ) == DISP_CHANGE_SUCCESSFUL ) {
749 PrintCDSError( cdsRet );
754 for ( modeNum = 0 ; ; modeNum++ ) {
755 if ( !EnumDisplaySettings(
NULL, modeNum, &devmode ) ) {
758 if ( (
int)devmode.dmPelsWidth >= parms.
width
759 && (
int)devmode.dmPelsHeight >= parms.
height
760 && devmode.dmBitsPerPel == 32 ) {
762 if ( ( cdsRet = ChangeDisplaySettings( &devmode, CDS_FULLSCREEN ) ) == DISP_CHANGE_SUCCESSFUL ) {
794 const char *driverName;
800 hDC = GetDC( GetDesktopWindow() );
804 ReleaseDC( GetDesktopWindow(), hDC );
808 common->
Printf(
"^3Windowed mode requires 32 bit desktop depth^0\n");
817 GLW_CreateWindowClasses();
827 common->
Printf(
"^3GLimp_Init() could not load r_glDriver \"%s\"^0\n", driverName );
833 GLW_GetWGLExtensionsWithFakeWindow();
837 if ( !GLW_SetFullScreen( parms ) ) {
845 if ( !GLW_CreateWindow( parms ) ) {
873 memset( &dm, 0,
sizeof( dm ) );
874 dm.dmSize =
sizeof( dm );
875 dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
878 dm.dmFields |= DM_DISPLAYFREQUENCY;
885 exstyle = WS_EX_TOPMOST;
886 stylebits = WS_POPUP|WS_VISIBLE|WS_SYSMENU;
887 SetWindowLong(
win32.
hWnd, GWL_STYLE, stylebits );
888 SetWindowLong(
win32.
hWnd, GWL_EXSTYLE, exstyle );
889 dm.dmPelsWidth = parms.
width;
890 dm.dmPelsHeight = parms.
height;
891 dm.dmBitsPerPel = 32;
900 r.right = parms.
width;
902 w = r.right - r.left;
903 h = r.bottom - r.top;
927 AdjustWindowRect (&r, stylebits,
FALSE);
928 SetWindowLong(
win32.
hWnd, GWL_STYLE, stylebits );
929 SetWindowLong(
win32.
hWnd, GWL_EXSTYLE, exstyle );
932 bool ret = ( ChangeDisplaySettings( &dm, parms.
fullScreen ? CDS_FULLSCREEN : 0 ) == DISP_CHANGE_SUCCESSFUL );
933 SetWindowPos(
win32.
hWnd, parms.
fullScreen ? HWND_TOPMOST : HWND_NOTOPMOST, x, y, w, h, parms.
fullScreen ? SWP_NOSIZE | SWP_NOMOVE : SWP_SHOWWINDOW );
946 const char *success[] = {
"failed",
"success" };
952 if ( qwglMakeCurrent ) {
953 retVal = qwglMakeCurrent(
NULL,
NULL ) != 0;
954 common->
Printf(
"...wglMakeCurrent( NULL, NULL ): %s\n", success[retVal] );
959 retVal = qwglDeleteContext(
win32.
hGLRC ) != 0;
960 common->
Printf(
"...deleting GL context: %s\n", success[retVal] );
967 common->
Printf(
"...releasing DC: %s\n", success[retVal] );
982 ChangeDisplaySettings( 0, 0 );
1072 static void GLimp_RenderThreadWrapper(
void ) {
1090 GetSystemInfo( &info );
1091 if ( info.dwNumberOfProcessors < 2 ) {
1105 (LPTHREAD_START_ROUTINE)GLimp_RenderThreadWrapper,
1111 common->
Error(
"GLimp_SpawnRenderThread: failed" );
1117 SetThreadAffinityMask( GetCurrentThread, 1 );
1193 if ( renderThreadActive ) {
1198 if ( r == WAIT_OBJECT_0 ) {
1203 if ( r == WAIT_OBJECT_0 ) {
1212 if ( r == WAIT_TIMEOUT ) {
1236 common->
Printf(
"Couldn't find proc address for: %s\n", name );
PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB
PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB
GLsizei const GLfloat * value
void GLimp_SwapBuffers(void)
idCVar r_glDriver("r_glDriver","", CVAR_RENDERER,"\"opengl32\", etc.")
#define WIN32_FAKE_WINDOW_CLASS_NAME
#define WGL_DEPTH_BITS_ARB
bool windowClassRegistered
idCVar r_swapInterval("r_swapInterval","0", CVAR_RENDERER|CVAR_ARCHIVE|CVAR_INTEGER,"changes wglSwapIntarval")
CONST PIXELFORMATDESCRIPTOR UINT
#define WGL_BLUE_BITS_ARB
bool QGL_Init(const char *dllname)
PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB
GLenum GLsizei GLenum GLenum const GLvoid * table
void GLimp_WakeBackEnd(void *data)
volatile bool renderThreadActive
unsigned short oldHardwareGamma[3][256]
void(* GLExtension_t)(void)
void GLimp_SetGamma(unsigned short red[256], unsigned short green[256], unsigned short blue[256])
LONG WINAPI FakeWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#define WGL_DOUBLE_BUFFER_ARB
const char * wgl_extensions_string
void(* glimpRenderThread)(void)
PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB
LONG WINAPI MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
HANDLE renderCompletedEvent
GLubyte GLubyte GLubyte GLubyte w
PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB
void GLimp_FrontEndSleep(void)
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT
PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB
void GLW_WM_CREATE(HWND hWnd)
GLsizei GLsizei GLenum GLenum const GLvoid * data
int GetInteger(void) const
#define WGL_STENCIL_BITS_ARB
virtual void virtual void FatalError(const char *fmt,...) id_attribute((format(printf
idCVar r_logFile("r_logFile","0", CVAR_RENDERER|CVAR_INTEGER,"number of frames to emit GL logs")
void GLimp_RestoreGamma()
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB
typedef HDC(WINAPI *PFNWGLGETCURRENTREADDCARBPROC)(void)
virtual void Printf(const char *fmt,...) id_attribute((format(printf
void GLimp_EnableLogging(bool enable)
void GLimp_ActivateContext(void)
bool GLimp_SetScreenParms(glimpParms_t parms)
bool GLimp_SpawnRenderThread(void(*function)(void))
const char * GetString(void) const
GLdouble GLdouble GLdouble r
PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB
HANDLE renderThreadHandle
void * GLimp_BackEndSleep(void)
#define WGL_SAMPLE_BUFFERS_ARB
#define WGL_GREEN_BITS_ARB
bool IsModified(void) const
GLExtension_t GLimp_ExtensionPointer(const char *name)
#define WGL_ALPHA_BITS_ARB
PIXELFORMATDESCRIPTOR pfd
PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
#define WIN32_WINDOW_CLASS_NAME
HANDLE renderCommandsEvent
void GLW_CheckWGLExtensions(HDC hDC)
PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB
bool GLimp_Init(glimpParms_t parms)
unsigned long renderThreadId
const char *WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC(HDC hdc)
void GLimp_Shutdown(void)
virtual void DPrintf(const char *fmt,...) id_attribute((format(printf
virtual void Error(const char *fmt,...) id_attribute((format(printf
PFNWGLSETPBUFFERATTRIBARBPROC wglSetPbufferAttribARB
void OutputDebugString(const char *text)
void GLimp_DeactivateContext(void)
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB