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