Multi pass
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "GlRenderConstants.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
OpenGLRenderPass::OpenGLRenderPass(OpenGLRenderer& renderer) :
|
||||
mRenderer(renderer)
|
||||
{
|
||||
@@ -93,7 +95,10 @@ std::vector<RenderPassDescriptor> OpenGLRenderPass::BuildLayerPassDescriptors(
|
||||
{
|
||||
std::vector<RenderPassDescriptor> passes;
|
||||
const std::size_t passCount = layerStates.size() < layerPrograms.size() ? layerStates.size() : layerPrograms.size();
|
||||
passes.reserve(passCount);
|
||||
std::size_t descriptorCount = 0;
|
||||
for (std::size_t index = 0; index < passCount; ++index)
|
||||
descriptorCount += layerPrograms[index].passes.size();
|
||||
passes.reserve(descriptorCount);
|
||||
|
||||
GLuint sourceTexture = mRenderer.DecodedTexture();
|
||||
GLuint sourceFramebuffer = mRenderer.DecodeFramebuffer();
|
||||
@@ -105,25 +110,90 @@ std::vector<RenderPassDescriptor> OpenGLRenderPass::BuildLayerPassDescriptors(
|
||||
continue;
|
||||
const std::size_t remaining = layerStates.size() - index;
|
||||
const bool writeToMain = (remaining % 2) == 1;
|
||||
const GLuint layerOutputTexture = writeToMain ? mRenderer.CompositeTexture() : mRenderer.LayerTempTexture();
|
||||
const GLuint layerOutputFramebuffer = writeToMain ? mRenderer.CompositeFramebuffer() : mRenderer.LayerTempFramebuffer();
|
||||
const RenderPassOutputTarget layerOutputTarget = writeToMain ? RenderPassOutputTarget::Composite : RenderPassOutputTarget::LayerTemp;
|
||||
|
||||
RenderPassDescriptor pass;
|
||||
pass.kind = RenderPassKind::LayerEffect;
|
||||
pass.outputTarget = writeToMain ? RenderPassOutputTarget::Composite : RenderPassOutputTarget::LayerTemp;
|
||||
pass.passIndex = index;
|
||||
pass.passId = state.layerId;
|
||||
pass.layerId = state.layerId;
|
||||
pass.shaderId = state.shaderId;
|
||||
pass.sourceTexture = sourceTexture;
|
||||
pass.sourceFramebuffer = sourceFramebuffer;
|
||||
pass.destinationFramebuffer = writeToMain ? mRenderer.CompositeFramebuffer() : mRenderer.LayerTempFramebuffer();
|
||||
pass.layerProgram = &layerProgram;
|
||||
pass.passProgram = &layerProgram.passes.front();
|
||||
pass.layerState = &state;
|
||||
pass.capturePreLayerHistory = state.temporalHistorySource == TemporalHistorySource::PreLayerInput;
|
||||
passes.push_back(pass);
|
||||
const GLuint layerInputTexture = sourceTexture;
|
||||
const GLuint layerInputFramebuffer = sourceFramebuffer;
|
||||
GLuint previousPassTexture = layerInputTexture;
|
||||
GLuint previousPassFramebuffer = layerInputFramebuffer;
|
||||
std::map<std::string, std::pair<GLuint, GLuint>> namedOutputs;
|
||||
std::size_t temporaryTargetIndex = 0;
|
||||
|
||||
sourceTexture = writeToMain ? mRenderer.CompositeTexture() : mRenderer.LayerTempTexture();
|
||||
sourceFramebuffer = writeToMain ? mRenderer.CompositeFramebuffer() : mRenderer.LayerTempFramebuffer();
|
||||
for (std::size_t passIndex = 0; passIndex < layerProgram.passes.size(); ++passIndex)
|
||||
{
|
||||
PassProgram& passProgram = layerProgram.passes[passIndex];
|
||||
const bool lastPassForLayer = passIndex + 1 == layerProgram.passes.size();
|
||||
const std::string outputName = passProgram.outputName.empty() ? passProgram.passId : passProgram.outputName;
|
||||
const bool writesLayerOutput = outputName == "layerOutput" || lastPassForLayer;
|
||||
|
||||
GLuint passSourceTexture = previousPassTexture;
|
||||
GLuint passSourceFramebuffer = previousPassFramebuffer;
|
||||
if (!passProgram.inputNames.empty())
|
||||
{
|
||||
const std::string& inputName = passProgram.inputNames.front();
|
||||
if (inputName == "layerInput")
|
||||
{
|
||||
passSourceTexture = layerInputTexture;
|
||||
passSourceFramebuffer = layerInputFramebuffer;
|
||||
}
|
||||
else if (inputName == "previousPass")
|
||||
{
|
||||
passSourceTexture = previousPassTexture;
|
||||
passSourceFramebuffer = previousPassFramebuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto namedOutputIt = namedOutputs.find(inputName);
|
||||
if (namedOutputIt != namedOutputs.end())
|
||||
{
|
||||
passSourceTexture = namedOutputIt->second.first;
|
||||
passSourceFramebuffer = namedOutputIt->second.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLuint passDestinationTexture = layerOutputTexture;
|
||||
GLuint passDestinationFramebuffer = layerOutputFramebuffer;
|
||||
RenderPassOutputTarget outputTarget = layerOutputTarget;
|
||||
if (!writesLayerOutput)
|
||||
{
|
||||
if (temporaryTargetIndex < mRenderer.TemporaryRenderTargetCount())
|
||||
{
|
||||
const RenderTarget& temporaryTarget = mRenderer.TemporaryRenderTarget(temporaryTargetIndex);
|
||||
++temporaryTargetIndex;
|
||||
passDestinationTexture = temporaryTarget.texture;
|
||||
passDestinationFramebuffer = temporaryTarget.framebuffer;
|
||||
outputTarget = RenderPassOutputTarget::Temporary;
|
||||
}
|
||||
}
|
||||
|
||||
RenderPassDescriptor pass;
|
||||
pass.kind = RenderPassKind::LayerEffect;
|
||||
pass.outputTarget = outputTarget;
|
||||
pass.passIndex = passes.size();
|
||||
pass.passId = passProgram.passId;
|
||||
pass.layerId = state.layerId;
|
||||
pass.shaderId = state.shaderId;
|
||||
pass.sourceTexture = passSourceTexture;
|
||||
pass.sourceFramebuffer = passIndex == 0 ? layerInputFramebuffer : passSourceFramebuffer;
|
||||
pass.destinationTexture = passDestinationTexture;
|
||||
pass.destinationFramebuffer = passDestinationFramebuffer;
|
||||
pass.layerProgram = &layerProgram;
|
||||
pass.passProgram = &passProgram;
|
||||
pass.layerState = &state;
|
||||
pass.capturePreLayerHistory = passIndex == 0 && state.temporalHistorySource == TemporalHistorySource::PreLayerInput;
|
||||
passes.push_back(pass);
|
||||
|
||||
namedOutputs[outputName] = std::make_pair(passDestinationTexture, passDestinationFramebuffer);
|
||||
namedOutputs[passProgram.passId] = std::make_pair(passDestinationTexture, passDestinationFramebuffer);
|
||||
previousPassTexture = passDestinationTexture;
|
||||
previousPassFramebuffer = passDestinationFramebuffer;
|
||||
}
|
||||
|
||||
sourceTexture = layerOutputTexture;
|
||||
sourceFramebuffer = layerOutputFramebuffer;
|
||||
}
|
||||
|
||||
return passes;
|
||||
|
||||
@@ -15,6 +15,7 @@ enum class RenderPassKind
|
||||
|
||||
enum class RenderPassOutputTarget
|
||||
{
|
||||
Temporary,
|
||||
LayerTemp,
|
||||
Composite
|
||||
};
|
||||
@@ -29,6 +30,7 @@ struct RenderPassDescriptor
|
||||
std::string shaderId;
|
||||
GLuint sourceTexture = 0;
|
||||
GLuint sourceFramebuffer = 0;
|
||||
GLuint destinationTexture = 0;
|
||||
GLuint destinationFramebuffer = 0;
|
||||
OpenGLRenderer::LayerProgram* layerProgram = nullptr;
|
||||
OpenGLRenderer::LayerProgram::PassProgram* passProgram = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user