Files
Vivid2DRenderer/Vivid2DRenderer/systems/buffer/BufferBuilder.cpp
tzdwindows 7 ab8c621a00 refactor(buffer): rename namespace from Buffer to Vivid2D::Render::Buffer
- Updated namespace in BufferBuilder.cpp
- Updated namespace in BufferBuilder.h
- Updated namespace in BufferUploader.cpp
- Updated namespace in BufferUploader.h
- Updated namespace in Tesselator.cpp
- Updated namespace in Tesselator.h

chore(project): add new source files and update preprocessor definitions

- Added GLM_ENABLE_EXPERIMENTAL and _CRT_SECURE_NO_WARNINGS to preprocessor definitions
- Included new header files: AnimationParameter.h, Mesh2D.h, ModelPart.h, BoundingBox.h, VertexList.h
- Included new source files: AnimationParameter.cpp, Mesh2D.cpp, ModelPart.cpp, BoundingBox.cpp, VertexList.cpp
- Added MultiSelectionBoxRenderer.h and MultiSelectionBoxRenderer.cpp
- Added Texture.h and Texture.cpp
- Added Vertex.h and Vertex.cpp
- Updated project filters for new files
2025-11-15 10:21:03 +08:00

182 lines
5.5 KiB
C++

#include "pch.h"
#include "BufferUploader.h"
#include "BufferBuilder.h"
#include <glad/glad.h>
#include <spdlog/spdlog.h>
#include <glm/gtc/type_ptr.hpp>
namespace Vivid2D::Render::Buffer {
// ==========================================================
// RenderState 实现
// ==========================================================
void RenderState::saveCurrentState() {
GLint currentProgram = 0;
glGetIntegerv(GL_CURRENT_PROGRAM, &currentProgram);
this->shaderProgram = static_cast<unsigned int>(currentProgram);
GLint boundTexture = 0;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTexture);
this->textureId = static_cast<unsigned int>(boundTexture);
GLint activeTextureUnit = 0;
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTextureUnit);
this->textureUnit = activeTextureUnit - GL_TEXTURE0;
this->depthTest = glIsEnabled(GL_DEPTH_TEST);
this->blending = glIsEnabled(GL_BLEND);
while (glGetError() != GL_NO_ERROR) {}
}
void RenderState::applyState() const {
// 恢复 Program
if (shaderProgram != 0) {
glUseProgram(shaderProgram);
}
// 恢复 Texture
if (textureId != 0) {
glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture(GL_TEXTURE_2D, textureId);
}
// 恢复 Blending/Depth
if (this->blending) {
glEnable(GL_BLEND);
}
else {
glDisable(GL_BLEND);
}
if (this->depthTest) {
glEnable(GL_DEPTH_TEST);
}
else {
glDisable(GL_DEPTH_TEST);
}
}
// ==========================================================
// BufferBuilder 实现
// ==========================================================
// 默认构造函数 (256 floats -> 64 顶点)
BufferBuilder::BufferBuilder() : BufferBuilder(256) {}
// 带容量构造函数
BufferBuilder::BufferBuilder(int initialFloatCapacity)
: array(std::max(16, initialFloatCapacity)), size(0), vertexCount(0)
{
// 默认绘制模式
this->mode = GL_TRIANGLES;
// 确保 array 初始是空的
this->array.clear();
}
void BufferBuilder::begin(int glMode, int estimatedVertexCount) {
this->mode = glMode;
this->size = 0;
this->vertexCount = 0;
this->array.clear();
// 保存当前渲染状态
if (!stateSaved) {
renderState.saveCurrentState();
stateSaved = true;
}
if (estimatedVertexCount > 0) {
this->array.reserve(estimatedVertexCount * COMPONENTS_PER_VERTEX);
}
}
void BufferBuilder::setTexture(unsigned int textureId, int textureUnit) {
this->renderState.textureId = textureId;
this->renderState.textureUnit = textureUnit;
}
void BufferBuilder::setShader(unsigned int programId) {
this->renderState.shaderProgram = programId;
}
void BufferBuilder::setColor(const glm::vec4& color) {
this->renderState.color = color;
}
void BufferBuilder::setOpacity(float opacity) {
this->renderState.opacity = opacity;
}
void BufferBuilder::vertex(float x, float y, float u, float v) {
this->array.push_back(x);
this->array.push_back(y);
this->array.push_back(u);
this->array.push_back(v);
this->size = this->array.size();
this->vertexCount++;
}
std::unique_ptr<BuiltBuffer> BufferBuilder::end() {
if (vertexCount == 0) return nullptr;
RenderSystem::assertOnRenderThread();
// 1. 创建和绑定 GPU 资源
unsigned int vao = RenderSystem::GenVertexArrays();
unsigned int vbo = RenderSystem::GenBuffers();
RenderSystem::BindVertexArray(vao);
RenderSystem::BindBuffer(GL_ARRAY_BUFFER, vbo);
// 2. 上传数据
// 假设 RenderSystem 已经定义了 GL_ARRAY_BUFFER 和 GL_DYNAMIC_DRAW
RenderSystem::BufferData(GL_ARRAY_BUFFER, this->array.size() * sizeof(float),
this->array.data(), GL_DYNAMIC_DRAW);
// 3. 设置顶点属性 (Location 0: Position, Location 1: TexCoord)
// Position (location 0): 2 floats, offset 0
RenderSystem::enableVertexAttribArray(0);
RenderSystem::vertexAttribPointer(0, 2, GL_FLOAT, false,
COMPONENTS_PER_VERTEX * sizeof(float), 0);
// Texture Coords (location 1): 2 floats, offset 2 * sizeof(float)
RenderSystem::enableVertexAttribArray(1);
RenderSystem::vertexAttribPointer(1, 2, GL_FLOAT, false,
COMPONENTS_PER_VERTEX * sizeof(float),
reinterpret_cast<const void*>(2 * sizeof(float)));
// 4. 解绑
RenderSystem::BindBuffer(GL_ARRAY_BUFFER, 0);
RenderSystem::BindVertexArray(0);
// 5. 返回 BuiltBuffer
RenderState stateCopy = renderState.copy();
stateSaved = false;
return std::make_unique<BuiltBuffer>(vao, vbo, vertexCount, mode, stateCopy);
}
void BufferBuilder::endImmediate() {
std::unique_ptr<BuiltBuffer> buffer = end();
if (buffer != nullptr) {
BufferUploader::drawWithShader(std::move(buffer));
}
}
void BufferBuilder::dispose(const BuiltBuffer* buffer) {
if (buffer != nullptr) {
RenderSystem::DeleteVertexArrays(buffer->vao);
RenderSystem::DeleteBuffers(buffer->vbo);
}
}
void BufferBuilder::clear() {
this->array.clear();
this->size = 0;
this->vertexCount = 0;
}
} // namespace Buffer