Refactor (renderer):优化缓冲区上传和渲染管道

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

View File

@@ -4,53 +4,202 @@
#ifdef VIVID_2D_MYDLL_API
#undef VIVID_2D_MYDLL_API
#endif
#define VIVID_2D_MYDLL_API __declspec(dllexport)
#define VIVID_2D_MYDLL_API __declspec(dllimport)
#include <glm/glm.hpp>
#include <iostream>
#include <glm/vec2.hpp>
#include <systems/RenderSystem.h>
#include <glad/glad.h>
#include <systems/Buffer/BufferBuilder.h>
#include <systems/Buffer/Tesselator.h>
#include <systems/sources/ShaderManagement.h>
#include <systems/sources/ShaderProgram.h>
#include <GLFW/glfw3.h>
#include <stdexcept>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#ifndef M_PI
#define M_PI 3.14159265358979323846f
#endif
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
RenderSystem::viewport(0, 0, width, height);
}
int main() {
// ----------------------------------------------------
// GLM 向量操作 (与 RenderSystem 无关,保持原样)
// ----------------------------------------------------
glm::vec2 position(100.0f, 200.0f);
glm::vec2 velocity(5.0f, -2.0f);
position += velocity;
std::cout << "New Position: (" << position.x << ", " << position.y << ")" << std::endl;
std::cout << "---------------------------------------" << std::endl;
if (!glfwInit()) {
std::cerr << "Failed to initialize GLFW" << std::endl;
return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// ----------------------------------------------------
// RenderSystem 静态方法调用 (无需实例化)
// ----------------------------------------------------
GLFWwindow* window = glfwCreateWindow(800, 600, "Vivid2D Circle Test", NULL, NULL);
if (window == NULL) {
std::cerr << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// 1. 初始化日志系统 (假设已实现)
std::cout << "Initializing RenderSystem Logging..." << std::endl;
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cerr << "Failed to initialize GLAD" << std::endl;
glfwTerminate();
return -1;
}
RenderSystem::InitializeLogging();
// 2. 开始渲染线程初始化阶段 (假设已实现)
try {
typedef RenderSystem::GLADloader GLADloaderType;
RenderSystem::loadGLFunctions(reinterpret_cast<GLADloaderType>(glfwGetProcAddress));
}
catch (const std::runtime_error& e) {
std::cerr << "FATAL ERROR during GL function loading in DLL: " << e.what() << std::endl;
glfwTerminate();
return -1;
}
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
std::cout << "Initializing RenderSystem Logging..." << std::endl;
RenderSystem::initRenderThread();
RenderSystem::beginInitialization();
// 3. 记录一个渲染指令到队列中
std::cout << "Recording a clear color command..." << std::endl;
// 这是一个 lambda 函数,捕获了要执行的 GL 命令
RenderSystem::recordRenderCall([]() {
// 在实际的 RenderSystem 实现中,这会调用 glClearColor(1.0f, 0.5f, 0.0f, 1.0f);
std::cout << "-> (Render Thread) Executing glClearColor(Orange)" << std::endl;
});
RenderSystem::viewport(0, 0, 800, 600);
// 4. 执行队列中的渲染指令
std::cout << "Replaying render queue (" << RenderSystem::getQueueSize() << " calls)..." << std::endl;
RenderSystem::replayQueue(); // 假设这个调用会执行上面的 lambda
// ----------------------------------------------------------------------
// 步骤 1: 记录编译指令,但不立即执行
// ----------------------------------------------------------------------
std::cout << "Compiling all shaders..." << std::endl;
RenderSystem::recordRenderCall([]() { ShaderManagement::compileAllShaders(); });
// ----------------------------------------------------------------------
// 步骤 2: 立即执行队列,编译着色器
// ----------------------------------------------------------------------
std::cout << "Executing initialization queue (Shader compilation)..." << std::endl;
RenderSystem::replayQueue();
std::cout << "Shader compilation executed. Queue size: " << RenderSystem::getQueueSize() << std::endl;
// ----------------------------------------------------------------------
// 步骤 3: 在主线程上安全地获取已编译的着色器 ID 和设置 Uniforms
// ----------------------------------------------------------------------
glm::mat4 projection = glm::ortho(0.0f, 800.0f, 600.0f, 0.0f, -1.0f, 1.0f);
glm::mat4 viewMatrix = glm::mat4(1.0f);
glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(400.0f, 300.0f, 0.0f));
ShaderProgram* circleProgram = ShaderManagement::getShaderProgram("Solid Color Shader");
if (circleProgram) {
// 记录设置 Uniforms 的指令
RenderSystem::recordRenderCall([=]() {
circleProgram->use();
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// 设置 Projection Matrix (mat3)
GLint projLoc = circleProgram->getUniformLocation("uProjectionMatrix");
if (projLoc != -1) {
RenderSystem::uniformMatrix3(projLoc, projection, false);
}
// 设置 View Matrix (mat3)
GLint viewLoc = circleProgram->getUniformLocation("uViewMatrix");
if (viewLoc != -1) {
RenderSystem::uniformMatrix3(viewLoc, viewMatrix, false);
}
// 设置 Model Matrix (mat3)
GLint modelLoc = circleProgram->getUniformLocation("uModelMatrix");
if (modelLoc != -1) {
RenderSystem::uniformMatrix3(modelLoc, modelMatrix, false);
}
circleProgram->stop();
});
}
else {
std::cerr << "FATAL ERROR: Solid Color Shader not found after compilation. Please check the name or compilation logs." << std::endl;
glfwTerminate();
return -1;
}
// ----------------------------------------------------------------------
// 步骤 4: 记录绘制命令,使用已获取的 ID
// ----------------------------------------------------------------------
std::cout << "Recording Circle drawing command..." << std::endl;
// ----------------------------------------------------------------------
// 步骤 5: 执行队列,设置 Uniforms 并记录几何体到 VBO
// ----------------------------------------------------------------------
std::cout << "Executing final initialization queue (Uniforms and Geometry)..." << std::endl;
RenderSystem::replayQueue(); // 再次执行队列,此时执行 Uniform 设置和绘制命令
std::cout << "Final initialization executed. Queue size: " << RenderSystem::getQueueSize() << std::endl;
// 5. 结束初始化阶段
RenderSystem::finishInitialization();
// 6. 关闭日志系统 (确保日志被刷新)
std::cout << "Shutting down RenderSystem Logging." << std::endl;
RenderSystem::ShutdownLogging();
if (RenderSystem::getQueueSize() > 0) {
throw std::runtime_error("FATAL ERROR: Initialization failed to clear the render queue before main loop.");
}
std::cout << "\nStarting main render loop..." << std::endl;
while (!glfwWindowShouldClose(window)) {
RenderSystem::clearColor(0.2f, 0.3f, 0.3f, 1.0f);
RenderSystem::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Buffer::Tesselator& t = Buffer::Tesselator::getInstance();
Buffer::BufferBuilder& builder = t.getBuilder();
// 矩形的位置和大小
const float rectX = 0; // 矩形左上角的 X 坐标
const float rectY = 0; // 矩形左上角的 Y 坐标
const float rectWidth = 200.0f; // 矩形宽度
const float rectHeight = 150.0f; // 矩形高度
// 确保深度测试被禁用,混合被启用
RenderSystem::disableDepthTest();
RenderSystem::enableBlend();
RenderSystem::defaultBlendFunc();
// 【关键修正】:设置绘制模式为实心填充
// 如果你希望画线框,可以使用 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
RenderSystem::recordRenderCall([]() {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // 实心填充模式
});
// 【关键修正】:开始绘制矩形
// 使用 GL_TRIANGLE_STRIP 绘制一个填充的矩形 (4个顶点)
builder.begin(GL_TRIANGLE_STRIP, 4); // 绘制两个三角形形成一个矩形
builder.setShader(circleProgram->getProgramId());
builder.setColor(glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); // 红色
builder.setTexture(0, 0); // 不需要纹理
// 矩形的四个顶点(顺序很重要,对于 GL_TRIANGLE_STRIP
// 左上角 (X, Y)
builder.vertex(rectX, rectY, 0.0f, 0.0f);
// 右上角 (X + Width, Y)
builder.vertex(rectX + rectWidth, rectY, 1.0f, 0.0f);
// 左下角 (X, Y + Height)
builder.vertex(rectX, rectY + rectHeight, 0.0f, 1.0f);
// 右下角 (X + Width, Y + Height)
builder.vertex(rectX + rectWidth, rectY + rectHeight, 1.0f, 1.0f);
t.end();
// 确保 GL 状态记录被执行
RenderSystem::replayQueue();
glfwSwapBuffers(window);
glfwPollEvents();
}
std::cout << "\nShutting down RenderSystem Logging." << std::endl;
RenderSystem::recordRenderCall([]() { ShaderManagement::cleanup(); });
RenderSystem::replayQueue();
RenderSystem::ShutdownLogging();
return 0;
}