Refactor OpenGL SwapChain HDC management

- OpenGLSwapChain now gets HDC from OpenGLDevice instead of creating its own
- Renamed OpenGLDevice::GetContext() to GetGLContext() for clarity
- Renamed OpenGLDevice::GetDC() to GetPresentationDC() for clarity
- OpenGLDevice now owns the HDC/HGLRC lifecycle
- OpenGLSwapChain::Initialize() now takes OpenGLDevice* parameter
- OpenGLSwapChain::Present() uses device's HDC for SwapBuffers
- Updated minimal test to use new API and capture from frame 25-35
- RenderDoc SetDevice now uses GetGLContext() for proper OpenGL hook
This commit is contained in:
2026-03-23 21:43:32 +08:00
parent 0fa4f2e3a8
commit 003d6ed630
5 changed files with 108 additions and 147 deletions

View File

@@ -67,52 +67,6 @@ bool OpenGLDevice::Initialize(const RHIDeviceDesc& desc) {
return CreateRenderWindow(desc.width, desc.height, titleStr.c_str(), desc.enableDebugLayer);
}
bool OpenGLDevice::CreateRenderWindow(int width, int height, const char* title, bool enableDebug) {
if (m_initialized) {
return true;
}
if (!s_windowClassRegistered) {
WNDCLASSEXW wc = {};
wc.cbSize = sizeof(WNDCLASSEXW);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = DefWindowProcW;
wc.hInstance = GetModuleHandleW(nullptr);
wc.lpszClassName = kWindowClassName;
if (!RegisterClassExW(&wc)) {
return false;
}
s_windowClassRegistered = true;
}
std::wstring titleW(title ? std::wstring(title, title + strlen(title)) : L"XCEngine");
HWND hwnd = CreateWindowExW(
0,
kWindowClassName,
titleW.c_str(),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
width, height,
nullptr,
nullptr,
GetModuleHandleW(nullptr),
nullptr
);
if (!hwnd) {
return false;
}
m_hwnd = hwnd;
m_ownsWindow = true;
ShowWindow(m_hwnd, SW_SHOWNORMAL);
UpdateWindow(m_hwnd);
return InitializeWithExistingWindow(m_hwnd);
}
bool OpenGLDevice::InitializeWithExistingWindow(HWND hwnd) {
if (m_initialized) {
return true;
@@ -280,6 +234,52 @@ bool OpenGLDevice::InitializeWithExistingWindow(HWND hwnd) {
return true;
}
bool OpenGLDevice::CreateRenderWindow(int width, int height, const char* title, bool enableDebug) {
if (m_initialized) {
return true;
}
if (!s_windowClassRegistered) {
WNDCLASSEXW wc = {};
wc.cbSize = sizeof(WNDCLASSEXW);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = DefWindowProcW;
wc.hInstance = GetModuleHandleW(nullptr);
wc.lpszClassName = kWindowClassName;
if (!RegisterClassExW(&wc)) {
return false;
}
s_windowClassRegistered = true;
}
std::wstring titleW(title ? std::wstring(title, title + strlen(title)) : L"XCEngine");
HWND hwnd = CreateWindowExW(
0,
kWindowClassName,
titleW.c_str(),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
width, height,
nullptr,
nullptr,
GetModuleHandleW(nullptr),
nullptr
);
if (!hwnd) {
return false;
}
m_hwnd = hwnd;
m_ownsWindow = true;
ShowWindow(m_hwnd, SW_SHOWNORMAL);
UpdateWindow(m_hwnd);
return InitializeWithExistingWindow(m_hwnd);
}
void OpenGLDevice::Shutdown() {
if (m_hglrc) {
wglMakeCurrent(nullptr, nullptr);
@@ -396,7 +396,7 @@ RHITexture* OpenGLDevice::CreateTexture(const TextureDesc& desc) {
RHISwapChain* OpenGLDevice::CreateSwapChain(const SwapChainDesc& desc) {
auto* swapChain = new OpenGLSwapChain();
if (m_hwnd) {
swapChain->Initialize(m_hwnd, desc.width, desc.height);
swapChain->Initialize(this, m_hwnd, desc.width, desc.height);
}
return swapChain;
}