- 删除多余的注释并简化applyRenderState逻辑 - 增强了丢失着色器制服和程序的错误记录 改进了绘制调用中的VAO/VBO绑定和属性管理 在渲染系统中增加了高兴功能的加载支持 - 调整线程断言逻辑以更好地处理初始化 - 在缓冲区绑定期间启用顶点属性数组 - 禁用深度测试并启用2D渲染的混合 - 更新了着色器源代码定义和正确的行结束符 - 导出ShaderProgram类以实现DLL可见性 - 通过删除不必要的注释简化纯色着色器 - 集成GLFW窗口管理和OpenGL上下文设置 - 实现了framebuffer resize回调来调整视口 - 添加了基本的渲染循环矩形镶嵌示例 - 确保在退出时正确清理着色器和渲染资源
277 lines
11 KiB
C++
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, ¤tProgram);
|
|
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;
|
|
|
|
}; |