Update shader
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 3m0s
CI / Windows Release Package (push) Has been skipped

This commit is contained in:
Aiden
2026-05-12 16:52:15 +10:00
parent 02b221f481
commit 1429b2e660
6 changed files with 178 additions and 18 deletions

View File

@@ -6,6 +6,10 @@
#include <functional>
#include <utility>
#ifndef GL_FRAMEBUFFER_BINDING
#define GL_FRAMEBUFFER_BINDING 0x8CA6
#endif
RuntimeRenderScene::~RuntimeRenderScene()
{
ShutdownGl();
@@ -90,12 +94,50 @@ void RuntimeRenderScene::RenderFrame(uint64_t frameIndex, unsigned width, unsign
{
ConsumePreparedPrograms();
std::vector<LayerProgram*> readyLayers;
for (const std::string& layerId : mLayerOrder)
{
LayerProgram* layer = FindLayer(layerId);
if (!layer || !layer->renderer || !layer->renderer->HasProgram())
continue;
layer->renderer->RenderFrame(frameIndex, width, height);
readyLayers.push_back(layer);
}
if (readyLayers.empty())
return;
GLint outputFramebuffer = 0;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &outputFramebuffer);
if (readyLayers.size() == 1)
{
readyLayers.front()->renderer->RenderFrame(frameIndex, width, height);
return;
}
if (!EnsureLayerTargets(width, height))
{
glBindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(outputFramebuffer));
readyLayers.back()->renderer->RenderFrame(frameIndex, width, height);
return;
}
GLuint layerInputTexture = 0;
std::size_t nextTargetIndex = 0;
for (std::size_t layerIndex = 0; layerIndex < readyLayers.size(); ++layerIndex)
{
const bool isFinalLayer = layerIndex == readyLayers.size() - 1;
if (isFinalLayer)
{
glBindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(outputFramebuffer));
readyLayers[layerIndex]->renderer->RenderFrame(frameIndex, width, height, layerInputTexture, layerInputTexture);
continue;
}
glBindFramebuffer(GL_FRAMEBUFFER, mLayerFramebuffers[nextTargetIndex]);
readyLayers[layerIndex]->renderer->RenderFrame(frameIndex, width, height, layerInputTexture, layerInputTexture);
layerInputTexture = mLayerTextures[nextTargetIndex];
nextTargetIndex = 1 - nextTargetIndex;
}
}
@@ -109,6 +151,7 @@ void RuntimeRenderScene::ShutdownGl()
}
mLayers.clear();
mLayerOrder.clear();
DestroyLayerTargets();
}
void RuntimeRenderScene::ConsumePreparedPrograms()
@@ -146,6 +189,68 @@ void RuntimeRenderScene::ConsumePreparedPrograms()
}
}
bool RuntimeRenderScene::EnsureLayerTargets(unsigned width, unsigned height)
{
if (width == 0 || height == 0)
return false;
if (mLayerFramebuffers[0] != 0 && mLayerFramebuffers[1] != 0 && mLayerTextures[0] != 0 && mLayerTextures[1] != 0
&& mLayerTargetWidth == width && mLayerTargetHeight == height)
return true;
DestroyLayerTargets();
mLayerTargetWidth = width;
mLayerTargetHeight = height;
glGenFramebuffers(2, mLayerFramebuffers);
glGenTextures(2, mLayerTextures);
for (int index = 0; index < 2; ++index)
{
glBindTexture(GL_TEXTURE_2D, mLayerTextures[index]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA8,
static_cast<GLsizei>(width),
static_cast<GLsizei>(height),
0,
GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8_REV,
nullptr);
glBindFramebuffer(GL_FRAMEBUFFER, mLayerFramebuffers[index]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mLayerTextures[index], 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
DestroyLayerTargets();
return false;
}
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
return true;
}
void RuntimeRenderScene::DestroyLayerTargets()
{
if (mLayerFramebuffers[0] != 0 || mLayerFramebuffers[1] != 0)
glDeleteFramebuffers(2, mLayerFramebuffers);
if (mLayerTextures[0] != 0 || mLayerTextures[1] != 0)
glDeleteTextures(2, mLayerTextures);
mLayerFramebuffers[0] = 0;
mLayerFramebuffers[1] = 0;
mLayerTextures[0] = 0;
mLayerTextures[1] = 0;
mLayerTargetWidth = 0;
mLayerTargetHeight = 0;
}
RuntimeRenderScene::LayerProgram* RuntimeRenderScene::FindLayer(const std::string& layerId)
{
for (LayerProgram& layer : mLayers)