Files
2026-05-12 15:26:02 +10:00

135 lines
2.8 KiB
C++

#include "HiddenGlWindow.h"
namespace
{
constexpr const char* kWindowClassName = "RenderCadenceCompositorHiddenGlWindow";
}
HiddenGlWindow::~HiddenGlWindow()
{
Destroy();
}
bool HiddenGlWindow::Create(unsigned width, unsigned height, std::string& error)
{
return CreateShared(width, height, nullptr, nullptr, error);
}
bool HiddenGlWindow::CreateShared(unsigned width, unsigned height, HDC sharedDeviceContext, HGLRC sharedContext, std::string& error)
{
Destroy();
mInstance = GetModuleHandle(nullptr);
WNDCLASSA wc = {};
wc.style = CS_OWNDC;
wc.lpfnWndProc = HiddenGlWindow::WindowProc;
wc.hInstance = mInstance;
wc.lpszClassName = kWindowClassName;
mClassAtom = RegisterClassA(&wc);
if (mClassAtom == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
{
error = "RegisterClassA failed for hidden OpenGL window.";
return false;
}
mWindow = CreateWindowA(
kWindowClassName,
"Render Cadence Compositor Hidden GL",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
static_cast<int>(width),
static_cast<int>(height),
nullptr,
nullptr,
mInstance,
nullptr);
if (!mWindow)
{
error = "CreateWindowA failed for hidden OpenGL window.";
return false;
}
mDc = GetDC(mWindow);
if (!mDc)
{
error = "GetDC failed for hidden OpenGL window.";
return false;
}
PIXELFORMATDESCRIPTOR pfd = {};
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 0;
pfd.iLayerType = PFD_MAIN_PLANE;
int pixelFormat = 0;
if (sharedDeviceContext != nullptr)
pixelFormat = GetPixelFormat(sharedDeviceContext);
if (pixelFormat == 0)
pixelFormat = ChoosePixelFormat(mDc, &pfd);
if (pixelFormat == 0 || !SetPixelFormat(mDc, pixelFormat, &pfd))
{
error = "Could not choose/set pixel format for hidden OpenGL window.";
return false;
}
mGlrc = wglCreateContext(mDc);
if (!mGlrc)
{
error = "wglCreateContext failed for hidden OpenGL window.";
return false;
}
if (sharedContext != nullptr && wglShareLists(sharedContext, mGlrc) != TRUE)
{
error = "wglShareLists failed for hidden OpenGL shared context.";
return false;
}
return true;
}
bool HiddenGlWindow::MakeCurrent() const
{
return mDc != nullptr && mGlrc != nullptr && wglMakeCurrent(mDc, mGlrc) == TRUE;
}
void HiddenGlWindow::ClearCurrent() const
{
wglMakeCurrent(nullptr, nullptr);
}
void HiddenGlWindow::Destroy()
{
ClearCurrent();
if (mGlrc)
{
wglDeleteContext(mGlrc);
mGlrc = nullptr;
}
if (mWindow && mDc)
{
ReleaseDC(mWindow, mDc);
mDc = nullptr;
}
if (mWindow)
{
DestroyWindow(mWindow);
mWindow = nullptr;
}
mInstance = nullptr;
mClassAtom = 0;
}
LRESULT CALLBACK HiddenGlWindow::WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hwnd, message, wParam, lParam);
}