doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
win_glimp.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 /*
29 ** WIN_GLIMP.C
30 **
31 ** This file contains ALL Win32 specific stuff having to do with the
32 ** OpenGL refresh. When a port is being made the following functions
33 ** must be implemented by the port:
34 **
35 ** GLimp_SwapBuffers
36 ** GLimp_Init
37 ** GLimp_Shutdown
38 ** GLimp_SetGamma
39 **
40 ** Note that the GLW_xxx functions are Windows specific GL-subsystem
41 ** related functions that are relevant ONLY to win_glimp.c
42 */
43 #include "../../idlib/precompiled.h"
44 #pragma hdrstop
45 
46 #include "win_local.h"
47 #include "rc/AFEditor_resource.h"
48 #include "rc/doom_resource.h"
49 #include "../../renderer/tr_local.h"
50 
51 static void GLW_InitExtensions( void );
52 
53 
54 // WGL_ARB_extensions_string
56 
57 // WGL_EXT_swap_interval
58 PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
59 
60 // WGL_ARB_pixel_format
61 PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB;
62 PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB;
63 PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
64 
65 // WGL_ARB_pbuffer
66 PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB;
67 PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB;
68 PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB;
69 PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB;
70 PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB;
71 
72 // WGL_ARB_render_texture
73 PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB;
74 PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB;
75 PFNWGLSETPBUFFERATTRIBARBPROC wglSetPbufferAttribARB;
76 
77 
78 
79 /* ARB_pixel_format */
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
129 
130 /* ARB_multisample */
131 #define WGL_SAMPLE_BUFFERS_ARB 0x2041
132 #define WGL_SAMPLES_ARB 0x2042
133 
134 
135 
136 //
137 // function declaration
138 //
139 bool QGL_Init( const char *dllname );
140 void QGL_Shutdown( void );
141 
142 
143 
144 /*
145 ========================
146 GLimp_GetOldGammaRamp
147 ========================
148 */
149 static void GLimp_SaveGamma( void ) {
150  HDC hDC;
151  BOOL success;
152 
153  hDC = GetDC( GetDesktopWindow() );
154  success = GetDeviceGammaRamp( hDC, win32.oldHardwareGamma );
155  common->DPrintf( "...getting default gamma ramp: %s\n", success ? "success" : "failed" );
156  ReleaseDC( GetDesktopWindow(), hDC );
157 }
158 
159 /*
160 ========================
161 GLimp_RestoreGamma
162 ========================
163 */
164 static void GLimp_RestoreGamma( void ) {
165  HDC hDC;
166  BOOL success;
167 
168  // if we never read in a reasonable looking
169  // table, don't write it out
170  if ( win32.oldHardwareGamma[0][255] == 0 ) {
171  return;
172  }
173 
174  hDC = GetDC( GetDesktopWindow() );
175  success = SetDeviceGammaRamp( hDC, win32.oldHardwareGamma );
176  common->DPrintf ( "...restoring hardware gamma: %s\n", success ? "success" : "failed" );
177  ReleaseDC( GetDesktopWindow(), hDC );
178 }
179 
180 
181 /*
182 ========================
183 GLimp_SetGamma
184 
185 The renderer calls this when the user adjusts r_gamma or r_brightness
186 ========================
187 */
188 void GLimp_SetGamma( unsigned short red[256], unsigned short green[256], unsigned short blue[256] ) {
189  unsigned short table[3][256];
190  int i;
191 
192  if ( !win32.hDC ) {
193  return;
194  }
195 
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];
200  }
201 
202  if ( !SetDeviceGammaRamp( win32.hDC, table ) ) {
203  common->Printf( "WARNING: SetDeviceGammaRamp failed.\n" );
204  }
205 }
206 
207 /*
208 =============================================================================
209 
210 WglExtension Grabbing
211 
212 This is gross -- creating a window just to get a context to get the wgl extensions
213 
214 =============================================================================
215 */
216 
217 /*
218 ====================
219 FakeWndProc
220 
221 Only used to get wglExtensions
222 ====================
223 */
225  HWND hWnd,
226  UINT uMsg,
227  WPARAM wParam,
228  LPARAM lParam) {
229 
230  if ( uMsg == WM_DESTROY ) {
231  PostQuitMessage(0);
232  }
233 
234  if ( uMsg != WM_CREATE ) {
235  return DefWindowProc(hWnd, uMsg, wParam, lParam);
236  }
237 
238  const static PIXELFORMATDESCRIPTOR pfd = {
239  sizeof(PIXELFORMATDESCRIPTOR),
240  1,
241  PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
242  PFD_TYPE_RGBA,
243  24,
244  0, 0, 0, 0, 0, 0,
245  8, 0,
246  0, 0, 0, 0,
247  24, 8,
248  0,
249  PFD_MAIN_PLANE,
250  0,
251  0,
252  0,
253  0,
254  };
255  int pixelFormat;
256  HDC hDC;
257  HGLRC hGLRC;
258 
259  hDC = GetDC(hWnd);
260 
261  // Set up OpenGL
262  pixelFormat = ChoosePixelFormat(hDC, &pfd);
263  SetPixelFormat(hDC, pixelFormat, &pfd);
264  hGLRC = qwglCreateContext(hDC);
265  qwglMakeCurrent(hDC, hGLRC);
266 
267  // free things
268  wglMakeCurrent(NULL, NULL);
269  wglDeleteContext(hGLRC);
270  ReleaseDC(hWnd, hDC);
271 
272  return DefWindowProc(hWnd, uMsg, wParam, lParam);
273 }
274 
275 
276 /*
277 ==================
278 GLW_GetWGLExtensionsWithFakeWindow
279 ==================
280 */
283  GLimp_ExtensionPointer("wglGetExtensionsStringARB");
286  } else {
288  }
289 
290  // WGL_EXT_swap_control
291  wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) GLimp_ExtensionPointer( "wglSwapIntervalEXT" );
292  r_swapInterval.SetModified(); // force a set next frame
293 
294  // WGL_ARB_pixel_format
295  wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)GLimp_ExtensionPointer("wglGetPixelFormatAttribivARB");
296  wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)GLimp_ExtensionPointer("wglGetPixelFormatAttribfvARB");
297  wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)GLimp_ExtensionPointer("wglChoosePixelFormatARB");
298 
299  // WGL_ARB_pbuffer
300  wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)GLimp_ExtensionPointer("wglCreatePbufferARB");
301  wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)GLimp_ExtensionPointer("wglGetPbufferDCARB");
302  wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)GLimp_ExtensionPointer("wglReleasePbufferDCARB");
303  wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)GLimp_ExtensionPointer("wglDestroyPbufferARB");
304  wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)GLimp_ExtensionPointer("wglQueryPbufferARB");
305 
306  // WGL_ARB_render_texture
307  wglBindTexImageARB = (PFNWGLBINDTEXIMAGEARBPROC)GLimp_ExtensionPointer("wglBindTexImageARB");
308  wglReleaseTexImageARB = (PFNWGLRELEASETEXIMAGEARBPROC)GLimp_ExtensionPointer("wglReleaseTexImageARB");
309  wglSetPbufferAttribARB = (PFNWGLSETPBUFFERATTRIBARBPROC)GLimp_ExtensionPointer("wglSetPbufferAttribARB");
310 }
311 
312 /*
313 ==================
314 GLW_GetWGLExtensionsWithFakeWindow
315 ==================
316 */
317 static void GLW_GetWGLExtensionsWithFakeWindow( void ) {
318  HWND hWnd;
319  MSG msg;
320 
321  // Create a window for the sole purpose of getting
322  // a valid context to get the wglextensions
323  hWnd = CreateWindow(WIN32_FAKE_WINDOW_CLASS_NAME, GAME_NAME,
324  WS_OVERLAPPEDWINDOW,
325  40, 40,
326  640,
327  480,
329  if ( !hWnd ) {
330  common->FatalError( "GLW_GetWGLExtensionsWithFakeWindow: Couldn't create fake window" );
331  }
332 
333  HDC hDC = GetDC( hWnd );
334  HGLRC gRC = wglCreateContext( hDC );
335  wglMakeCurrent( hDC, gRC );
336  GLW_CheckWGLExtensions( hDC );
337  wglDeleteContext( gRC );
338  ReleaseDC( hWnd, hDC );
339 
340  DestroyWindow( hWnd );
341  while ( GetMessage( &msg, NULL, 0, 0 ) ) {
342  TranslateMessage( &msg );
343  DispatchMessage( &msg );
344  }
345 }
346 
347 //=============================================================================
348 
349 /*
350 ====================
351 GLW_WM_CREATE
352 ====================
353 */
354 void GLW_WM_CREATE( HWND hWnd ) {
355 }
356 
357 
358 
359 /*
360 ====================
361 GLW_InitDriver
362 
363 Set the pixelformat for the window before it is
364 shown, and create the rendering context
365 ====================
366 */
367 static bool GLW_InitDriver( glimpParms_t parms ) {
368  PIXELFORMATDESCRIPTOR src =
369  {
370  sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
371  1, // version number
372  PFD_DRAW_TO_WINDOW | // support window
373  PFD_SUPPORT_OPENGL | // support OpenGL
374  PFD_DOUBLEBUFFER, // double buffered
375  PFD_TYPE_RGBA, // RGBA type
376  32, // 32-bit color depth
377  0, 0, 0, 0, 0, 0, // color bits ignored
378  8, // 8 bit destination alpha
379  0, // shift bit ignored
380  0, // no accumulation buffer
381  0, 0, 0, 0, // accum bits ignored
382  24, // 24-bit z-buffer
383  8, // 8-bit stencil buffer
384  0, // no auxiliary buffer
385  PFD_MAIN_PLANE, // main layer
386  0, // reserved
387  0, 0, 0 // layer masks ignored
388  };
389 
390  common->Printf( "Initializing OpenGL driver\n" );
391 
392  //
393  // get a DC for our window if we don't already have one allocated
394  //
395  if ( win32.hDC == NULL ) {
396  common->Printf( "...getting DC: " );
397 
398  if ( ( win32.hDC = GetDC( win32.hWnd ) ) == NULL ) {
399  common->Printf( "^3failed^0\n" );
400  return false;
401  }
402  common->Printf( "succeeded\n" );
403  }
404 
405  // the multisample path uses the wgl
406  if ( wglChoosePixelFormatARB && parms.multiSamples > 1 ) {
407  int iAttributes[20];
408  FLOAT fAttributes[] = {0, 0};
409  UINT numFormats;
410 
411  // FIXME: specify all the other stuff
412  iAttributes[0] = WGL_SAMPLE_BUFFERS_ARB;
413  iAttributes[1] = 1;
414  iAttributes[2] = WGL_SAMPLES_ARB;
415  iAttributes[3] = parms.multiSamples;
416  iAttributes[4] = WGL_DOUBLE_BUFFER_ARB;
417  iAttributes[5] = TRUE;
418  iAttributes[6] = WGL_STENCIL_BITS_ARB;
419  iAttributes[7] = 8;
420  iAttributes[8] = WGL_DEPTH_BITS_ARB;
421  iAttributes[9] = 24;
422  iAttributes[10] = WGL_RED_BITS_ARB;
423  iAttributes[11] = 8;
424  iAttributes[12] = WGL_BLUE_BITS_ARB;
425  iAttributes[13] = 8;
426  iAttributes[14] = WGL_GREEN_BITS_ARB;
427  iAttributes[15] = 8;
428  iAttributes[16] = WGL_ALPHA_BITS_ARB;
429  iAttributes[17] = 8;
430  iAttributes[18] = 0;
431  iAttributes[19] = 0;
432 
433  wglChoosePixelFormatARB( win32.hDC, iAttributes, fAttributes, 1, &win32.pixelformat, &numFormats );
434  } else {
435  // this is the "classic" choose pixel format path
436 
437  // eventually we may need to have more fallbacks, but for
438  // now, ask for everything
439  if ( parms.stereo ) {
440  common->Printf( "...attempting to use stereo\n" );
441  src.dwFlags |= PFD_STEREO;
442  }
443 
444  //
445  // choose, set, and describe our desired pixel format. If we're
446  // using a minidriver then we need to bypass the GDI functions,
447  // otherwise use the GDI functions.
448  //
449  if ( ( win32.pixelformat = ChoosePixelFormat( win32.hDC, &src ) ) == 0 ) {
450  common->Printf( "...^3GLW_ChoosePFD failed^0\n");
451  return false;
452  }
453  common->Printf( "...PIXELFORMAT %d selected\n", win32.pixelformat );
454  }
455 
456  // get the full info
457  DescribePixelFormat( win32.hDC, win32.pixelformat, sizeof( win32.pfd ), &win32.pfd );
458  glConfig.colorBits = win32.pfd.cColorBits;
459  glConfig.depthBits = win32.pfd.cDepthBits;
460  glConfig.stencilBits = win32.pfd.cStencilBits;
461 
462  // XP seems to set this incorrectly
463  if ( !glConfig.stencilBits ) {
464  glConfig.stencilBits = 8;
465  }
466 
467  // the same SetPixelFormat is used either way
468  if ( SetPixelFormat( win32.hDC, win32.pixelformat, &win32.pfd ) == FALSE ) {
469  common->Printf( "...^3SetPixelFormat failed^0\n", win32.hDC );
470  return false;
471  }
472 
473  //
474  // startup the OpenGL subsystem by creating a context and making it current
475  //
476  common->Printf( "...creating GL context: " );
477  if ( ( win32.hGLRC = qwglCreateContext( win32.hDC ) ) == 0 ) {
478  common->Printf( "^3failed^0\n" );
479  return false;
480  }
481  common->Printf( "succeeded\n" );
482 
483  common->Printf( "...making context current: " );
484  if ( !qwglMakeCurrent( win32.hDC, win32.hGLRC ) ) {
485  qwglDeleteContext( win32.hGLRC );
486  win32.hGLRC = NULL;
487  common->Printf( "^3failed^0\n" );
488  return false;
489  }
490  common->Printf( "succeeded\n" );
491 
492  return true;
493 }
494 
495 /*
496 ====================
497 GLW_CreateWindowClasses
498 ====================
499 */
500 static void GLW_CreateWindowClasses( void ) {
501  WNDCLASS wc;
502 
503  //
504  // register the window class if necessary
505  //
507  return;
508  }
509 
510  memset( &wc, 0, sizeof( wc ) );
511 
512  wc.style = 0;
513  wc.lpfnWndProc = (WNDPROC) MainWndProc;
514  wc.cbClsExtra = 0;
515  wc.cbWndExtra = 0;
516  wc.hInstance = win32.hInstance;
517  wc.hIcon = LoadIcon( win32.hInstance, MAKEINTRESOURCE(IDI_ICON1));
518  wc.hCursor = LoadCursor (NULL,IDC_ARROW);
519  wc.hbrBackground = (struct HBRUSH__ *)COLOR_GRAYTEXT;
520  wc.lpszMenuName = 0;
521  wc.lpszClassName = WIN32_WINDOW_CLASS_NAME;
522 
523  if ( !RegisterClass( &wc ) ) {
524  common->FatalError( "GLW_CreateWindow: could not register window class" );
525  }
526  common->Printf( "...registered window class\n" );
527 
528  // now register the fake window class that is only used
529  // to get wgl extensions
530  wc.style = 0;
531  wc.lpfnWndProc = (WNDPROC) FakeWndProc;
532  wc.cbClsExtra = 0;
533  wc.cbWndExtra = 0;
534  wc.hInstance = win32.hInstance;
535  wc.hIcon = LoadIcon( win32.hInstance, MAKEINTRESOURCE(IDI_ICON1));
536  wc.hCursor = LoadCursor (NULL,IDC_ARROW);
537  wc.hbrBackground = (struct HBRUSH__ *)COLOR_GRAYTEXT;
538  wc.lpszMenuName = 0;
539  wc.lpszClassName = WIN32_FAKE_WINDOW_CLASS_NAME;
540 
541  if ( !RegisterClass( &wc ) ) {
542  common->FatalError( "GLW_CreateWindow: could not register window class" );
543  }
544  common->Printf( "...registered fake window class\n" );
545 
547 }
548 
549 /*
550 =======================
551 GLW_CreateWindow
552 
553 Responsible for creating the Win32 window.
554 If cdsFullscreen is true, it won't have a border
555 =======================
556 */
557 static bool GLW_CreateWindow( glimpParms_t parms ) {
558  int stylebits;
559  int x, y, w, h;
560  int exstyle;
561 
562  //
563  // compute width and height
564  //
565  if ( parms.fullScreen ) {
566  exstyle = WS_EX_TOPMOST;
567  stylebits = WS_POPUP|WS_VISIBLE|WS_SYSMENU;
568 
569  x = 0;
570  y = 0;
571  w = parms.width;
572  h = parms.height;
573  } else {
574  RECT r;
575 
576  // adjust width and height for window border
577  r.bottom = parms.height;
578  r.left = 0;
579  r.top = 0;
580  r.right = parms.width;
581 
582  exstyle = 0;
583  stylebits = WINDOW_STYLE|WS_SYSMENU;
584  AdjustWindowRect (&r, stylebits, FALSE);
585 
586  w = r.right - r.left;
587  h = r.bottom - r.top;
588 
589  x = win32.win_xpos.GetInteger();
590  y = win32.win_ypos.GetInteger();
591 
592  // adjust window coordinates if necessary
593  // so that the window is completely on screen
594  if ( x + w > win32.desktopWidth ) {
595  x = ( win32.desktopWidth - w );
596  }
597  if ( y + h > win32.desktopHeight ) {
598  y = ( win32.desktopHeight - h );
599  }
600  if ( x < 0 ) {
601  x = 0;
602  }
603  if ( y < 0 ) {
604  y = 0;
605  }
606  }
607 
608  win32.hWnd = CreateWindowEx (
609  exstyle,
611  GAME_NAME,
612  stylebits,
613  x, y, w, h,
614  NULL,
615  NULL,
617  NULL);
618 
619  if ( !win32.hWnd ) {
620  common->Printf( "^3GLW_CreateWindow() - Couldn't create window^0\n" );
621  return false;
622  }
623 
624  ::SetTimer( win32.hWnd, 0, 100, NULL );
625 
626  ShowWindow( win32.hWnd, SW_SHOW );
627  UpdateWindow( win32.hWnd );
628  common->Printf( "...created window @ %d,%d (%dx%d)\n", x, y, w, h );
629 
630  if ( !GLW_InitDriver( parms ) ) {
631  ShowWindow( win32.hWnd, SW_HIDE );
632  DestroyWindow( win32.hWnd );
633  win32.hWnd = NULL;
634  return false;
635  }
636 
637  SetForegroundWindow( win32.hWnd );
638  SetFocus( win32.hWnd );
639 
641 
642  return true;
643 }
644 
645 
646 
647 static void PrintCDSError( int value ) {
648  switch ( value ) {
649  case DISP_CHANGE_RESTART:
650  common->Printf( "restart required\n" );
651  break;
652  case DISP_CHANGE_BADPARAM:
653  common->Printf( "bad param\n" );
654  break;
655  case DISP_CHANGE_BADFLAGS:
656  common->Printf( "bad flags\n" );
657  break;
658  case DISP_CHANGE_FAILED:
659  common->Printf( "DISP_CHANGE_FAILED\n" );
660  break;
661  case DISP_CHANGE_BADMODE:
662  common->Printf( "bad mode\n" );
663  break;
664  case DISP_CHANGE_NOTUPDATED:
665  common->Printf( "not updated\n" );
666  break;
667  default:
668  common->Printf( "unknown error %d\n", value );
669  break;
670  }
671 }
672 
673 
674 /*
675 ===================
676 GLW_SetFullScreen
677 ===================
678 */
679 static bool GLW_SetFullScreen( glimpParms_t parms ) {
680 #if 0
681  // for some reason, bounds checker claims that windows is
682  // writing past the bounds of dm in the get display frequency call
683  union {
684  DEVMODE dm;
685  byte filler[1024];
686  } hack;
687 #endif
688  DEVMODE dm;
689  int cdsRet;
690 
691  DEVMODE devmode;
692  int modeNum;
693  bool matched;
694 
695  // first make sure the user is not trying to select a mode that his card/monitor can't handle
696  matched = false;
697  for ( modeNum = 0 ; ; modeNum++ ) {
698  if ( !EnumDisplaySettings( NULL, modeNum, &devmode ) ) {
699  if ( matched ) {
700  // we got a resolution match, but not a frequency match
701  // so disable the frequency requirement
702  common->Printf( "...^3%dhz is unsupported at %dx%d^0\n", parms.displayHz, parms.width, parms.height );
703  parms.displayHz = 0;
704  break;
705  }
706  common->Printf( "...^3%dx%d is unsupported in 32 bit^0\n", parms.width, parms.height );
707  return false;
708  }
709  if ( (int)devmode.dmPelsWidth >= parms.width
710  && (int)devmode.dmPelsHeight >= parms.height
711  && devmode.dmBitsPerPel == 32 ) {
712 
713  matched = true;
714 
715  if ( parms.displayHz == 0 || devmode.dmDisplayFrequency == parms.displayHz ) {
716  break;
717  }
718  }
719  }
720 
721  memset( &dm, 0, sizeof( dm ) );
722  dm.dmSize = sizeof( dm );
723 
724  dm.dmPelsWidth = parms.width;
725  dm.dmPelsHeight = parms.height;
726  dm.dmBitsPerPel = 32;
727  dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
728 
729  if ( parms.displayHz != 0 ) {
730  dm.dmDisplayFrequency = parms.displayHz;
731  dm.dmFields |= DM_DISPLAYFREQUENCY;
732  }
733 
734  common->Printf( "...calling CDS: " );
735 
736  // try setting the exact mode requested, because some drivers don't report
737  // the low res modes in EnumDisplaySettings, but still work
738  if ( ( cdsRet = ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) ) == DISP_CHANGE_SUCCESSFUL ) {
739  common->Printf( "ok\n" );
740  win32.cdsFullscreen = true;
741  return true;
742  }
743 
744  //
745  // the exact mode failed, so scan EnumDisplaySettings for the next largest mode
746  //
747  common->Printf( "^3failed^0, " );
748 
749  PrintCDSError( cdsRet );
750 
751  common->Printf( "...trying next higher resolution:" );
752 
753  // we could do a better matching job here...
754  for ( modeNum = 0 ; ; modeNum++ ) {
755  if ( !EnumDisplaySettings( NULL, modeNum, &devmode ) ) {
756  break;
757  }
758  if ( (int)devmode.dmPelsWidth >= parms.width
759  && (int)devmode.dmPelsHeight >= parms.height
760  && devmode.dmBitsPerPel == 32 ) {
761 
762  if ( ( cdsRet = ChangeDisplaySettings( &devmode, CDS_FULLSCREEN ) ) == DISP_CHANGE_SUCCESSFUL ) {
763  common->Printf( "ok\n" );
764  win32.cdsFullscreen = true;
765 
766  return true;
767  }
768  break;
769  }
770  }
771 
772  common->Printf( "\n...^3no high res mode found^0\n" );
773  return false;
774 }
775 
776 
777 
778 /*
779 ===================
780 GLimp_Init
781 
782 This is the platform specific OpenGL initialization function. It
783 is responsible for loading OpenGL, initializing it,
784 creating a window of the appropriate size, doing
785 fullscreen manipulations, etc. Its overall responsibility is
786 to make sure that a functional OpenGL subsystem is operating
787 when it returns to the ref.
788 
789 If there is any failure, the renderer will revert back to safe
790 parameters and try again.
791 ===================
792 */
793 bool GLimp_Init( glimpParms_t parms ) {
794  const char *driverName;
795  HDC hDC;
796 
797  common->Printf( "Initializing OpenGL subsystem\n" );
798 
799  // check our desktop attributes
800  hDC = GetDC( GetDesktopWindow() );
801  win32.desktopBitsPixel = GetDeviceCaps( hDC, BITSPIXEL );
802  win32.desktopWidth = GetDeviceCaps( hDC, HORZRES );
803  win32.desktopHeight = GetDeviceCaps( hDC, VERTRES );
804  ReleaseDC( GetDesktopWindow(), hDC );
805 
806  // we can't run in a window unless it is 32 bpp
807  if ( win32.desktopBitsPixel < 32 && !parms.fullScreen ) {
808  common->Printf("^3Windowed mode requires 32 bit desktop depth^0\n");
809  return false;
810  }
811 
812  // save the hardware gamma so it can be
813  // restored on exit
814  GLimp_SaveGamma();
815 
816  // create our window classes if we haven't already
817  GLW_CreateWindowClasses();
818 
819  // this will load the dll and set all our qgl* function pointers,
820  // but doesn't create a window
821 
822  // r_glDriver is only intended for using instrumented OpenGL
823  // dlls. Normal users should never have to use it, and it is
824  // not archived.
825  driverName = r_glDriver.GetString()[0] ? r_glDriver.GetString() : "opengl32";
826  if ( !QGL_Init( driverName ) ) {
827  common->Printf( "^3GLimp_Init() could not load r_glDriver \"%s\"^0\n", driverName );
828  return false;
829  }
830 
831  // getting the wgl extensions involves creating a fake window to get a context,
832  // which is pretty disgusting, and seems to mess with the AGP VAR allocation
833  GLW_GetWGLExtensionsWithFakeWindow();
834 
835  // try to change to fullscreen
836  if ( parms.fullScreen ) {
837  if ( !GLW_SetFullScreen( parms ) ) {
838  GLimp_Shutdown();
839  return false;
840  }
841  }
842 
843  // try to create a window with the correct pixel format
844  // and init the renderer context
845  if ( !GLW_CreateWindow( parms ) ) {
846  GLimp_Shutdown();
847  return false;
848  }
849 
850  // wglSwapinterval, etc
852 
853  // check logging
855 
856  return true;
857 }
858 
859 
860 /*
861 ===================
862 GLimp_SetScreenParms
863 
864 Sets up the screen based on passed parms..
865 ===================
866 */
868  int exstyle;
869  int stylebits;
870  int x, y, w, h;
871  DEVMODE dm;
872 
873  memset( &dm, 0, sizeof( dm ) );
874  dm.dmSize = sizeof( dm );
875  dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
876  if ( parms.displayHz != 0 ) {
877  dm.dmDisplayFrequency = parms.displayHz;
878  dm.dmFields |= DM_DISPLAYFREQUENCY;
879  }
880 
883 
884  if ( parms.fullScreen ) {
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;
892  x = y = w = h = 0;
893  } else {
894  RECT r;
895 
896  // adjust width and height for window border
897  r.bottom = parms.height;
898  r.left = 0;
899  r.top = 0;
900  r.right = parms.width;
901 
902  w = r.right - r.left;
903  h = r.bottom - r.top;
904 
905  x = win32.win_xpos.GetInteger();
906  y = win32.win_ypos.GetInteger();
907 
908  // adjust window coordinates if necessary
909  // so that the window is completely on screen
910  if ( x + w > win32.desktopWidth ) {
911  x = ( win32.desktopWidth - w );
912  }
913  if ( y + h > win32.desktopHeight ) {
914  y = ( win32.desktopHeight - h );
915  }
916  if ( x < 0 ) {
917  x = 0;
918  }
919  if ( y < 0 ) {
920  y = 0;
921  }
922  dm.dmPelsWidth = win32.desktopWidth;
923  dm.dmPelsHeight = win32.desktopHeight;
924  dm.dmBitsPerPel = win32.desktopBitsPixel;
925  exstyle = 0;
926  stylebits = WINDOW_STYLE|WS_SYSMENU;
927  AdjustWindowRect (&r, stylebits, FALSE);
928  SetWindowLong( win32.hWnd, GWL_STYLE, stylebits );
929  SetWindowLong( win32.hWnd, GWL_EXSTYLE, exstyle );
930  common->Printf( "%i %i %i %i\n", x, y, w, h );
931  }
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 );
934  return ret;
935 }
936 
937 /*
938 ===================
939 GLimp_Shutdown
940 
941 This routine does all OS specific shutdown procedures for the OpenGL
942 subsystem.
943 ===================
944 */
945 void GLimp_Shutdown( void ) {
946  const char *success[] = { "failed", "success" };
947  int retVal;
948 
949  common->Printf( "Shutting down OpenGL subsystem\n" );
950 
951  // set current context to NULL
952  if ( qwglMakeCurrent ) {
953  retVal = qwglMakeCurrent( NULL, NULL ) != 0;
954  common->Printf( "...wglMakeCurrent( NULL, NULL ): %s\n", success[retVal] );
955  }
956 
957  // delete HGLRC
958  if ( win32.hGLRC ) {
959  retVal = qwglDeleteContext( win32.hGLRC ) != 0;
960  common->Printf( "...deleting GL context: %s\n", success[retVal] );
961  win32.hGLRC = NULL;
962  }
963 
964  // release DC
965  if ( win32.hDC ) {
966  retVal = ReleaseDC( win32.hWnd, win32.hDC ) != 0;
967  common->Printf( "...releasing DC: %s\n", success[retVal] );
968  win32.hDC = NULL;
969  }
970 
971  // destroy window
972  if ( win32.hWnd ) {
973  common->Printf( "...destroying window\n" );
974  ShowWindow( win32.hWnd, SW_HIDE );
975  DestroyWindow( win32.hWnd );
976  win32.hWnd = NULL;
977  }
978 
979  // reset display settings
980  if ( win32.cdsFullscreen ) {
981  common->Printf( "...resetting display\n" );
982  ChangeDisplaySettings( 0, 0 );
983  win32.cdsFullscreen = false;
984  }
985 
986  // close the thread so the handle doesn't dangle
987  if ( win32.renderThreadHandle ) {
988  common->Printf( "...closing smp thread\n" );
989  CloseHandle( win32.renderThreadHandle );
991  }
992 
993  // restore gamma
995 
996  // shutdown QGL subsystem
997  QGL_Shutdown();
998 }
999 
1000 
1001 /*
1002 =====================
1003 GLimp_SwapBuffers
1004 =====================
1005 */
1006 void GLimp_SwapBuffers( void ) {
1007  //
1008  // wglSwapinterval is a windows-private extension,
1009  // so we must check for it here instead of portably
1010  //
1011  if ( r_swapInterval.IsModified() ) {
1013 
1014  if ( wglSwapIntervalEXT ) {
1016  }
1017  }
1018 
1019  qwglSwapBuffers( win32.hDC );
1020 
1021 //Sys_DebugPrintf( "*** SwapBuffers() ***\n" );
1022 }
1023 
1024 /*
1025 ===========================================================
1026 
1027 SMP acceleration
1028 
1029 ===========================================================
1030 */
1031 
1032 //#define REALLOC_DC
1033 
1034 /*
1035 ===================
1036 GLimp_ActivateContext
1037 
1038 ===================
1039 */
1041  if ( !qwglMakeCurrent( win32.hDC, win32.hGLRC ) ) {
1042  win32.wglErrors++;
1043  }
1044 }
1045 
1046 /*
1047 ===================
1048 GLimp_DeactivateContext
1049 
1050 ===================
1051 */
1053  qglFinish();
1054  if ( !qwglMakeCurrent( win32.hDC, NULL ) ) {
1055  win32.wglErrors++;
1056  }
1057 #ifdef REALLOC_DC
1058  // makeCurrent NULL frees the DC, so get another
1059  if ( ( win32.hDC = GetDC( win32.hWnd ) ) == NULL ) {
1060  win32.wglErrors++;
1061  }
1062 #endif
1063 
1064 }
1065 
1066 /*
1067 ===================
1068 GLimp_RenderThreadWrapper
1069 
1070 ===================
1071 */
1072 static void GLimp_RenderThreadWrapper( void ) {
1074 
1075  // unbind the context before we die
1076  qwglMakeCurrent( win32.hDC, NULL );
1077 }
1078 
1079 /*
1080 =======================
1081 GLimp_SpawnRenderThread
1082 
1083 Returns false if the system only has a single processor
1084 =======================
1085 */
1086 bool GLimp_SpawnRenderThread( void (*function)( void ) ) {
1087  SYSTEM_INFO info;
1088 
1089  // check number of processors
1090  GetSystemInfo( &info );
1091  if ( info.dwNumberOfProcessors < 2 ) {
1092  return false;
1093  }
1094 
1095  // create the IPC elements
1096  win32.renderCommandsEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
1097  win32.renderCompletedEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
1098  win32.renderActiveEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
1099 
1100  win32.glimpRenderThread = function;
1101 
1102  win32.renderThreadHandle = CreateThread(
1103  NULL, // LPSECURITY_ATTRIBUTES lpsa,
1104  0, // DWORD cbStack,
1105  (LPTHREAD_START_ROUTINE)GLimp_RenderThreadWrapper, // LPTHREAD_START_ROUTINE lpStartAddr,
1106  0, // LPVOID lpvThreadParm,
1107  0, // DWORD fdwCreate,
1108  &win32.renderThreadId );
1109 
1110  if ( !win32.renderThreadHandle ) {
1111  common->Error( "GLimp_SpawnRenderThread: failed" );
1112  }
1113 
1114  SetThreadPriority( win32.renderThreadHandle, THREAD_PRIORITY_ABOVE_NORMAL );
1115 #if 0
1116  // make sure they always run on different processors
1117  SetThreadAffinityMask( GetCurrentThread, 1 );
1118  SetThreadAffinityMask( win32.renderThreadHandle, 2 );
1119 #endif
1120 
1121  return true;
1122 }
1123 
1124 
1125 //#define DEBUG_PRINTS
1126 
1127 /*
1128 ===================
1129 GLimp_BackEndSleep
1130 
1131 ===================
1132 */
1133 void *GLimp_BackEndSleep( void ) {
1134  void *data;
1135 
1136 #ifdef DEBUG_PRINTS
1137 OutputDebugString( "-->GLimp_BackEndSleep\n" );
1138 #endif
1139  ResetEvent( win32.renderActiveEvent );
1140 
1141  // after this, the front end can exit GLimp_FrontEndSleep
1142  SetEvent( win32.renderCompletedEvent );
1143 
1144  WaitForSingleObject( win32.renderCommandsEvent, INFINITE );
1145 
1146  ResetEvent( win32.renderCompletedEvent );
1147  ResetEvent( win32.renderCommandsEvent );
1148 
1149  data = win32.smpData;
1150 
1151  // after this, the main thread can exit GLimp_WakeRenderer
1152  SetEvent( win32.renderActiveEvent );
1153 
1154 #ifdef DEBUG_PRINTS
1155 OutputDebugString( "<--GLimp_BackEndSleep\n" );
1156 #endif
1157  return data;
1158 }
1159 
1160 /*
1161 ===================
1162 GLimp_FrontEndSleep
1163 
1164 ===================
1165 */
1166 void GLimp_FrontEndSleep( void ) {
1167 #ifdef DEBUG_PRINTS
1168 OutputDebugString( "-->GLimp_FrontEndSleep\n" );
1169 #endif
1170  WaitForSingleObject( win32.renderCompletedEvent, INFINITE );
1171 
1172 #ifdef DEBUG_PRINTS
1173 OutputDebugString( "<--GLimp_FrontEndSleep\n" );
1174 #endif
1175 }
1176 
1177 volatile bool renderThreadActive;
1178 
1179 /*
1180 ===================
1181 GLimp_WakeBackEnd
1182 
1183 ===================
1184 */
1185 void GLimp_WakeBackEnd( void *data ) {
1186  int r;
1187 
1188 #ifdef DEBUG_PRINTS
1189 OutputDebugString( "-->GLimp_WakeBackEnd\n" );
1190 #endif
1191  win32.smpData = data;
1192 
1193  if ( renderThreadActive ) {
1194  common->FatalError( "GLimp_WakeBackEnd: already active" );
1195  }
1196 
1197  r = WaitForSingleObject( win32.renderActiveEvent, 0 );
1198  if ( r == WAIT_OBJECT_0 ) {
1199  common->FatalError( "GLimp_WakeBackEnd: already signaled" );
1200  }
1201 
1202  r = WaitForSingleObject( win32.renderCommandsEvent, 0 );
1203  if ( r == WAIT_OBJECT_0 ) {
1204  common->FatalError( "GLimp_WakeBackEnd: commands already signaled" );
1205  }
1206 
1207  // after this, the renderer can continue through GLimp_RendererSleep
1208  SetEvent( win32.renderCommandsEvent );
1209 
1210  r = WaitForSingleObject( win32.renderActiveEvent, 5000 );
1211 
1212  if ( r == WAIT_TIMEOUT ) {
1213  common->FatalError( "GLimp_WakeBackEnd: WAIT_TIMEOUT" );
1214  }
1215 
1216 #ifdef DEBUG_PRINTS
1217 OutputDebugString( "<--GLimp_WakeBackEnd\n" );
1218 #endif
1219 }
1220 
1221 //===================================================================
1222 
1223 /*
1224 ===================
1225 GLimp_ExtensionPointer
1226 
1227 Returns a function pointer for an OpenGL extension entry point
1228 ===================
1229 */
1231  void (*proc)(void);
1232 
1233  proc = (GLExtension_t)qwglGetProcAddress( name );
1234 
1235  if ( !proc ) {
1236  common->Printf( "Couldn't find proc address for: %s\n", name );
1237  }
1238 
1239  return proc;
1240 }
1241 
FLOAT
Definition: win_qgl.cpp:63
PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB
Definition: win_glimp.cpp:68
PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB
Definition: win_glimp.cpp:66
GLsizei const GLfloat * value
Definition: glext.h:3614
void GLimp_SwapBuffers(void)
Definition: win_glimp.cpp:1006
idCVar r_glDriver("r_glDriver","", CVAR_RENDERER,"\"opengl32\", etc.")
#define WIN32_FAKE_WINDOW_CLASS_NAME
Definition: Licensee.h:98
#define WGL_DEPTH_BITS_ARB
Definition: win_glimp.cpp:113
bool windowClassRegistered
Definition: win_local.h:117
int multiSamples
Definition: tr_local.h:1076
idCVar r_swapInterval("r_swapInterval","0", CVAR_RENDERER|CVAR_ARCHIVE|CVAR_INTEGER,"changes wglSwapIntarval")
CONST PIXELFORMATDESCRIPTOR UINT
Definition: win_qgl.cpp:47
HGLRC hGLRC
Definition: win_local.h:122
bool fullScreen
Definition: tr_local.h:1073
#define GAME_NAME
Definition: Licensee.h:37
#define WGL_BLUE_BITS_ARB
Definition: win_glimp.cpp:104
bool QGL_Init(const char *dllname)
Definition: win_qgl.cpp:1690
GLenum GLint GLint y
Definition: glext.h:2849
PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB
Definition: win_glimp.cpp:74
void * smpData
Definition: win_local.h:167
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glext.h:2846
void GLimp_WakeBackEnd(void *data)
Definition: win_glimp.cpp:1185
#define WINAPI
Definition: qgl.h:64
volatile bool renderThreadActive
Definition: win_glimp.cpp:1177
GLclampf GLclampf blue
Definition: glext.h:2843
bool isFullscreen
Definition: RenderSystem.h:90
unsigned short oldHardwareGamma[3][256]
Definition: win_local.h:135
GLuint src
Definition: glext.h:5390
void(* GLExtension_t)(void)
Definition: qgl.h:75
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
#define BOOL
Definition: mprintf.c:71
void GLimp_SetGamma(unsigned short red[256], unsigned short green[256], unsigned short blue[256])
Definition: win_glimp.cpp:188
LONG WINAPI FakeWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: win_glimp.cpp:224
#define WGL_DOUBLE_BUFFER_ARB
Definition: win_glimp.cpp:96
void SetModified(void)
Definition: CVarSystem.h:138
static idCVar win_ypos
Definition: win_local.h:145
bool cdsFullscreen
Definition: win_local.h:131
const char * wgl_extensions_string
Definition: RenderSystem.h:49
void(* glimpRenderThread)(void)
Definition: win_local.h:166
PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB
Definition: win_glimp.cpp:67
LONG WINAPI MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
HANDLE renderActiveEvent
Definition: win_local.h:163
HANDLE renderCompletedEvent
Definition: win_local.h:162
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
static idCVar win_xpos
Definition: win_local.h:144
PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB
Definition: win_glimp.cpp:73
void GLimp_FrontEndSleep(void)
Definition: win_glimp.cpp:1166
idCommon * common
Definition: Common.cpp:206
int wglErrors
Definition: win_local.h:168
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT
Definition: win_glimp.cpp:58
#define NULL
Definition: Lib.h:88
HDC hDC
Definition: wglext.h:383
PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB
Definition: win_glimp.cpp:69
void GLW_WM_CREATE(HWND hWnd)
Definition: win_glimp.cpp:354
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:2853
int GetInteger(void) const
Definition: CVarSystem.h:143
#define WGL_STENCIL_BITS_ARB
Definition: win_glimp.cpp:114
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()
Definition: glimp.cpp:131
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB
Definition: win_glimp.cpp:63
typedef HDC(WINAPI *PFNWGLGETCURRENTREADDCARBPROC)(void)
int desktopWidth
Definition: win_local.h:129
virtual void Printf(const char *fmt,...) id_attribute((format(printf
void GLimp_EnableLogging(bool enable)
Definition: dedicated.cpp:75
void GLimp_ActivateContext(void)
Definition: win_glimp.cpp:1040
bool GLimp_SetScreenParms(glimpParms_t parms)
Definition: win_glimp.cpp:867
bool GLimp_SpawnRenderThread(void(*function)(void))
Definition: win_glimp.cpp:1086
const char * GetString(void) const
Definition: CVarSystem.h:141
#define WGL_RED_BITS_ARB
Definition: win_glimp.cpp:100
long LONG
GLdouble GLdouble GLdouble r
Definition: glext.h:2951
HGLRC
Definition: win_qgl.cpp:52
glconfig_t glConfig
#define IDI_ICON1
Definition: doom_resource.h:30
PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB
Definition: win_glimp.cpp:61
void ClearModified(void)
Definition: CVarSystem.h:139
HANDLE renderThreadHandle
Definition: win_local.h:164
void * GLimp_BackEndSleep(void)
Definition: win_glimp.cpp:1133
unsigned char byte
Definition: Lib.h:75
const GLcharARB * name
Definition: glext.h:3629
#define WGL_SAMPLE_BUFFERS_ARB
Definition: win_glimp.cpp:131
void GLimp_SaveGamma()
Definition: glimp.cpp:110
#define WGL_GREEN_BITS_ARB
Definition: win_glimp.cpp:102
bool IsModified(void) const
Definition: CVarSystem.h:137
GLExtension_t GLimp_ExtensionPointer(const char *name)
Definition: win_glimp.cpp:1230
#define WGL_SAMPLES_ARB
Definition: win_glimp.cpp:132
#define WGL_ALPHA_BITS_ARB
Definition: win_glimp.cpp:106
PIXELFORMATDESCRIPTOR pfd
Definition: win_local.h:123
PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB
Definition: win_glimp.cpp:62
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
#define FALSE
Definition: mprintf.c:70
#define qglFinish
Definition: qgl_linked.h:118
#define WIN32_WINDOW_CLASS_NAME
Definition: Licensee.h:97
int desktopBitsPixel
Definition: win_local.h:128
HANDLE renderCommandsEvent
Definition: win_local.h:161
void GLW_CheckWGLExtensions(HDC hDC)
Definition: win_glimp.cpp:281
PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB
Definition: win_glimp.cpp:70
#define TRUE
Definition: mprintf.c:69
void QGL_Shutdown(void)
Definition: win_qgl.cpp:1302
HINSTANCE hInstance
Definition: win_local.h:102
bool GLimp_Init(glimpParms_t parms)
Definition: win_glimp.cpp:793
unsigned long renderThreadId
Definition: win_local.h:165
#define WINDOW_STYLE
Definition: win_local.h:61
Win32Vars_t win32
Definition: win_main.cpp:65
const char *WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC(HDC hdc)
Definition: wglext.h:347
void GLimp_Shutdown(void)
Definition: win_glimp.cpp:945
virtual void DPrintf(const char *fmt,...) id_attribute((format(printf
virtual void Error(const char *fmt,...) id_attribute((format(printf
int pixelformat
Definition: win_local.h:124
PFNWGLSETPBUFFERATTRIBARBPROC wglSetPbufferAttribARB
Definition: win_glimp.cpp:75
void OutputDebugString(const char *text)
Definition: macosx_sys.mm:243
void GLimp_DeactivateContext(void)
Definition: win_glimp.cpp:1052
int desktopHeight
Definition: win_local.h:129
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB
Definition: win_glimp.cpp:55
GLclampf green
Definition: glext.h:2843
int stencilBits
Definition: RenderSystem.h:60