Add OpenGL backend: OpenGLDevice class

- Created OpenGLDevice class for window and OpenGL context management
- Added CreateWindow() and InitializeWithExistingWindow() methods
- Integrated with GLFW and GLAD
- Added to tests/OpenGL as test target

This is the first step in building the OpenGL RHI backend parallel to D3D12.
This commit is contained in:
2026-03-16 16:07:12 +08:00
parent 9c29cfa0a6
commit 6aaf89e603
3 changed files with 151 additions and 13 deletions

View File

@@ -21,6 +21,20 @@ file(COPY ${copyResources} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug)
file(GLOB assimpDll "${CMAKE_CURRENT_SOURCE_DIR}/package/dll/assimp-vc143-mt.dll")
file(COPY ${assimpDll} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug)
add_executable(
XCRender
main.cpp
OpenGLDevice.cpp
./package/src/glad.c
)
target_link_libraries(XCRender
PRIVATE
glfw3.lib
assimp-vc143-mt.lib
XCEngine
)
add_custom_command(TARGET XCRender POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/compare_ppm.py
@@ -31,17 +45,4 @@ add_custom_command(TARGET XCRender POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm
$<TARGET_FILE_DIR:XCRender>/GT.ppm
)
add_executable(
XCRender
main.cpp
./package/src/glad.c
)
target_link_libraries(XCRender
PRIVATE
glfw3.lib
assimp-vc143-mt.lib
XCEngine
)

View File

@@ -0,0 +1,95 @@
#define GLFW_INCLUDE_NONE
#include "OpenGLDevice.h"
#include <glad/glad.h>
#include <GLFW/glfw3.h>
namespace XCEngine {
namespace RHI {
OpenGLDevice::OpenGLDevice()
: m_window(nullptr)
, m_initialized(false)
, m_ownsWindow(false) {
}
OpenGLDevice::~OpenGLDevice() {
Shutdown();
}
bool OpenGLDevice::CreateWindow(int width, int height, const char* title, bool enableDebug) {
if (m_initialized) {
return true;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
m_window = glfwCreateWindow(width, height, title, nullptr, nullptr);
if (!m_window) {
return false;
}
m_ownsWindow = true;
return InitializeWithExistingWindow(m_window);
}
bool OpenGLDevice::InitializeWithExistingWindow(GLFWwindow* window) {
if (m_initialized) {
return true;
}
m_window = window;
if (!m_window) {
return false;
}
glfwMakeContextCurrent(m_window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
return false;
}
m_deviceInfo.vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
m_deviceInfo.renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
m_deviceInfo.version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
glGetIntegerv(GL_MAJOR_VERSION, &m_deviceInfo.majorVersion);
glGetIntegerv(GL_MINOR_VERSION, &m_deviceInfo.minorVersion);
m_initialized = true;
return true;
}
void OpenGLDevice::Shutdown() {
if (m_ownsWindow && m_window) {
glfwDestroyWindow(m_window);
}
m_window = nullptr;
m_initialized = false;
m_ownsWindow = false;
}
void OpenGLDevice::SwapBuffers() {
if (m_window) {
glfwSwapBuffers(m_window);
}
}
bool OpenGLDevice::PollEvents() {
glfwPollEvents();
return !glfwWindowShouldClose(m_window);
}
void OpenGLDevice::SetShouldClose(bool shouldClose) {
if (m_window) {
glfwSetWindowShouldClose(m_window, shouldClose ? GLFW_TRUE : GLFW_FALSE);
}
}
bool OpenGLDevice::ShouldClose() const {
return m_window && glfwWindowShouldClose(m_window) == GLFW_TRUE;
}
} // namespace RHI
} // namespace XCEngine

View File

@@ -0,0 +1,42 @@
#pragma once
#include <string>
#include <GLFW/glfw3.h>
namespace XCEngine {
namespace RHI {
struct OpenGLDeviceInfo {
std::string vendor;
std::string renderer;
std::string version;
int majorVersion;
int minorVersion;
};
class OpenGLDevice {
public:
OpenGLDevice();
~OpenGLDevice();
bool CreateWindow(int width, int height, const char* title, bool enableDebug = false);
bool InitializeWithExistingWindow(GLFWwindow* window);
void Shutdown();
GLFWwindow* GetWindow() const { return m_window; }
const OpenGLDeviceInfo& GetDeviceInfo() const { return m_deviceInfo; }
void SwapBuffers();
bool PollEvents();
void SetShouldClose(bool shouldClose);
bool ShouldClose() const;
private:
GLFWwindow* m_window;
OpenGLDeviceInfo m_deviceInfo;
bool m_initialized;
bool m_ownsWindow;
};
} // namespace RHI
} // namespace XCEngine