2 * $Source: /cvs/cvsroot/d2x/arch/ogl/wgl.c,v $
5 * $Date: 2001-10-25 08:25:34 $
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 $
13 * Revision 1.2 2001/01/29 13:47:52 bradleyb
14 * Fixed build, some minor cleanups.
32 /*#include "event.h"*/
38 extern int Inferno_verbose;
40 static int mouse_hidden=0;
43 //extern unsigned int key_wparam, key_lparam, key_msg;
44 void keyboard_handler();
45 extern int WMKey_Handler_Ready;
49 static int GLPREF_width,GLPREF_height;
50 static int GLSTATE_width,GLSTATE_height;
51 static bool GLPREF_windowed;
53 static HGLRC GL_ResourceContext=NULL;
54 //static WORD Saved_gamma_values[256*3];
55 bool OpenGL_Initialize(void);
56 void OpenGL_Shutdown(void);
59 void PumpMessages(void)
63 while (PeekMessage(&msg,NULL,0,0,PM_REMOVE|PM_NOYIELD))
65 TranslateMessage(&msg);
66 DispatchMessage(&msg);
69 static void finiObjects()
77 // DisableOpenGL( g_hWnd, hDC, hRC );
81 long PASCAL DescentWndProc(HWND hWnd,UINT message,
82 WPARAM wParam,LPARAM lParam )
89 if (WMKey_Handler_Ready) {
90 // key_wparam=wParam; key_lparam=lParam; key_msg=message;
100 case WM_NCLBUTTONDOWN:
102 case WM_NCRBUTTONDOWN:
105 case WM_PALETTECHANGED:
106 case WM_PALETTEISCHANGING:
109 // Win32_Key_Hook(wParam);
110 // DPH: This doesn't work... no idea why not...
117 return DefWindowProc(hWnd,message,wParam,lParam);
122 void ogl_swap_buffers_internal(void){
126 int get_win_x_bs(void){
127 // return GetSystemMetrics(SM_CXBORDER)*2
128 return GetSystemMetrics(SM_CXFIXEDFRAME)*2;
130 int get_win_y_bs(void){
131 // return GetSystemMetrics(SM_CYBORDER)*2+GetSystemMetrics(SM_CYCAPTION);
132 return GetSystemMetrics(SM_CYFIXEDFRAME)*2+GetSystemMetrics(SM_CYCAPTION);
134 void win32_create_window(int x,int y)
138 WNDCLASS wcDescentClass;
141 Error("hInst=NULL\n");
144 wcDescentClass.lpszClassName = "WinD1X";
145 wcDescentClass.hInstance = hInst;
146 wcDescentClass.lpfnWndProc = DescentWndProc;
147 wcDescentClass.hCursor = LoadCursor(NULL, IDC_ARROW);
148 wcDescentClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
149 wcDescentClass.lpszMenuName = NULL;
150 wcDescentClass.hbrBackground = NULL;
151 wcDescentClass.style = CS_OWNDC;
152 wcDescentClass.cbClsExtra = 0;
153 wcDescentClass.cbWndExtra = 0;
155 // Register the class
156 if (!RegisterClass(&wcDescentClass)){
157 // printf("RegisterClass==0?\n");
158 //always seems to return 0 after the first time, yet if you remove the call, it crashes. Heh.
162 flags=WS_POPUP | WS_SYSMENU;
164 flags=WS_OVERLAPPED | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
166 if (!ogl_fullscreen){
167 x+=get_win_x_bs();y+=get_win_y_bs();
169 if (FindArg("-gl_test2")){
170 x=GetSystemMetrics(SM_CXSCREEN);
171 y=GetSystemMetrics(SM_CYSCREEN);
174 g_hWnd = CreateWindowEx(0,
186 if (!g_hWnd) Error("no window?\n");
187 ShowWindow(g_hWnd,SW_SHOWNORMAL);
188 UpdateWindow(g_hWnd);
196 if (!FindArg( "-nomouse" ))
198 if (!FindArg( "-nojoystick" ))
199 joy_init(JOYSTICKID1);
200 if (!FindArg( "-nosound" ))
202 // printf("arch_init successfully completed\n");
208 void ogl_destroy_window(void){
210 ogl_smash_texture_list_internal();
218 if (!FindArg( "-nomouse" ))
220 if (!FindArg( "-nojoystick" ))
222 if (!FindArg( "-nosound" ))
224 DestroyWindow(g_hWnd);
226 Error("ogl_destroy_window: no g_hWnd?\n");
232 void ogl_do_fullscreen_internal(void){
233 if (GLPREF_windowed==ogl_fullscreen){
234 ogl_destroy_window();
235 win32_create_window(GLPREF_width,GLPREF_height);
236 ogl_vivify_texture_list_internal();
241 int ogl_init_window(int x, int y){
245 if (GLSTATE_width==GLPREF_width && GLSTATE_height==GLPREF_height && GLPREF_windowed!=ogl_fullscreen)
246 return 0;//we are already in the right mode, don't do anything.
247 if (!ogl_fullscreen && GLPREF_windowed){
248 SetWindowPos(g_hWnd,0,0,0,x+get_win_x_bs(),y+get_win_y_bs(),SWP_NOMOVE);
250 ogl_destroy_window();
251 win32_create_window(x,y);
252 ogl_vivify_texture_list_internal();
255 win32_create_window(x,y);
260 hInst=GetModuleHandle (NULL);
262 void ogl_close(void){
263 ogl_destroy_window();
267 //windows opengl fullscreen changing - courtesy of Jeff Slutter
271 Windows Full Screen Setup
273 ===========================================================================
277 // Entering this function, the following values must be valid
278 // GLPREF_width,GLPREF_height: preferred width and height
279 // GLPREF_windowed: do we want windowed or full screen mode
280 // g_hWnd: handle to the window created for OpenGL
281 // On exit from this function (if returned true) the following values will be set
282 // GLSTATE_width,GLSTATE_height: real width and height of screen
283 // hDC: device context of the window
284 // GL_ResourceContext: OpenGL resource context
285 // Saved_gamma_values: Initial gamma values
286 bool OpenGL_Initialize(void)
291 PIXELFORMATDESCRIPTOR pfd;//, pfd_copy;
293 GLPREF_windowed=!ogl_fullscreen;
295 if (FindArg("-gl_test1")){
296 GLSTATE_width = GLPREF_width;
297 GLSTATE_height = GLPREF_height;
301 // First set our display mode
302 // Create direct draw surface
306 devmode.dmSize=sizeof(devmode);
307 devmode.dmBitsPerPel=16;
308 devmode.dmPelsWidth=GLPREF_width;
309 devmode.dmPelsHeight=GLPREF_height;
310 devmode.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
312 retval=ChangeDisplaySettings(&devmode,0);
314 if (retval!=DISP_CHANGE_SUCCESSFUL)
316 // we couldn't switch to the desired screen mode
317 // fall back to 640x480
319 devmode.dmBitsPerPel=16;
320 devmode.dmPelsWidth=640;
321 devmode.dmPelsHeight=480;
322 devmode.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
324 retval=ChangeDisplaySettings(&devmode,0);
325 if (retval!=DISP_CHANGE_SUCCESSFUL)
327 errstr="ChangeDisplaySettings";
328 // we couldn't even switch to 640x480, we're out of here
329 // restore screen mode to default
330 ChangeDisplaySettings(NULL,0);
334 // successful, change our global settings to reflect what
341 // success at changing the video mode
348 // we want windowed mode, figure out how big the window is
350 GetWindowRect(g_hWnd,&rect);
351 width=abs(rect.right-rect.left);
352 height=abs(rect.bottom-rect.top);
356 // full screen mode, we want the window to be on top of everything
357 SetWindowPos(g_hWnd,HWND_TOPMOST,0,0,GLPREF_width,GLPREF_height,SWP_FRAMECHANGED);
359 height=GLPREF_height;
360 GetWindowRect(g_hWnd,&rect);
363 GLSTATE_width = width;
364 GLSTATE_height = height;
370 // Now we finally setup OpenGL
371 // If OpenGL is to be dynamically loaded, do this now (if the DLL isn't already
373 // remove the following error when you figure out what you want to do
374 // it's put here to make sure you notice this
375 #ifdef OGL_RUNTIME_LOAD
376 ogl_init_load_library();
379 // Setup our pixel format
381 memset(&pfd,0,sizeof(pfd));
382 pfd.nSize = sizeof(pfd);
384 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
385 // pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_GENERIC_ACCELERATED;
386 pfd.iPixelType = PFD_TYPE_RGBA;
391 pfd.cStencilBits = 0;
392 pfd.iLayerType = PFD_MAIN_PLANE;
393 pfd.dwLayerMask = PFD_MAIN_PLANE;
396 // Find the user's "best match" PFD
397 pf = ChoosePixelFormat(hDC,&pfd);
400 errstr="ChoosePixelFormat";
401 // no pixel format closely matches
406 if(SetPixelFormat(hDC,pf,&pfd)==FALSE)
408 errstr="SetPixelFormat";
409 // unable to set the pixel format
413 // Now retrieve the PFD, we need to check some things
414 /* if(DescribePixelFormat(hDC,pf,sizeof(PIXELFORMATDESCRIPTOR),&pfd_copy)==0)
416 errstr="DescribePixelFormat";
417 // unable to get the PFD
421 // Make sure we are hardware accelerated
422 if((pfd_copy.dwFlags&PFD_GENERIC_ACCELERATED)==0&&(pfd_copy.dwFlags&PFD_GENERIC_FORMAT)!=0)
424 // we are not hardware accelerated!
428 // Finally, create our OpenGL context and make it current
429 GL_ResourceContext = wglCreateContext(hDC);
430 if(GL_ResourceContext==NULL)
432 errstr="wglCreateContext";
433 // we couldn't create a context!
437 // Make the context current
438 wglMakeCurrent(hDC,GL_ResourceContext);
440 // Save our gamma values because we'll probably be changing them,
441 // this way we can restore them on exit
443 // GetDeviceGammaRamp(hDC,(LPVOID)Saved_gamma_values);
450 Error("opengl init error: %s\n",errstr);
454 void OpenGL_Shutdown(void)
456 // Do any needed OpenGL shutdown here
459 // Now do Window specific shutdown
460 if(wglMakeCurrent)//check to make sure the function is valid (dyanmic loaded OpenGL)
461 wglMakeCurrent(NULL, NULL);
463 if(wglDeleteContext)//check to make sure the function is valid (dyanmic loaded OpenGL)
464 wglDeleteContext(GL_ResourceContext);
466 // Restore back to user screen settings
468 ChangeDisplaySettings(NULL,0);
470 // Restore gamma values
472 // SetDeviceGammaRamp(hDC,(LPVOID)Saved_gamma_values);
474 ReleaseDC(g_hWnd,hDC);