Fix OpenGL render target binding composition

This commit is contained in:
2026-03-26 01:56:10 +08:00
parent 4b7d05d22d
commit 2e17c0019c
8 changed files with 361 additions and 54 deletions

View File

@@ -65,7 +65,8 @@ OpenGLCommandList::OpenGLCommandList()
, m_currentProgram(0)
, m_internalVAO(0)
, m_currentPipelineState(nullptr)
, m_currentShader(nullptr) {
, m_currentShader(nullptr)
, m_composedFramebuffer(nullptr) {
}
OpenGLCommandList::~OpenGLCommandList() {
@@ -457,6 +458,7 @@ void OpenGLCommandList::PopDebugGroup() {
}
void OpenGLCommandList::Shutdown() {
ReleaseComposedFramebuffer();
DisableConfiguredVertexAttributes();
if (m_internalVAO != 0) {
glDeleteVertexArrays(1, &m_internalVAO);
@@ -467,12 +469,21 @@ void OpenGLCommandList::Shutdown() {
}
void OpenGLCommandList::Reset() {
ReleaseComposedFramebuffer();
m_currentPipelineState = nullptr;
}
void OpenGLCommandList::Close() {
}
void OpenGLCommandList::ReleaseComposedFramebuffer() {
if (m_composedFramebuffer != nullptr) {
m_composedFramebuffer->Shutdown();
delete m_composedFramebuffer;
m_composedFramebuffer = nullptr;
}
}
void OpenGLCommandList::SetShader(RHIShader* shader) {
m_currentShader = static_cast<OpenGLShader*>(shader);
if (m_currentShader) {
@@ -593,29 +604,63 @@ void OpenGLCommandList::SetScissorRects(uint32_t count, const Rect* rects) {
void OpenGLCommandList::SetRenderTargets(uint32_t count, RHIResourceView** renderTargets, RHIResourceView* depthStencil) {
if (count > 0 && renderTargets != nullptr) {
std::vector<GLuint> fbos(count);
const bool requiresComposedFramebuffer = count > 1 || depthStencil != nullptr;
std::vector<GLenum> drawBuffers(count, GL_NONE);
for (uint32_t i = 0; i < count; ++i) {
if (renderTargets[i]) {
OpenGLResourceView* view = static_cast<OpenGLResourceView*>(renderTargets[i]);
fbos[i] = view->GetFramebuffer();
if (renderTargets[i] != nullptr) {
drawBuffers[i] = ToOpenGLColorAttachment(i);
}
}
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[0]);
if (requiresComposedFramebuffer) {
uint32_t width = 0;
uint32_t height = 0;
std::vector<GLenum> drawBuffers(count);
for (uint32_t i = 0; i < count; ++i) {
drawBuffers[i] = ToOpenGLColorAttachment(i);
for (uint32_t i = 0; i < count; ++i) {
auto* view = static_cast<OpenGLResourceView*>(renderTargets[i]);
const OpenGLTexture* texture = view != nullptr ? view->GetTextureResource() : nullptr;
if (texture != nullptr) {
width = texture->GetWidth();
height = texture->GetHeight();
break;
}
}
if ((width == 0 || height == 0) && depthStencil != nullptr) {
auto* dsv = static_cast<OpenGLResourceView*>(depthStencil);
const OpenGLTexture* depthTexture = dsv != nullptr ? dsv->GetTextureResource() : nullptr;
if (depthTexture != nullptr) {
width = depthTexture->GetWidth();
height = depthTexture->GetHeight();
}
}
ReleaseComposedFramebuffer();
m_composedFramebuffer = new OpenGLFramebuffer();
if (!m_composedFramebuffer->Initialize(nullptr, width, height, count, renderTargets, depthStencil)) {
ReleaseComposedFramebuffer();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDrawBuffers(0, nullptr);
return;
}
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_composedFramebuffer->GetFramebuffer());
} else {
ReleaseComposedFramebuffer();
OpenGLResourceView* view = static_cast<OpenGLResourceView*>(renderTargets[0]);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, view != nullptr ? view->GetFramebuffer() : 0);
}
glDrawBuffers(count, drawBuffers.data());
glDrawBuffers(count, drawBuffers.data());
} else if (depthStencil) {
ReleaseComposedFramebuffer();
OpenGLResourceView* dsv = static_cast<OpenGLResourceView*>(depthStencil);
if (dsv && dsv->IsValid()) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dsv->GetFramebuffer());
}
glDrawBuffers(0, nullptr);
} else {
ReleaseComposedFramebuffer();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}