Extra2D/src/renderer/rhi/opengl/gl_pipeline.cpp

116 lines
2.6 KiB
C++
Raw Normal View History

#include <renderer/rhi/opengl/gl_pipeline.h>
#include <renderer/rhi/opengl/gl_utils.h>
namespace extra2d {
GLPipeline::GLPipeline(const PipelineDesc &desc) : desc_(desc), vao_(0) {}
GLPipeline::~GLPipeline() { destroy(); }
bool GLPipeline::create() {
// 创建 VAO
glGenVertexArrays(1, &vao_);
if (vao_ == 0) {
return false;
}
glBindVertexArray(vao_);
// 配置顶点属性
const auto &layout = desc_.vertexLayout;
for (const auto &attr : layout.attributes) {
glEnableVertexAttribArray(attr.location);
GLenum type = GL_FLOAT;
GLint size = 1;
GLboolean normalized = GL_FALSE;
switch (attr.format) {
case VertexFormat::Float1:
size = 1;
break;
case VertexFormat::Float2:
size = 2;
break;
case VertexFormat::Float3:
size = 3;
break;
case VertexFormat::Float4:
size = 4;
break;
default:
break;
}
glVertexAttribPointer(attr.location, size, type, normalized, layout.stride,
reinterpret_cast<const void *>(attr.offset));
}
glBindVertexArray(0);
return true;
}
void GLPipeline::destroy() {
if (vao_ != 0) {
glDeleteVertexArrays(1, &vao_);
vao_ = 0;
}
}
void GLPipeline::bind() {
// 绑定着色器程序
if (shaderProgram_ != 0) {
glUseProgram(shaderProgram_);
}
// 注意不再绑定VAO因为我们使用动态顶点属性配置
// 顶点属性在 GLCommandList::setVertexBuffer 中配置
// 应用混合状态
if (desc_.blendState.enabled) {
glEnable(GL_BLEND);
glBlendFunc(blendFactorToGL(desc_.blendState.srcFactor),
blendFactorToGL(desc_.blendState.dstFactor));
} else {
glDisable(GL_BLEND);
}
// 应用深度状态
if (desc_.depthStencilState.depthTestEnabled) {
glEnable(GL_DEPTH_TEST);
glDepthFunc(compareFuncToGL(desc_.depthStencilState.depthCompare));
glDepthMask(desc_.depthStencilState.depthWriteEnabled ? GL_TRUE : GL_FALSE);
} else {
glDisable(GL_DEPTH_TEST);
}
// 应用光栅化状态
if (desc_.rasterizerState.cullEnabled) {
glEnable(GL_CULL_FACE);
glCullFace(desc_.rasterizerState.cullFrontFace ? GL_FRONT : GL_BACK);
glFrontFace(desc_.rasterizerState.frontCCW ? GL_CCW : GL_CW);
} else {
glDisable(GL_CULL_FACE);
}
}
void GLPipeline::unbind() { glBindVertexArray(0); }
ShaderHandle GLPipeline::getVertexShader() const {
return desc_.vertexShader;
}
ShaderHandle GLPipeline::getFragmentShader() const {
return desc_.fragmentShader;
}
const VertexLayout& GLPipeline::getVertexLayout() const {
return desc_.vertexLayout;
}
bool GLPipeline::isValid() const {
return vao_ != 0;
}
} // namespace extra2d