Extra2D/include/renderer/rhi/opengl/gl_command_list.h

177 lines
5.5 KiB
C++

#pragma once
#include <glad/glad.h>
#include <renderer/rhi/rhi.h>
namespace extra2d {
// 前向声明
class GLPipeline;
class GLBuffer;
class GLTexture;
class GLFramebuffer;
/**
* @brief OpenGL 命令列表实现
*/
class GLCommandList : public RHICommandList {
public:
GLCommandList();
~GLCommandList() override;
//===========================================================================
// 命令列表生命周期
//===========================================================================
void begin() override;
void end() override;
void submit() override;
//===========================================================================
// 渲染通道
//===========================================================================
void beginRenderPass(RHIFramebuffer *framebuffer,
ClearFlags clearFlags = ClearFlags::Color,
const Color &clearColor = Color::Black,
float clearDepth = 1.0f,
uint8_t clearStencil = 0) override;
void endRenderPass() override;
//===========================================================================
// 状态设置
//===========================================================================
void setViewport(const Viewport &viewport) override;
void setScissor(const ScissorRect &scissor) override;
void setPipeline(RHIPipeline *pipeline) override;
//===========================================================================
// 资源绑定
//===========================================================================
void setVertexBuffer(uint32_t slot, RHIBuffer *buffer,
uint32_t offset = 0, uint32_t stride = 0) override;
void setIndexBuffer(RHIBuffer *buffer, IndexType type,
uint32_t offset = 0) override;
void setUniformBuffer(uint32_t slot, RHIBuffer *buffer) override;
void setUniformBuffer(uint32_t slot, RHIBuffer *buffer, uint32_t offset, uint32_t size = 0) override;
void setTexture(uint32_t slot, RHITexture *texture) override;
void setSampler(uint32_t slot, TextureFilter minFilter,
TextureFilter magFilter, TextureWrap wrapS,
TextureWrap wrapT) override;
//===========================================================================
// 绘制命令
//===========================================================================
void draw(uint32_t vertexCount, uint32_t firstVertex = 0,
uint32_t instanceCount = 1, uint32_t firstInstance = 0) override;
void drawIndexed(uint32_t indexCount, uint32_t firstIndex = 0,
int32_t vertexOffset = 0, uint32_t instanceCount = 1,
uint32_t firstInstance = 0) override;
//===========================================================================
// 工具方法
//===========================================================================
void clear(ClearFlags flags, const Color &color = Color::Black,
float depth = 1.0f, uint8_t stencil = 0) override;
bool isRecording() const override;
// 设置 uniform 变量
void setUniform(const char* name, float value) override;
void setUniform(const char* name, const Vec2& value) override;
void setUniform(const char* name, const Vec3& value) override;
void setUniform(const char* name, const Color& value) override;
void setUniform(const char* name, const Mat4& value) override;
private:
// 状态缓存机制 - 避免冗余的 OpenGL 状态切换
struct StateCache {
// 管线状态
GLPipeline* pipeline = nullptr;
GLuint shaderProgram = 0;
// 视口状态
Viewport viewport;
bool viewportValid = false;
// 裁剪状态
ScissorRect scissor{0, 0, 0, 0};
bool scissorValid = false;
bool scissorEnabled = false;
// 缓冲区状态
GLBuffer* vertexBuffers[4] = {nullptr, nullptr, nullptr, nullptr}; // 支持最多4个顶点缓冲区槽
uint32_t vertexBufferOffsets[4] = {0, 0, 0, 0};
GLBuffer* indexBuffer = nullptr;
// Uniform 缓冲区状态
struct UBOBinding {
GLBuffer* buffer = nullptr;
uint32_t offset = 0;
uint32_t size = 0;
bool valid = false;
};
UBOBinding uniformBuffers[4]; // 支持最多4个 UBO 槽
// 纹理状态
struct TextureBinding {
GLTexture* texture = nullptr;
bool valid = false;
};
TextureBinding textures[8]; // 支持最多8个纹理槽
// 帧缓冲状态
GLFramebuffer* framebuffer = nullptr;
// 重置所有状态缓存
void reset() {
pipeline = nullptr;
shaderProgram = 0;
viewportValid = false;
scissorValid = false;
scissorEnabled = false;
for (int i = 0; i < 4; ++i) {
vertexBuffers[i] = nullptr;
vertexBufferOffsets[i] = 0;
uniformBuffers[i] = {};
}
indexBuffer = nullptr;
for (int i = 0; i < 8; ++i) {
textures[i] = {};
}
framebuffer = nullptr;
}
};
bool recording_ = false;
StateCache stateCache_;
// 统计信息(调试用)
struct Stats {
uint32_t pipelineChanges = 0;
uint32_t textureChanges = 0;
uint32_t bufferChanges = 0;
uint32_t viewportChanges = 0;
uint32_t redundantPipelineChanges = 0;
uint32_t redundantTextureChanges = 0;
uint32_t redundantBufferChanges = 0;
void reset() {
pipelineChanges = 0;
textureChanges = 0;
bufferChanges = 0;
viewportChanges = 0;
redundantPipelineChanges = 0;
redundantTextureChanges = 0;
redundantBufferChanges = 0;
}
} stats_;
};
} // namespace extra2d