refactor(RHI): 将窗口职责从RHI移到Platform层

- RHIDeviceDesc 删除 windowHandle/width/height/appName
- SwapChainDesc 添加 windowHandle 字段
- RHISwapChain 删除 PollEvents/ShouldClose/SetFullscreen 等窗口相关接口
- OpenGLDevice 删除 CreateRenderWindow,改用 InitializeWithExistingWindow
- 更新所有集成测试使用新API
- 273个单元测试 + 8个集成测试全部通过
This commit is contained in:
2026-03-24 23:00:49 +08:00
parent 9fae910854
commit 7a66913f2b
22 changed files with 66 additions and 379 deletions

View File

@@ -20,9 +20,6 @@
#include "XCEngine/RHI/OpenGL/OpenGLResourceView.h"
#include "XCEngine/Debug/Logger.h"
static bool s_windowClassRegistered = false;
static const wchar_t kWindowClassName[] = L"XCEngine_OpenGL_WindowClass";
typedef const char* (WINAPI* PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC hdc);
typedef BOOL (WINAPI* PFNWGLCHOOSEPIXELFORMATARBPROC)(HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats);
typedef HGLRC (WINAPI* PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC hdc, HGLRC hShareContext, const int* attribList);
@@ -45,9 +42,7 @@ OpenGLDevice::OpenGLDevice()
: m_hwnd(nullptr)
, m_hdc(nullptr)
, m_hglrc(nullptr)
, m_initialized(false)
, m_ownsWindow(false)
, m_shouldClose(false) {
, m_initialized(false) {
m_textureUnitAllocator = std::make_unique<OpenGLTextureUnitAllocator>();
m_uniformBufferManager = std::make_unique<OpenGLUniformBufferManager>();
}
@@ -61,16 +56,7 @@ bool OpenGLDevice::Initialize(const RHIDeviceDesc& desc) {
return true;
}
if (desc.windowHandle) {
return InitializeWithExistingWindow(static_cast<HWND>(desc.windowHandle));
}
std::string titleStr = "XCEngine";
if (!desc.appName.empty()) {
titleStr = std::string(desc.appName.begin(), desc.appName.end());
}
return CreateRenderWindow(desc.width, desc.height, titleStr.c_str(), desc.enableDebugLayer);
return false;
}
bool OpenGLDevice::InitializeWithExistingWindow(HWND hwnd) {
@@ -248,52 +234,6 @@ 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);
@@ -304,10 +244,6 @@ void OpenGLDevice::Shutdown() {
if (m_hdc && m_hwnd) {
ReleaseDC(m_hwnd, m_hdc);
m_hdc = nullptr;
}
if (m_ownsWindow && m_hwnd) {
DestroyWindow(m_hwnd);
m_hwnd = nullptr;
}
@@ -319,8 +255,6 @@ void OpenGLDevice::Shutdown() {
}
m_initialized = false;
m_ownsWindow = false;
m_shouldClose = false;
}
void OpenGLDevice::SwapBuffers() {
@@ -329,30 +263,6 @@ void OpenGLDevice::SwapBuffers() {
}
}
bool OpenGLDevice::PollEvents() {
MSG msg;
while (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) {
m_shouldClose = true;
return false;
}
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return !m_shouldClose;
}
void OpenGLDevice::SetShouldClose(bool shouldClose) {
m_shouldClose = shouldClose;
if (m_hwnd && shouldClose) {
PostMessageW(m_hwnd, WM_CLOSE, 0, 0);
}
}
bool OpenGLDevice::ShouldClose() const {
return m_shouldClose;
}
RHIBuffer* OpenGLDevice::CreateBuffer(const BufferDesc& desc) {
auto* buffer = new OpenGLBuffer();
OpenGLBufferType bufferType = OpenGLBufferType::Vertex;
@@ -416,8 +326,9 @@ RHITexture* OpenGLDevice::CreateTexture(const TextureDesc& desc) {
RHISwapChain* OpenGLDevice::CreateSwapChain(const SwapChainDesc& desc) {
auto* swapChain = new OpenGLSwapChain();
if (m_hwnd) {
swapChain->Initialize(this, m_hwnd, desc.width, desc.height);
HWND hwnd = static_cast<HWND>(desc.windowHandle);
if (hwnd) {
swapChain->Initialize(this, hwnd, desc.width, desc.height);
}
return swapChain;
}