Enhance OpenGLSwapChain with presentation control

- Add PresentMode enum (Immediate, VSync, Mailbox, Fifo)
- Add SurfaceFormat enum for color formats
- Add Initialize() overloads with vsync, width/height, PresentMode
- Add Resize(), SetVSync() for runtime control
- Add GetWidth/Height/FramebufferWidth/FramebufferHeight
- Add ShouldClose, SetShouldClose, PollEvents for window management
- Implement using GLFW for window/swap control
This commit is contained in:
2026-03-17 02:25:18 +08:00
parent be72e2f4a7
commit d75780f8c4
2 changed files with 128 additions and 5 deletions

View File

@@ -1,18 +1,70 @@
#define GLFW_INCLUDE_NONE
#include "XCEngine/RHI/OpenGL/OpenGLSwapChain.h"
#include <GLFW/glfw3.h>
#include <glad/glad.h>
namespace XCEngine {
namespace RHI {
OpenGLSwapChain::OpenGLSwapChain() : m_window(nullptr) {
static int ToGLFWPresentMode(PresentMode mode) {
switch (mode) {
case PresentMode::Immediate: return 0;
case PresentMode::VSync: return 1;
case PresentMode::Mailbox: return -1;
case PresentMode::Fifo: return 1;
default: return 1;
}
}
OpenGLSwapChain::OpenGLSwapChain()
: m_window(nullptr)
, m_width(0)
, m_height(0)
, m_framebufferWidth(0)
, m_framebufferHeight(0)
, m_vsync(true)
, m_presentMode(PresentMode::VSync) {
}
OpenGLSwapChain::~OpenGLSwapChain() {
Shutdown();
}
bool OpenGLSwapChain::Initialize(GLFWwindow* window) {
bool OpenGLSwapChain::Initialize(GLFWwindow* window, bool vsync) {
m_window = window;
m_vsync = vsync;
m_presentMode = vsync ? PresentMode::VSync : PresentMode::Immediate;
int w, h;
glfwGetFramebufferSize(window, &w, &h);
m_framebufferWidth = w;
m_framebufferHeight = h;
glfwGetWindowSize(window, &w, &h);
m_width = w;
m_height = h;
glfwSwapInterval(m_vsync ? 1 : 0);
return true;
}
bool OpenGLSwapChain::Initialize(GLFWwindow* window, int width, int height, PresentMode mode) {
m_window = window;
m_width = width;
m_height = height;
m_presentMode = mode;
m_vsync = (mode == PresentMode::VSync || mode == PresentMode::Fifo);
glfwSetWindowSize(window, width, height);
int w, h;
glfwGetFramebufferSize(window, &w, &h);
m_framebufferWidth = w;
m_framebufferHeight = h;
glfwSwapInterval(m_vsync ? 1 : 0);
return true;
}
@@ -21,11 +73,47 @@ void OpenGLSwapChain::Shutdown() {
}
void OpenGLSwapChain::Present() {
glfwSwapBuffers(m_window);
if (m_window) {
glfwSwapBuffers(m_window);
}
}
void OpenGLSwapChain::SwapBuffers() {
glfwSwapBuffers(m_window);
if (m_window) {
glfwSwapBuffers(m_window);
}
}
void OpenGLSwapChain::Resize(int width, int height) {
m_width = width;
m_height = height;
if (m_window) {
glfwSetWindowSize(m_window, width, height);
}
}
void OpenGLSwapChain::SetVSync(bool enabled) {
m_vsync = enabled;
glfwSwapInterval(enabled ? 1 : 0);
}
void OpenGLSwapChain::SetFramebufferSize(int width, int height) {
m_framebufferWidth = width;
m_framebufferHeight = height;
}
bool OpenGLSwapChain::ShouldClose() const {
return m_window && glfwWindowShouldClose(m_window);
}
void OpenGLSwapChain::SetShouldClose(bool shouldClose) {
if (m_window) {
glfwSetWindowShouldClose(m_window, shouldClose ? GLFW_TRUE : GLFW_FALSE);
}
}
void OpenGLSwapChain::PollEvents() {
glfwPollEvents();
}
} // namespace RHI