quakeforge/libs/video/targets/vid_win_gl.c
Bill Currie f12b3ea134 [vid] Allow render systems to unload late
This cleans up the tangled mess of attempting to unload the gl driver in
X11: for whatever reason, the display gets tied in to the library.
2023-03-06 21:15:15 +09:00

218 lines
5.5 KiB
C

/*
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 <ddraw.h>
#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);
}