/* vid_win_gl.c Win32 GL vid component Copyright (C) 1996-1997 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "winquake.h" #include #include "QF/cvar.h" #include "QF/sys.h" #include "QF/vid.h" #include "context_win.h" #include "r_internal.h" #include "vid_internal.h" #include "vid_gl.h" // Define GLAPIENTRY to a useful value #ifndef GLAPIENTRY # define GLAPIENTRY WINAPI #endif static void *libgl_handle; static HGLRC (GLAPIENTRY * qfwglCreateContext) (HDC); static BOOL (GLAPIENTRY * qfwglDeleteContext) (HGLRC); static HGLRC (GLAPIENTRY * qfwglGetCurrentContext) (void); static HDC (GLAPIENTRY * qfwglGetCurrentDC) (void); static BOOL (GLAPIENTRY * qfwglMakeCurrent) (HDC, HGLRC); static void (GLAPIENTRY *qfglFinish) (void); static void *(WINAPI * glGetProcAddress) (const char *symbol) = NULL; static int use_gl_proceaddress = 0; static char *gl_driver; static cvar_t gl_driver_cvar = { .name = "gl_driver", .description = "The OpenGL library to use. (path optional)", .default_value = GL_DRIVER, .flags = CVAR_ROM, .value = { .type = 0, .value = &gl_driver }, }; static HGLRC baseRC;//FIXME should be in gl_ctx_t, but that's GLXContext... static void * QFGL_GetProcAddress (void *handle, const char *name) { void *glfunc = NULL; if (use_gl_proceaddress && glGetProcAddress) glfunc = glGetProcAddress (name); if (!glfunc) glfunc = GetProcAddress (handle, name); return glfunc; } static void * QFGL_ProcAddress (const char *name, qboolean crit) { void *glfunc = NULL; Sys_MaskPrintf (SYS_vid, "DEBUG: Finding symbol %s ... ", name); glfunc = QFGL_GetProcAddress (libgl_handle, name); if (glfunc) { Sys_MaskPrintf (SYS_vid, "found [%p]\n", glfunc); return glfunc; } Sys_MaskPrintf (SYS_vid, "not found\n"); if (crit) { Sys_Error ("Couldn't load critical OpenGL function %s, exiting...", name); } return NULL; } static void wgl_choose_visual (gl_ctx_t *ctx) { } static void wgl_set_pixel_format (void) { int pixelformat; PIXELFORMATDESCRIPTOR pfd = { .nSize = sizeof(PIXELFORMATDESCRIPTOR), .nVersion = 1, .dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW, .iPixelType = PFD_TYPE_RGBA, .cColorBits = win_gdevmode.dmBitsPerPel, .cDepthBits = 32, .iLayerType = PFD_MAIN_PLANE, }; if (!(pixelformat = ChoosePixelFormat (win_maindc, &pfd))) { Sys_Error ("ChoosePixelFormat failed"); } if (!SetPixelFormat (win_maindc, pixelformat, &pfd)) { Sys_Error ("SetPixelFormat failed"); } } static void wgl_create_context (gl_ctx_t *ctx, int core) { DWORD lasterror; win_maindc = GetDC (win_mainwindow); wgl_set_pixel_format (); baseRC = qfwglCreateContext (win_maindc); if (!baseRC) { lasterror=GetLastError(); if (win_maindc && win_mainwindow) ReleaseDC (win_mainwindow, win_maindc); Sys_Error ("Could not initialize GL (wglCreateContext failed).\n\n" "Make sure you are in 65535 color mode, and try running " "with -window.\n" "Error code: (%lx)", lasterror); } if (!qfwglMakeCurrent (win_maindc, baseRC)) { lasterror = GetLastError (); if (baseRC) qfwglDeleteContext (baseRC); if (win_maindc && win_mainwindow) ReleaseDC (win_mainwindow, win_maindc); Sys_Error ("wglMakeCurrent failed (%lx)", lasterror); } ctx->init_gl (); } static void wgl_end_rendering (void) { if (!scr_skipupdate) { qfglFinish (); SwapBuffers (win_maindc); } // handle the mouse state when windowed if that's changed if (!vid_fullscreen) { //FIXME if (!in_grab) { //FIXME if (windowed_mouse) { //FIXME IN_DeactivateMouse (); //FIXME IN_ShowMouse (); //FIXME windowed_mouse = false; //FIXME } //FIXME } else { //FIXME windowed_mouse = true; //FIXME } } } static void wgl_load_gl (gl_ctx_t *ctx) { libgl_handle = LoadLibrary (gl_driver); if (!libgl_handle) { Sys_Error ("Couldn't load OpenGL library %s!", gl_driver); } glGetProcAddress = (void *) GetProcAddress (libgl_handle, "wglGetProcAddress"); qfwglCreateContext = QFGL_ProcAddress ("wglCreateContext", true); qfwglDeleteContext = QFGL_ProcAddress ("wglDeleteContext", true); qfwglGetCurrentContext = QFGL_ProcAddress ("wglGetCurrentContext", true); qfwglGetCurrentDC = QFGL_ProcAddress ("wglGetCurrentDC", true); qfwglMakeCurrent = QFGL_ProcAddress ("wglMakeCurrent", true); use_gl_proceaddress = 1; qfglFinish = QFGL_ProcAddress ("glFinish", true); } gl_ctx_t * Win_GL_Context (vid_internal_t *vi) { gl_ctx_t *ctx = calloc (1, sizeof (gl_ctx_t)); ctx->load_gl = wgl_load_gl; ctx->choose_visual = wgl_choose_visual; ctx->create_context = wgl_create_context; ctx->get_proc_address = QFGL_ProcAddress; ctx->end_rendering = wgl_end_rendering; vi->ctx = ctx; return ctx; } void Win_GL_Init_Cvars (void) { Cvar_Register (&gl_driver_cvar, 0, 0); }