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

116 lines
2.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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