2 * $Source: /cvs/cvsroot/d2x/video/ogl_wgl.c,v $
5 * $Date: 2001-01-29 13:47:52 $
7 * opengl platform specific functions for WGL - added by Peter Hawkins
8 * fullscreen example code courtesy of Jeff Slutter
9 * everything merged together and cleaned up by Matt Mueller
10 * (with some win32 help from Nirvana)
12 * $Log: not supported by cvs2svn $
29 /*#include "event.h"*/
35 extern int Inferno_verbose;
37 static int mouse_hidden=0;
40 //extern unsigned int key_wparam, key_lparam, key_msg;
41 void keyboard_handler();
42 extern int WMKey_Handler_Ready;
46 static int GLPREF_width,GLPREF_height;
47 static int GLSTATE_width,GLSTATE_height;
48 static bool GLPREF_windowed;
50 static HGLRC GL_ResourceContext=NULL;
51 //static WORD Saved_gamma_values[256*3];
52 bool OpenGL_Initialize(void);
53 void OpenGL_Shutdown(void);
56 void PumpMessages(void)
60 while (PeekMessage(&msg,NULL,0,0,PM_REMOVE|PM_NOYIELD))
62 TranslateMessage(&msg);
63 DispatchMessage(&msg);
66 static void finiObjects()
74 // DisableOpenGL( g_hWnd, hDC, hRC );
78 long PASCAL DescentWndProc(HWND hWnd,UINT message,
79 WPARAM wParam,LPARAM lParam )
86 if (WMKey_Handler_Ready) {
87 // key_wparam=wParam; key_lparam=lParam; key_msg=message;
97 case WM_NCLBUTTONDOWN:
99 case WM_NCRBUTTONDOWN:
102 case WM_PALETTECHANGED:
103 case WM_PALETTEISCHANGING:
106 // Win32_Key_Hook(wParam);
107 // DPH: This doesn't work... no idea why not...
114 return DefWindowProc(hWnd,message,wParam,lParam);
119 void ogl_swap_buffers_internal(void){
123 int get_win_x_bs(void){
124 // return GetSystemMetrics(SM_CXBORDER)*2
125 return GetSystemMetrics(SM_CXFIXEDFRAME)*2;
127 int get_win_y_bs(void){
128 // return GetSystemMetrics(SM_CYBORDER)*2+GetSystemMetrics(SM_CYCAPTION);
129 return GetSystemMetrics(SM_CYFIXEDFRAME)*2+GetSystemMetrics(SM_CYCAPTION);
131 void win32_create_window(int x,int y)
135 WNDCLASS wcDescentClass;
138 Error("hInst=NULL\n");
141 wcDescentClass.lpszClassName = "WinD1X";
142 wcDescentClass.hInstance = hInst;
143 wcDescentClass.lpfnWndProc = DescentWndProc;
144 wcDescentClass.hCursor = LoadCursor(NULL, IDC_ARROW);
145 wcDescentClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
146 wcDescentClass.lpszMenuName = NULL;
147 wcDescentClass.hbrBackground = NULL;
148 wcDescentClass.style = CS_OWNDC;
149 wcDescentClass.cbClsExtra = 0;
150 wcDescentClass.cbWndExtra = 0;
152 // Register the class
153 if (!RegisterClass(&wcDescentClass)){
154 // printf("RegisterClass==0?\n");
155 //always seems to return 0 after the first time, yet if you remove the call, it crashes. Heh.
159 flags=WS_POPUP | WS_SYSMENU;
161 flags=WS_OVERLAPPED | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
163 if (!ogl_fullscreen){
164 x+=get_win_x_bs();y+=get_win_y_bs();
166 if (FindArg("-gl_test2")){
167 x=GetSystemMetrics(SM_CXSCREEN);
168 y=GetSystemMetrics(SM_CYSCREEN);
171 g_hWnd = CreateWindowEx(0,
183 if (!g_hWnd) Error("no window?\n");
184 ShowWindow(g_hWnd,SW_SHOWNORMAL);
185 UpdateWindow(g_hWnd);
193 if (!FindArg( "-nomouse" ))
195 if (!FindArg( "-nojoystick" ))
196 joy_init(JOYSTICKID1);
197 if (!FindArg( "-nosound" ))
199 // printf("arch_init successfully completed\n");
205 void ogl_destroy_window(void){
207 ogl_smash_texture_list_internal();
215 if (!FindArg( "-nomouse" ))
217 if (!FindArg( "-nojoystick" ))
219 if (!FindArg( "-nosound" ))
221 DestroyWindow(g_hWnd);
223 Error("ogl_destroy_window: no g_hWnd?\n");
229 void ogl_do_fullscreen_internal(void){
230 if (GLPREF_windowed==ogl_fullscreen){
231 ogl_destroy_window();
232 win32_create_window(GLPREF_width,GLPREF_height);
233 ogl_vivify_texture_list_internal();
238 int ogl_init_window(int x, int y){
242 if (GLSTATE_width==GLPREF_width && GLSTATE_height==GLPREF_height && GLPREF_windowed!=ogl_fullscreen)
243 return 0;//we are already in the right mode, don't do anything.
244 if (!ogl_fullscreen && GLPREF_windowed){
245 SetWindowPos(g_hWnd,0,0,0,x+get_win_x_bs(),y+get_win_y_bs(),SWP_NOMOVE);
247 ogl_destroy_window();
248 win32_create_window(x,y);
249 ogl_vivify_texture_list_internal();
252 win32_create_window(x,y);
257 hInst=GetModuleHandle (NULL);
259 void ogl_close(void){
260 ogl_destroy_window();
264 //windows opengl fullscreen changing - courtesy of Jeff Slutter
268 Windows Full Screen Setup
270 ===========================================================================
274 // Entering this function, the following values must be valid
275 // GLPREF_width,GLPREF_height: preferred width and height
276 // GLPREF_windowed: do we want windowed or full screen mode
277 // g_hWnd: handle to the window created for OpenGL
278 // On exit from this function (if returned true) the following values will be set
279 // GLSTATE_width,GLSTATE_height: real width and height of screen
280 // hDC: device context of the window
281 // GL_ResourceContext: OpenGL resource context
282 // Saved_gamma_values: Initial gamma values
283 bool OpenGL_Initialize(void)
288 PIXELFORMATDESCRIPTOR pfd;//, pfd_copy;
290 GLPREF_windowed=!ogl_fullscreen;
292 if (FindArg("-gl_test1")){
293 GLSTATE_width = GLPREF_width;
294 GLSTATE_height = GLPREF_height;
298 // First set our display mode
299 // Create direct draw surface
303 devmode.dmSize=sizeof(devmode);
304 devmode.dmBitsPerPel=16;
305 devmode.dmPelsWidth=GLPREF_width;
306 devmode.dmPelsHeight=GLPREF_height;
307 devmode.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
309 retval=ChangeDisplaySettings(&devmode,0);
311 if (retval!=DISP_CHANGE_SUCCESSFUL)
313 // we couldn't switch to the desired screen mode
314 // fall back to 640x480
316 devmode.dmBitsPerPel=16;
317 devmode.dmPelsWidth=640;
318 devmode.dmPelsHeight=480;
319 devmode.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
321 retval=ChangeDisplaySettings(&devmode,0);
322 if (retval!=DISP_CHANGE_SUCCESSFUL)
324 errstr="ChangeDisplaySettings";
325 // we couldn't even switch to 640x480, we're out of here
326 // restore screen mode to default
327 ChangeDisplaySettings(NULL,0);
331 // successful, change our global settings to reflect what
338 // success at changing the video mode
345 // we want windowed mode, figure out how big the window is
347 GetWindowRect(g_hWnd,&rect);
348 width=abs(rect.right-rect.left);
349 height=abs(rect.bottom-rect.top);
353 // full screen mode, we want the window to be on top of everything
354 SetWindowPos(g_hWnd,HWND_TOPMOST,0,0,GLPREF_width,GLPREF_height,SWP_FRAMECHANGED);
356 height=GLPREF_height;
357 GetWindowRect(g_hWnd,&rect);
360 GLSTATE_width = width;
361 GLSTATE_height = height;
367 // Now we finally setup OpenGL
368 // If OpenGL is to be dynamically loaded, do this now (if the DLL isn't already
370 // remove the following error when you figure out what you want to do
371 // it's put here to make sure you notice this
372 #ifdef OGL_RUNTIME_LOAD
373 ogl_init_load_library();
376 // Setup our pixel format
378 memset(&pfd,0,sizeof(pfd));
379 pfd.nSize = sizeof(pfd);
381 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
382 // pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_GENERIC_ACCELERATED;
383 pfd.iPixelType = PFD_TYPE_RGBA;
388 pfd.cStencilBits = 0;
389 pfd.iLayerType = PFD_MAIN_PLANE;
390 pfd.dwLayerMask = PFD_MAIN_PLANE;
393 // Find the user's "best match" PFD
394 pf = ChoosePixelFormat(hDC,&pfd);
397 errstr="ChoosePixelFormat";
398 // no pixel format closely matches
403 if(SetPixelFormat(hDC,pf,&pfd)==FALSE)
405 errstr="SetPixelFormat";
406 // unable to set the pixel format
410 // Now retrieve the PFD, we need to check some things
411 /* if(DescribePixelFormat(hDC,pf,sizeof(PIXELFORMATDESCRIPTOR),&pfd_copy)==0)
413 errstr="DescribePixelFormat";
414 // unable to get the PFD
418 // Make sure we are hardware accelerated
419 if((pfd_copy.dwFlags&PFD_GENERIC_ACCELERATED)==0&&(pfd_copy.dwFlags&PFD_GENERIC_FORMAT)!=0)
421 // we are not hardware accelerated!
425 // Finally, create our OpenGL context and make it current
426 GL_ResourceContext = wglCreateContext(hDC);
427 if(GL_ResourceContext==NULL)
429 errstr="wglCreateContext";
430 // we couldn't create a context!
434 // Make the context current
435 wglMakeCurrent(hDC,GL_ResourceContext);
437 // Save our gamma values because we'll probably be changing them,
438 // this way we can restore them on exit
440 // GetDeviceGammaRamp(hDC,(LPVOID)Saved_gamma_values);
447 Error("opengl init error: %s\n",errstr);
451 void OpenGL_Shutdown(void)
453 // Do any needed OpenGL shutdown here
456 // Now do Window specific shutdown
457 if(wglMakeCurrent)//check to make sure the function is valid (dyanmic loaded OpenGL)
458 wglMakeCurrent(NULL, NULL);
460 if(wglDeleteContext)//check to make sure the function is valid (dyanmic loaded OpenGL)
461 wglDeleteContext(GL_ResourceContext);
463 // Restore back to user screen settings
465 ChangeDisplaySettings(NULL,0);
467 // Restore gamma values
469 // SetDeviceGammaRamp(hDC,(LPVOID)Saved_gamma_values);
471 ReleaseDC(g_hWnd,hDC);