Render class
This commit is contained in:
@@ -64,6 +64,7 @@ set(APP_SOURCES
|
|||||||
"${APP_DIR}/gl/pipeline/OpenGLRenderPass.h"
|
"${APP_DIR}/gl/pipeline/OpenGLRenderPass.h"
|
||||||
"${APP_DIR}/gl/pipeline/OpenGLRenderPipeline.cpp"
|
"${APP_DIR}/gl/pipeline/OpenGLRenderPipeline.cpp"
|
||||||
"${APP_DIR}/gl/pipeline/OpenGLRenderPipeline.h"
|
"${APP_DIR}/gl/pipeline/OpenGLRenderPipeline.h"
|
||||||
|
"${APP_DIR}/gl/pipeline/RenderPassDescriptor.h"
|
||||||
"${APP_DIR}/gl/renderer/OpenGLRenderer.cpp"
|
"${APP_DIR}/gl/renderer/OpenGLRenderer.cpp"
|
||||||
"${APP_DIR}/gl/renderer/OpenGLRenderer.h"
|
"${APP_DIR}/gl/renderer/OpenGLRenderer.h"
|
||||||
"${APP_DIR}/gl/pipeline/OpenGLVideoIOBridge.cpp"
|
"${APP_DIR}/gl/pipeline/OpenGLVideoIOBridge.cpp"
|
||||||
|
|||||||
@@ -206,6 +206,7 @@
|
|||||||
<ClInclude Include="gl\OpenGLComposite.h" />
|
<ClInclude Include="gl\OpenGLComposite.h" />
|
||||||
<ClInclude Include="gl\pipeline\OpenGLRenderPass.h" />
|
<ClInclude Include="gl\pipeline\OpenGLRenderPass.h" />
|
||||||
<ClInclude Include="gl\pipeline\OpenGLRenderPipeline.h" />
|
<ClInclude Include="gl\pipeline\OpenGLRenderPipeline.h" />
|
||||||
|
<ClInclude Include="gl\pipeline\RenderPassDescriptor.h" />
|
||||||
<ClInclude Include="gl\renderer\OpenGLRenderer.h" />
|
<ClInclude Include="gl\renderer\OpenGLRenderer.h" />
|
||||||
<ClInclude Include="gl\shader\OpenGLShaderPrograms.h" />
|
<ClInclude Include="gl\shader\OpenGLShaderPrograms.h" />
|
||||||
<ClInclude Include="gl\pipeline\PngScreenshotWriter.h" />
|
<ClInclude Include="gl\pipeline\PngScreenshotWriter.h" />
|
||||||
|
|||||||
@@ -92,6 +92,9 @@
|
|||||||
<ClInclude Include="gl\pipeline\OpenGLRenderPipeline.h">
|
<ClInclude Include="gl\pipeline\OpenGLRenderPipeline.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="gl\pipeline\RenderPassDescriptor.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="gl\renderer\OpenGLRenderer.h">
|
<ClInclude Include="gl\renderer\OpenGLRenderer.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|||||||
@@ -43,26 +43,16 @@ void OpenGLRenderPass::Render(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GLuint sourceTexture = mRenderer.DecodedTexture();
|
const std::vector<RenderPassDescriptor> passes = BuildLayerPassDescriptors(layerStates, layerPrograms);
|
||||||
GLuint sourceFrameBuffer = mRenderer.DecodeFramebuffer();
|
for (const RenderPassDescriptor& pass : passes)
|
||||||
for (std::size_t index = 0; index < layerStates.size() && index < layerPrograms.size(); ++index)
|
|
||||||
{
|
{
|
||||||
const std::size_t remaining = layerStates.size() - index;
|
RenderLayerPass(
|
||||||
const bool writeToMain = (remaining % 2) == 1;
|
pass,
|
||||||
RenderShaderProgram(
|
|
||||||
sourceTexture,
|
|
||||||
writeToMain ? mRenderer.CompositeFramebuffer() : mRenderer.LayerTempFramebuffer(),
|
|
||||||
layerPrograms[index],
|
|
||||||
layerStates[index],
|
|
||||||
inputFrameWidth,
|
inputFrameWidth,
|
||||||
inputFrameHeight,
|
inputFrameHeight,
|
||||||
historyCap,
|
historyCap,
|
||||||
updateTextBinding,
|
updateTextBinding,
|
||||||
updateGlobalParams);
|
updateGlobalParams);
|
||||||
if (layerStates[index].temporalHistorySource == TemporalHistorySource::PreLayerInput)
|
|
||||||
mRenderer.TemporalHistory().PushPreLayerFramebuffer(layerStates[index].layerId, sourceFrameBuffer, inputFrameWidth, inputFrameHeight);
|
|
||||||
sourceTexture = writeToMain ? mRenderer.CompositeTexture() : mRenderer.LayerTempTexture();
|
|
||||||
sourceFrameBuffer = writeToMain ? mRenderer.CompositeFramebuffer() : mRenderer.LayerTempFramebuffer();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,6 +87,71 @@ void OpenGLRenderPass::RenderDecodePass(unsigned inputFrameWidth, unsigned input
|
|||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<RenderPassDescriptor> OpenGLRenderPass::BuildLayerPassDescriptors(
|
||||||
|
const std::vector<RuntimeRenderState>& layerStates,
|
||||||
|
std::vector<LayerProgram>& layerPrograms) const
|
||||||
|
{
|
||||||
|
std::vector<RenderPassDescriptor> passes;
|
||||||
|
const std::size_t passCount = layerStates.size() < layerPrograms.size() ? layerStates.size() : layerPrograms.size();
|
||||||
|
passes.reserve(passCount);
|
||||||
|
|
||||||
|
GLuint sourceTexture = mRenderer.DecodedTexture();
|
||||||
|
GLuint sourceFramebuffer = mRenderer.DecodeFramebuffer();
|
||||||
|
for (std::size_t index = 0; index < passCount; ++index)
|
||||||
|
{
|
||||||
|
const RuntimeRenderState& state = layerStates[index];
|
||||||
|
LayerProgram& layerProgram = layerPrograms[index];
|
||||||
|
const std::size_t remaining = layerStates.size() - index;
|
||||||
|
const bool writeToMain = (remaining % 2) == 1;
|
||||||
|
|
||||||
|
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.layerState = &state;
|
||||||
|
pass.capturePreLayerHistory = state.temporalHistorySource == TemporalHistorySource::PreLayerInput;
|
||||||
|
passes.push_back(pass);
|
||||||
|
|
||||||
|
sourceTexture = writeToMain ? mRenderer.CompositeTexture() : mRenderer.LayerTempTexture();
|
||||||
|
sourceFramebuffer = writeToMain ? mRenderer.CompositeFramebuffer() : mRenderer.LayerTempFramebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return passes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderPass::RenderLayerPass(
|
||||||
|
const RenderPassDescriptor& pass,
|
||||||
|
unsigned inputFrameWidth,
|
||||||
|
unsigned inputFrameHeight,
|
||||||
|
unsigned historyCap,
|
||||||
|
const TextBindingUpdater& updateTextBinding,
|
||||||
|
const GlobalParamsUpdater& updateGlobalParams)
|
||||||
|
{
|
||||||
|
if (pass.layerProgram == nullptr || pass.layerState == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
RenderShaderProgram(
|
||||||
|
pass.sourceTexture,
|
||||||
|
pass.destinationFramebuffer,
|
||||||
|
*pass.layerProgram,
|
||||||
|
*pass.layerState,
|
||||||
|
inputFrameWidth,
|
||||||
|
inputFrameHeight,
|
||||||
|
historyCap,
|
||||||
|
updateTextBinding,
|
||||||
|
updateGlobalParams);
|
||||||
|
|
||||||
|
if (pass.capturePreLayerHistory)
|
||||||
|
mRenderer.TemporalHistory().PushPreLayerFramebuffer(pass.layerId, pass.sourceFramebuffer, inputFrameWidth, inputFrameHeight);
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLRenderPass::RenderShaderProgram(
|
void OpenGLRenderPass::RenderShaderProgram(
|
||||||
GLuint sourceTexture,
|
GLuint sourceTexture,
|
||||||
GLuint destinationFrameBuffer,
|
GLuint destinationFrameBuffer,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "OpenGLRenderer.h"
|
#include "OpenGLRenderer.h"
|
||||||
|
#include "RenderPassDescriptor.h"
|
||||||
#include "ShaderTypes.h"
|
#include "ShaderTypes.h"
|
||||||
#include "VideoIOFormat.h"
|
#include "VideoIOFormat.h"
|
||||||
|
|
||||||
@@ -30,6 +31,16 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void RenderDecodePass(unsigned inputFrameWidth, unsigned inputFrameHeight, unsigned captureTextureWidth, VideoIOPixelFormat inputPixelFormat);
|
void RenderDecodePass(unsigned inputFrameWidth, unsigned inputFrameHeight, unsigned captureTextureWidth, VideoIOPixelFormat inputPixelFormat);
|
||||||
|
std::vector<RenderPassDescriptor> BuildLayerPassDescriptors(
|
||||||
|
const std::vector<RuntimeRenderState>& layerStates,
|
||||||
|
std::vector<LayerProgram>& layerPrograms) const;
|
||||||
|
void RenderLayerPass(
|
||||||
|
const RenderPassDescriptor& pass,
|
||||||
|
unsigned inputFrameWidth,
|
||||||
|
unsigned inputFrameHeight,
|
||||||
|
unsigned historyCap,
|
||||||
|
const TextBindingUpdater& updateTextBinding,
|
||||||
|
const GlobalParamsUpdater& updateGlobalParams);
|
||||||
void RenderShaderProgram(
|
void RenderShaderProgram(
|
||||||
GLuint sourceTexture,
|
GLuint sourceTexture,
|
||||||
GLuint destinationFrameBuffer,
|
GLuint destinationFrameBuffer,
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "OpenGLRenderer.h"
|
||||||
|
#include "ShaderTypes.h"
|
||||||
|
|
||||||
|
#include <gl/gl.h>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
enum class RenderPassKind
|
||||||
|
{
|
||||||
|
LayerEffect
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class RenderPassOutputTarget
|
||||||
|
{
|
||||||
|
LayerTemp,
|
||||||
|
Composite
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RenderPassDescriptor
|
||||||
|
{
|
||||||
|
RenderPassKind kind = RenderPassKind::LayerEffect;
|
||||||
|
RenderPassOutputTarget outputTarget = RenderPassOutputTarget::Composite;
|
||||||
|
std::size_t passIndex = 0;
|
||||||
|
std::string passId;
|
||||||
|
std::string layerId;
|
||||||
|
std::string shaderId;
|
||||||
|
GLuint sourceTexture = 0;
|
||||||
|
GLuint sourceFramebuffer = 0;
|
||||||
|
GLuint destinationFramebuffer = 0;
|
||||||
|
OpenGLRenderer::LayerProgram* layerProgram = nullptr;
|
||||||
|
const RuntimeRenderState* layerState = nullptr;
|
||||||
|
bool capturePreLayerHistory = false;
|
||||||
|
};
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gl/gl.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
enum class RenderTargetId
|
||||||
|
{
|
||||||
|
Decoded,
|
||||||
|
LayerTemp,
|
||||||
|
Composite,
|
||||||
|
Output,
|
||||||
|
OutputPack,
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RenderTarget
|
||||||
|
{
|
||||||
|
GLuint texture = 0;
|
||||||
|
GLuint framebuffer = 0;
|
||||||
|
unsigned width = 0;
|
||||||
|
unsigned height = 0;
|
||||||
|
GLenum internalFormat = GL_RGBA8;
|
||||||
|
GLenum pixelFormat = GL_RGBA;
|
||||||
|
GLenum pixelType = GL_UNSIGNED_BYTE;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RenderTargetPool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool Create(
|
||||||
|
RenderTargetId id,
|
||||||
|
unsigned width,
|
||||||
|
unsigned height,
|
||||||
|
GLenum internalFormat,
|
||||||
|
GLenum pixelFormat,
|
||||||
|
GLenum pixelType,
|
||||||
|
const char* errorPrefix,
|
||||||
|
std::string& error);
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
|
GLuint Texture(RenderTargetId id) const { return Target(id).texture; }
|
||||||
|
GLuint Framebuffer(RenderTargetId id) const { return Target(id).framebuffer; }
|
||||||
|
const RenderTarget& Target(RenderTargetId id) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::size_t TargetIndex(RenderTargetId id) { return static_cast<std::size_t>(id); }
|
||||||
|
|
||||||
|
std::array<RenderTarget, static_cast<std::size_t>(RenderTargetId::Count)> mTargets;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user