Files
XCEngine/engine/src/RHI/OpenGL/OpenGLRenderTargetView.cpp
ssdfasd 712e975610 refactor: Refactor OpenGL backend to use OpenGLEnums
Use centralized OpenGLEnums.h for enum conversion:
- Remove local ToGL* functions from OpenGLCommandList
- Replace with ToOpenGL() and ToOpenGLClearBuffer() from OpenGLEnums
- Simplify OpenGLTexture, OpenGLBuffer, OpenGLSampler, etc.
2026-03-25 19:01:36 +08:00

141 lines
4.5 KiB
C++

#include "XCEngine/RHI/OpenGL/OpenGLRenderTargetView.h"
#include "XCEngine/RHI/OpenGL/OpenGLEnums.h"
#include <glad/glad.h>
namespace XCEngine {
namespace RHI {
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, const OpenGLRenderTargetViewDesc& desc) {
m_texture = texture;
m_mipLevel = desc.mipLevel;
m_type = desc.type;
glGenFramebuffers(1, &m_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
unsigned int target = ToOpenGL(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) {
OpenGLRenderTargetViewDesc 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;
}
void OpenGLRenderTargetView::Shutdown() {
if (m_framebuffer) {
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