- 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
182 lines
5.5 KiB
C++
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, ¤tProgram);
|
|
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
|