Files
2026-05-22 18:57:55 -07:00

210 lines
5.3 KiB
C++

/*
===========================================================================
IceTech GPL Source Code
Copyright (C) 2026 Justin Marshall
This file is part of the IceTech GPL Source Code (?IceTech Source Code?).
IceTech Source Code 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 3 of the License, or
(at your option) any later version.
IceTech Source Code 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 IceTech Source Code. If not, see <http://www.gnu.org/licenses/>.
If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com
===========================================================================
*/
#include "opengl.h"
// Your D3D12 wrapper exports
extern bool QD3D12_InitForQuakeWindow(struct QD3D12Window* window, HWND hwnd, int width, int height, bool fastPath);
extern void QD3D12_ShutdownForQuake(void);
extern void QD3D12_BeginFrame();
void APIENTRY glSelectTextureSGIS(GLenum texture);
void APIENTRY glMTexCoord2fSGIS(GLenum texture, GLfloat s, GLfloat t);
void APIENTRY glActiveTextureARB(GLenum texture);
void APIENTRY glMultiTexCoord2fARB(GLenum texture, GLfloat s, GLfloat t);
void QD3D12_Resize();
void QD3D12_Present();
void QD3D12_EndFrame();
void QD3D12_CollectRetiredResources();
// Existing GL wrapper function from your compatibility layer
void APIENTRY glBindTexture(unsigned int target, unsigned int texture);
void QD3D12_SetCurrentWindow(struct QD3D12Window* window);
struct QD3D12FakeContext
{
HDC dc;
HWND hwnd;
bool initialized;
struct QD3D12Window* window;
};
static QD3D12FakeContext* g_currentContext = nullptr;
static HDC g_currentDC = nullptr;
struct QD3D12Window* AllocD3D12Window();
void FreeD3D12Window(struct QD3D12Window* wnd);
static void QD3D12_GetClientSize(HWND hwnd, int& w, int& h)
{
RECT rc = {};
GetClientRect(hwnd, &rc);
w = rc.right - rc.left;
h = rc.bottom - rc.top;
if (w <= 0) w = 640;
if (h <= 0) h = 480;
}
QD3D12_HGLRC WINAPI qd3d12_wglCreateContext(HDC hdc)
{
if (!hdc)
return nullptr;
HWND hwnd = WindowFromDC(hdc);
if (!hwnd)
return nullptr;
QD3D12FakeContext* ctx = new QD3D12FakeContext();
ctx->dc = hdc;
ctx->hwnd = hwnd;
ctx->initialized = false;
ctx->window = AllocD3D12Window();
return (QD3D12_HGLRC)ctx;
}
BOOL WINAPI qd3d12_wglMakeCurrent(HDC hdc, QD3D12_HGLRC hglrc)
{
static bool basicInitDone = false;
if (!hdc || !hglrc)
{
g_currentDC = nullptr;
g_currentContext = nullptr;
QD3D12_SetCurrentWindow(NULL);
return TRUE;
}
QD3D12FakeContext* ctx = (QD3D12FakeContext*)hglrc;
ctx->dc = hdc;
const bool wasInitialized = ctx->initialized;
int w = 640, h = 480;
QD3D12_GetClientSize(ctx->hwnd, w, h);
if (!ctx->initialized)
{
if (!QD3D12_InitForQuakeWindow(ctx->window, ctx->hwnd, w, h, basicInitDone))
return FALSE;
}
if (!basicInitDone)
{
if(!glRaytracingInit())
return FALSE;
if (!glRaytracingLightingInit())
return FALSE;
basicInitDone = true;
QD3D12_BeginFrame();
}
g_currentDC = hdc;
g_currentContext = ctx;
QD3D12_SetCurrentWindow(ctx->window);
if (wasInitialized) {
QD3D12_Resize();
}
if (ctx->initialized) {
QD3D12_BeginFrame();
QD3D12_CollectRetiredResources();
}
ctx->initialized = true;
return TRUE;
}
HDC WINAPI qd3d12_wglGetCurrentDC(void)
{
return g_currentDC;
}
QD3D12_HGLRC WINAPI qd3d12_wglGetCurrentContext(void)
{
return (QD3D12_HGLRC)g_currentContext;
}
BOOL WINAPI qd3d12_wglDeleteContext(QD3D12_HGLRC hglrc)
{
if (!hglrc)
return FALSE;
QD3D12FakeContext* ctx = (QD3D12FakeContext*)hglrc;
const bool embeddedWindow = ctx->hwnd && GetParent(ctx->hwnd) != NULL;
if (ctx == g_currentContext)
{
if (ctx->initialized && !embeddedWindow)
QD3D12_ShutdownForQuake();
else
QD3D12_SetCurrentWindow(NULL);
g_currentContext = nullptr;
g_currentDC = nullptr;
}
FreeD3D12Window(ctx->window);
delete ctx;
return TRUE;
}
void APIENTRY glBindTextureEXT(unsigned int target, unsigned int texture)
{
glBindTexture(target, texture);
}
int WINAPI qd3d12_wglDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd) {
return DescribePixelFormat(hdc, iPixelFormat, nBytes, ppfd);
}
BOOL WINAPI qd3d12_wglSetPixelFormat(HDC hdc, int format, const PIXELFORMATDESCRIPTOR* ppfd) {
return 0;
}
BOOL WINAPI qd3d12_wglSwapIntervalEXT(int interval) {
(void)interval;
return TRUE;
}
BOOL WINAPI qd3d12_wglGetDeviceGammaRamp3DFX(HDC hdc, LPVOID ramp) {
return FALSE;
}
BOOL WINAPI qd3d12_wglSetDeviceGammaRamp3DFX(HDC hdc, LPVOID ramp) {
return FALSE;
}
__declspec(dllexport) BOOL WINAPI wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD) { return FALSE; }
__declspec(dllexport) BOOL WINAPI wglUseFontBitmapsW(HDC, DWORD, DWORD, DWORD) { return FALSE; }