Enhance OpenGL RTV and DSV with comprehensive framebuffer support

OpenGLRenderTargetView:
- Add RenderTargetType enum for different texture types
- Add RenderTargetViewDesc struct with mip level, array slice, layer info
- Add Initialize() with desc parameter for 2D/2DArray/3D/Cube
- Add InitializeCubemap() for cubemap faces
- Add Bind(count) overload for multiple framebuffers
- Add Clear() methods for color and depth-stencil
- Add static BindFramebuffer/UnbindFramebuffer methods

OpenGLDepthStencilView:
- Add DepthStencilType enum for different texture types
- Add DepthStencilViewDesc struct with mip level, array slice, layer info
- Add Initialize() with desc parameter for 2D/2DArray/Cube
- Add InitializeCubemap() for cubemap faces
- Add ClearDepth, ClearStencil, ClearDepthStencil methods
- Add static BindFramebuffer/UnbindFramebuffer methods
This commit is contained in:
2026-03-17 02:20:56 +08:00
parent 6126404e3f
commit be72e2f4a7
5 changed files with 265 additions and 17 deletions

View File

@@ -6,24 +6,72 @@
namespace XCEngine {
namespace RHI {
OpenGLDepthStencilView::OpenGLDepthStencilView() : m_texture(0), m_framebuffer(0), m_mipLevel(0) {
OpenGLDepthStencilView::OpenGLDepthStencilView()
: m_texture(0)
, m_framebuffer(0)
, m_mipLevel(0)
, m_width(0)
, m_height(0)
, m_type(DepthStencilType::Texture2D)
, m_format(DepthStencilFormat::D24_UNORM_S8_UINT) {
}
OpenGLDepthStencilView::~OpenGLDepthStencilView() {
Shutdown();
}
bool OpenGLDepthStencilView::Initialize(unsigned int texture, int mipLevel) {
bool OpenGLDepthStencilView::Initialize(unsigned int texture, const DepthStencilViewDesc& desc) {
m_texture = texture;
m_mipLevel = mipLevel;
m_mipLevel = desc.mipLevel;
m_type = desc.type;
glGenFramebuffers(1, &m_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture, mipLevel);
GLenum depthAttachment = GL_DEPTH_ATTACHMENT;
GLenum stencilAttachment = GL_STENCIL_ATTACHMENT;
switch (desc.type) {
case DepthStencilType::Texture2D:
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture, desc.mipLevel);
break;
case DepthStencilType::Texture2DArray:
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, texture, desc.mipLevel, desc.baseArraySlice);
break;
case DepthStencilType::TextureCube:
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + desc.baseArraySlice, texture, desc.mipLevel);
break;
}
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return false;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return true;
}
bool OpenGLDepthStencilView::Initialize(unsigned int texture, int mipLevel) {
DepthStencilViewDesc desc;
desc.mipLevel = mipLevel;
return Initialize(texture, desc);
}
bool OpenGLDepthStencilView::InitializeCubemap(unsigned int cubemap, int face, int mipLevel) {
m_texture = cubemap;
m_mipLevel = mipLevel;
m_type = DepthStencilType::TextureCube;
glGenFramebuffers(1, &m_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubemap, mipLevel);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return false;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return true;
}
@@ -43,5 +91,32 @@ void OpenGLDepthStencilView::Unbind() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void OpenGLDepthStencilView::ClearDepth(float depth) {
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glClearDepth(depth);
glClear(GL_DEPTH_BUFFER_BIT);
}
void OpenGLDepthStencilView::ClearStencil(uint8_t stencil) {
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glClearStencil(stencil);
glClear(GL_STENCIL_BUFFER_BIT);
}
void OpenGLDepthStencilView::ClearDepthStencil(float depth, uint8_t stencil) {
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glClearDepth(depth);
glClearStencil(stencil);
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
void OpenGLDepthStencilView::BindFramebuffer(unsigned int framebuffer) {
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
}
void OpenGLDepthStencilView::UnbindFramebuffer() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
} // namespace RHI
} // namespace XCEngine