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:
@@ -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
|
||||
|
||||
@@ -6,24 +6,89 @@
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
OpenGLRenderTargetView::OpenGLRenderTargetView() : m_texture(0), m_framebuffer(0), m_mipLevel(0) {
|
||||
static unsigned int ToGLRenderTargetType(RenderTargetType type) {
|
||||
switch (type) {
|
||||
case RenderTargetType::Texture2D: return GL_TEXTURE_2D;
|
||||
case RenderTargetType::Texture2DArray: return GL_TEXTURE_2D_ARRAY;
|
||||
case RenderTargetType::Texture3D: return GL_TEXTURE_3D;
|
||||
case RenderTargetType::TextureCube: return GL_TEXTURE_CUBE_MAP;
|
||||
case RenderTargetType::TextureCubeArray: return GL_TEXTURE_CUBE_MAP_ARRAY;
|
||||
default: return GL_TEXTURE_2D;
|
||||
}
|
||||
}
|
||||
|
||||
OpenGLRenderTargetView::OpenGLRenderTargetView()
|
||||
: m_texture(0)
|
||||
, m_framebuffer(0)
|
||||
, m_mipLevel(0)
|
||||
, m_width(0)
|
||||
, m_height(0)
|
||||
, m_type(RenderTargetType::Texture2D) {
|
||||
}
|
||||
|
||||
OpenGLRenderTargetView::~OpenGLRenderTargetView() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool OpenGLRenderTargetView::Initialize(unsigned int texture, int mipLevel) {
|
||||
bool OpenGLRenderTargetView::Initialize(unsigned int texture, const RenderTargetViewDesc& 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_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, mipLevel);
|
||||
|
||||
|
||||
unsigned int target = ToGLRenderTargetType(desc.type);
|
||||
GLenum attachment = GL_COLOR_ATTACHMENT0;
|
||||
|
||||
switch (desc.type) {
|
||||
case RenderTargetType::Texture2D:
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture, desc.mipLevel);
|
||||
break;
|
||||
case RenderTargetType::Texture2DArray:
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment, texture, desc.mipLevel, desc.baseArraySlice);
|
||||
break;
|
||||
case RenderTargetType::Texture3D:
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment, texture, desc.mipLevel, desc.layer);
|
||||
break;
|
||||
case RenderTargetType::TextureCube:
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_CUBE_MAP_POSITIVE_X + desc.baseArraySlice, texture, desc.mipLevel);
|
||||
break;
|
||||
case RenderTargetType::TextureCubeArray:
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment, texture, desc.mipLevel, desc.baseArraySlice);
|
||||
break;
|
||||
}
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLRenderTargetView::Initialize(unsigned int texture, int mipLevel) {
|
||||
RenderTargetViewDesc desc;
|
||||
desc.type = RenderTargetType::Texture2D;
|
||||
desc.mipLevel = mipLevel;
|
||||
return Initialize(texture, desc);
|
||||
}
|
||||
|
||||
bool OpenGLRenderTargetView::InitializeCubemap(unsigned int cubemap, int face, int mipLevel) {
|
||||
m_texture = cubemap;
|
||||
m_mipLevel = mipLevel;
|
||||
m_type = RenderTargetType::TextureCube;
|
||||
|
||||
glGenFramebuffers(1, &m_framebuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 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;
|
||||
}
|
||||
@@ -33,15 +98,55 @@ void OpenGLRenderTargetView::Shutdown() {
|
||||
glDeleteFramebuffers(1, &m_framebuffer);
|
||||
m_framebuffer = 0;
|
||||
}
|
||||
if (!m_framebuffers.empty()) {
|
||||
glDeleteFramebuffers(static_cast<GLsizei>(m_framebuffers.size()), m_framebuffers.data());
|
||||
m_framebuffers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLRenderTargetView::Bind(unsigned int slot) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
(void)slot;
|
||||
}
|
||||
|
||||
void OpenGLRenderTargetView::Bind(unsigned int count, const unsigned int* framebuffers, const int* drawBuffers) {
|
||||
if (count == 1) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[0]);
|
||||
} else {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[i]);
|
||||
glDrawBuffers(1, (const GLenum*)&drawBuffers[i]);
|
||||
}
|
||||
}
|
||||
(void)count;
|
||||
}
|
||||
|
||||
void OpenGLRenderTargetView::Unbind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void OpenGLRenderTargetView::Clear(float r, float g, float b, float a) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
glClearColor(r, g, b, a);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void OpenGLRenderTargetView::Clear(float r, float g, float b, float a, float depth, uint8_t stencil) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
glClearColor(r, g, b, a);
|
||||
glClearDepth(depth);
|
||||
glClearStencil(stencil);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void OpenGLRenderTargetView::BindFramebuffer(unsigned int framebuffer) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
}
|
||||
|
||||
void OpenGLRenderTargetView::UnbindFramebuffer() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
|
||||
Reference in New Issue
Block a user