Files
Vivid2DRenderer/Vivid2DRenderer/systems/RenderSystem.h
tzdwindows 7 0707a6d5cd Refactor (renderer):优化缓冲区上传和渲染管道
- 删除多余的注释并简化applyRenderState逻辑
- 增强了丢失着色器制服和程序的错误记录
改进了绘制调用中的VAO/VBO绑定和属性管理
在渲染系统中增加了高兴功能的加载支持
- 调整线程断言逻辑以更好地处理初始化
- 在缓冲区绑定期间启用顶点属性数组
- 禁用深度测试并启用2D渲染的混合
- 更新了着色器源代码定义和正确的行结束符
- 导出ShaderProgram类以实现DLL可见性
- 通过删除不必要的注释简化纯色着色器
- 集成GLFW窗口管理和OpenGL上下文设置
- 实现了framebuffer resize回调来调整视口
- 添加了基本的渲染循环矩形镶嵌示例
- 确保在退出时正确清理着色器和渲染资源
2025-11-14 22:27:38 +08:00

277 lines
11 KiB
C++

#pragma once
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <functional>
#include <queue>
#include <mutex>
#include <thread>
#include <stack>
#include <string>
#include <memory>
#include <atomic>
// 向前声明 spdlog::logger 以避免在头文件中包含其完整定义
namespace spdlog {
class logger;
}
class VIVID_2D_MYDLL_API RenderSystem {
public:
RenderSystem() = delete;
~RenderSystem() = delete;
RenderSystem(const RenderSystem&) = delete;
RenderSystem& operator=(const RenderSystem&) = delete;
using GLADloader = void* (*)(const char* name);
// ================== 日志系统管理 ==================
/**
* @brief 初始化日志系统。必须在任何日志调用之前,在主函数开始时调用。
*/
static void InitializeLogging();
/**
* @brief 关闭日志系统。应在主函数结束时调用以确保所有日志都被刷新。
*/
static void ShutdownLogging();
// ================== 初始化与线程管理 ==================
static void initRenderThread();
static void beginInitialization();
static void finishInitialization();
static bool isOnRenderThread();
static bool isInInitPhase();
static void assertOnRenderThread();
static void assertOnRenderThreadOrInit();
static void loadGLFunctions(GLADloader loader);
// ================== 渲染命令队列 ==================
static void recordRenderCall(std::function<void()>&& renderCall);
static void replayQueue();
// ================== OpenGL 状态管理封装 ==================
static void enable(GLenum capability);
static void disable(GLenum capability);
static void pushState();
static void popState();
static size_t getStateStackSize();
static void clearColor(float r, float g, float b, float a);
static void clear(GLbitfield mask);
static void viewport(int x, int y, int width, int height);
// ================== VAO / VBO / EBO 操作 ==================
static GLuint GenVertexArrays();
static void DeleteVertexArrays(GLuint vao);
static void BindVertexArray(GLuint vao);
static GLuint GenBuffers();
static void DeleteBuffers(GLuint buffer);
static void BindBuffer(GLenum target, GLuint buffer);
static void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
// ================== Uniform 设置 ==================
static void uniform1i(GLint location, int value);
static void uniform1f(GLint location, float value);
static void uniform2f(GLint location, float x, float y);
static void uniform3f(GLint location, float x, float y, float z);
static void uniform4f(GLint location, float x, float y, float z, float w);
static void uniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
static void uniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
static void uniform2f(GLint location, const glm::vec2& vec);
static void uniform3f(GLint location, const glm::vec3& vec);
static void uniform4f(GLint location, const glm::vec4& vec);
static void uniformMatrix3(GLint location, const glm::mat3& matrix, bool transpose = false);
static void uniformMatrix4(GLint location, const glm::mat4& matrix, bool transpose = false);
static GLint getUniformLocation(GLuint program, const std::string& name);
// ================== 绘制命令 ==================
static void lineWidth(float width);
static void drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices);
static void drawArrays(GLenum mode, GLint first, GLsizei count);
// ================== 混合模式 ==================
static void enableBlend();
static void disableBlend();
static void blendFunc(GLenum sfactor, GLenum dfactor);
static void defaultBlendFunc();
// ================== 着色器程序管理 ==================
static GLuint createProgram();
static GLint getCurrentProgram();
static void attachShader(GLuint program, GLuint shader);
static void linkProgram(GLuint program);
static GLint getProgrami(GLuint program, GLenum pname);
static std::string getProgramInfoLog(GLuint program);
static void detachShader(GLuint program, GLuint shader);
static void deleteProgram(GLuint program);
static GLuint linkProgram(GLuint vertexShader, GLuint fragmentShader);
static GLuint linkProgram(GLuint vertexShader, GLuint geometryShader, GLuint fragmentShader);
static void useProgram(GLuint program);
// ================== 着色器管理 ==================
static GLuint createShader(GLenum type);
static void shaderSource(GLuint shader, const std::string& source);
static void compileShader(GLuint shader);
static GLint getShaderi(GLuint shader, GLenum pname);
static std::string getShaderInfoLog(GLuint shader);
static void deleteShader(GLuint shader);
static GLuint compileShader(GLenum type, const std::string& source);
// ================== 深度测试 ==================
static void depthFunc(GLenum func);
static void depthMask(bool flag);
static void clearDepth(double depth);
static void enableDepthTest();
static void disableDepthTest();
// ================== 纹理管理 ==================
static void bindTexture(GLuint texture);
static void getTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels);
static void activeTexture(GLenum texture);
static GLuint genTextures();
static void deleteTextures(GLuint texture);
static void texImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels);
static void texParameteri(GLenum target, GLenum pname, GLint param);
static void setTextureMinFilter(GLenum filter);
static void setTextureMagFilter(GLenum filter);
static void setTextureWrapS(GLenum wrap);
static void setTextureWrapT(GLenum wrap);
static GLuint createDefaultTexture();
// ================== 顶点属性 ==================
static void enableVertexAttribArray(GLuint index);
static void disableVertexAttribArray(GLuint index);
static void vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
// ================== 工具方法 ==================
static void readPixels(int x, int y, int width, int height, GLenum format, GLenum type, void* pixels);
static bool isExtensionSupported(const std::string& extension);
static void pixelStore(GLenum pname, GLint param);
static std::string getVendor();
static std::string getRenderer();
static std::string getOpenGLVersion();
static std::string getGLSLVersion();
static void logDetailedGLInfo();
static void setupDefaultState();
static void checkGLError(const std::string& operation);
// ================== 获取状态 ==================
static int getViewportWidth();
static int getViewportHeight();
static glm::vec4 getClearColor();
static size_t getQueueSize();
private:
struct RenderState;
// 私有的、直接执行GL调用的版本
static void _enable(GLenum capability);
static void _disable(GLenum capability);
static void _pushState();
static void _popState();
static void _clearColor(float r, float g, float b, float a);
static void _clear(GLbitfield mask);
static void _viewport(int x, int y, int width, int height);
static void _glDeleteVertexArrays(GLuint vao);
static void _uniform1i(GLint location, int value);
static void _uniform1f(GLint location, float value);
static void _uniform2f(GLint location, float x, float y);
static void _uniform3f(GLint location, float x, float y, float z);
static void _uniform4f(GLint location, float x, float y, float z, float w);
static void _uniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
static void _uniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
static void _lineWidth(float width);
static void _drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices);
static void _drawArrays(GLenum mode, GLint first, GLsizei count);
static void _glBindVertexArray(GLuint vao);
static void _enableBlend();
static void _disableBlend();
static void _blendFunc(GLenum sfactor, GLenum dfactor);
static void _attachShader(GLuint program, GLuint shader);
static void _linkProgram(GLuint program);
static void _detachShader(GLuint program, GLuint shader);
static void _deleteProgram(GLuint program);
static void _useProgram(GLuint program);
static void _shaderSource(GLuint shader, const std::string& source);
static void _compileShader(GLuint shader);
static void _deleteShader(GLuint shader);
static void _depthFunc(GLenum func);
static void _depthMask(bool flag);
static void _clearDepth(double depth);
static void _enableDepthTest();
static void _disableDepthTest();
static void _bindTexture(GLuint texture);
static void _getTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels);
static void _activeTexture(GLenum texture);
static void _deleteTextures(GLuint texture);
static void _texImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels);
static void _texParameteri(GLenum target, GLenum pname, GLint param);
static void _glBindBuffer(GLenum target, GLuint buffer);
static void _glBufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
static void _glDeleteBuffers(GLuint buffer);
static void _enableVertexAttribArray(GLuint index);
static void _disableVertexAttribArray(GLuint index);
static void _vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
static void _readPixels(int x, int y, int width, int height, GLenum format, GLenum type, void* pixels);
static void _pixelStore(GLenum pname, GLint param);
static void _checkGLError(const std::string& operation);
static std::string getGLErrorString(GLenum error);
// 静态成员变量
static std::thread::id s_RenderThreadId;
static std::atomic<bool> s_IsInInit;
static std::queue<std::function<void()>> s_RenderQueue;
static std::mutex s_RenderQueueMutex;
static std::atomic<bool> s_IsReplayingQueue;
// ================== RenderState 结构体和实现 ==================
struct RenderSystem::RenderState {
GLint currentProgram = 0;
GLboolean blendEnabled = GL_FALSE;
GLboolean depthTestEnabled = GL_FALSE;
GLint blendSrcFactor = GL_SRC_ALPHA;
GLint blendDstFactor = GL_ONE_MINUS_SRC_ALPHA;
GLint activeTexture = GL_TEXTURE0;
GLint boundTexture = 0;
glm::vec4 clearColor{ 0.0f, 0.0f, 0.0f, 1.0f };
glm::ivec4 viewport{ 0, 0, 800, 600 };
RenderState() {
glGetIntegerv(GL_CURRENT_PROGRAM, &currentProgram);
blendEnabled = glIsEnabled(GL_BLEND);
depthTestEnabled = glIsEnabled(GL_DEPTH_TEST);
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcFactor);
glGetIntegerv(GL_BLEND_DST_RGB, &blendDstFactor);
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTexture);
glGetFloatv(GL_COLOR_CLEAR_VALUE, &clearColor[0]);
glGetIntegerv(GL_VIEWPORT, &viewport[0]);
while (glGetError() != GL_NO_ERROR) {}
}
void restore() {
glViewport(viewport.x, viewport.y, viewport.z, viewport.w);
glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
glUseProgram(currentProgram);
glActiveTexture(activeTexture);
glBindTexture(GL_TEXTURE_2D, boundTexture);
if (blendEnabled) glEnable(GL_BLEND); else glDisable(GL_BLEND);
glBlendFunc(blendSrcFactor, blendDstFactor);
if (depthTestEnabled) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
while (glGetError() != GL_NO_ERROR) {}
}
};
static std::stack<RenderState> s_StateStack;
static int s_ViewportWidth;
static int s_ViewportHeight;
static glm::vec4 s_ClearColorValue;
static std::shared_ptr<spdlog::logger> s_Logger;
};