#include "XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h" #include namespace XCEngine { namespace RHI { 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, const OpenGLDepthStencilViewDesc& desc) { m_texture = texture; m_mipLevel = desc.mipLevel; m_type = desc.type; glGenFramebuffers(1, &m_framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 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) { OpenGLDepthStencilViewDesc 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; } void OpenGLDepthStencilView::Shutdown() { if (m_framebuffer) { glDeleteFramebuffers(1, &m_framebuffer); m_framebuffer = 0; } } void OpenGLDepthStencilView::Bind() { glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); } 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