From 5f23f39a24bbc474cf2ade339c1feac447ee5742 Mon Sep 17 00:00:00 2001 From: Stefan Buschmann Date: Sun, 16 Jul 2017 10:30:18 +0200 Subject: [PATCH 1/2] Review RenderInterface. Simplify interface a bit, add more comments --- .../DemoAntialiasingAggregationPipeline.cpp | 4 +- .../DemoDOFAggregationPipeline.cpp | 4 +- .../DemoMultiFrameAggregationPipeline.cpp | 4 +- .../DemoSSAOAggregationPipeline.cpp | 4 +- .../DemoTransparencyAggregationPipeline.cpp | 5 +- .../demo-stages-plugins/ShapeDemo.cpp | 9 +- .../IntermediateFramePreparationStage.cpp | 2 +- .../stages/MultiFrameAggregationPipeline.cpp | 4 +- .../stages/MultiFrameAggregationStage.cpp | 2 +- .../rendering/AbstractRenderTarget.h | 2 +- .../gloperate/rendering/ColorRenderTarget.h | 2 +- .../gloperate/rendering/DepthRenderTarget.h | 2 +- .../rendering/DepthStencilRenderTarget.h | 2 +- .../gloperate/rendering/RenderTargetType.h | 2 +- .../gloperate/rendering/StencilRenderTarget.h | 2 +- .../stages/interfaces/CanvasInterface.h | 7 +- .../stages/interfaces/RenderInterface.h | 284 ++--------- .../source/rendering/ColorRenderTarget.cpp | 2 +- .../source/rendering/DepthRenderTarget.cpp | 2 +- .../rendering/DepthStencilRenderTarget.cpp | 2 +- .../source/rendering/StencilRenderTarget.cpp | 2 +- .../source/stages/base/ClearStage.cpp | 8 +- .../source/stages/base/RasterizationStage.cpp | 2 +- .../stages/interfaces/RenderInterface.cpp | 479 +++++++----------- 24 files changed, 263 insertions(+), 575 deletions(-) diff --git a/source/examples/demo-stages-plugins/DemoAntialiasingAggregationPipeline.cpp b/source/examples/demo-stages-plugins/DemoAntialiasingAggregationPipeline.cpp index e2e2762c..d2ef0d81 100644 --- a/source/examples/demo-stages-plugins/DemoAntialiasingAggregationPipeline.cpp +++ b/source/examples/demo-stages-plugins/DemoAntialiasingAggregationPipeline.cpp @@ -22,7 +22,7 @@ DemoAntialiasingAggregationPipeline::DemoAntialiasingAggregationPipeline(glopera m_antialiasingPipeline->multiFrameCount << multiFrameCount; // Inputs - *m_multiFramePipeline->canvasInterface.colorRenderTargetInput(0) << *createInput("Color"); + *m_multiFramePipeline->canvasInterface.colorRenderTargetInputs()[0] << *createInput("Color"); m_multiFramePipeline->canvasInterface.viewport << canvasInterface.viewport; m_multiFramePipeline->canvasInterface.backgroundColor << canvasInterface.backgroundColor; @@ -31,7 +31,7 @@ DemoAntialiasingAggregationPipeline::DemoAntialiasingAggregationPipeline(glopera m_multiFramePipeline->multiFrameCount << multiFrameCount; // Outputs - *createOutput("ColorOut") << *m_multiFramePipeline->canvasInterface.colorRenderTargetOutput(0); + *createOutput("ColorOut") << *m_multiFramePipeline->canvasInterface.colorRenderTargetOutputs()[0]; } DemoAntialiasingAggregationPipeline::~DemoAntialiasingAggregationPipeline() diff --git a/source/examples/demo-stages-plugins/DemoDOFAggregationPipeline.cpp b/source/examples/demo-stages-plugins/DemoDOFAggregationPipeline.cpp index 56611824..1ffa0322 100644 --- a/source/examples/demo-stages-plugins/DemoDOFAggregationPipeline.cpp +++ b/source/examples/demo-stages-plugins/DemoDOFAggregationPipeline.cpp @@ -22,7 +22,7 @@ DemoDOFAggregationPipeline::DemoDOFAggregationPipeline(gloperate::Environment * m_dofPipeline->multiFrameCount << multiFrameCount; // Inputs - *m_multiFramePipeline->canvasInterface.colorRenderTargetInput(0) << *createInput("Color"); + *m_multiFramePipeline->canvasInterface.colorRenderTargetInputs()[0] << *createInput("Color"); m_multiFramePipeline->canvasInterface.viewport << canvasInterface.viewport; m_multiFramePipeline->canvasInterface.backgroundColor << canvasInterface.backgroundColor; @@ -31,7 +31,7 @@ DemoDOFAggregationPipeline::DemoDOFAggregationPipeline(gloperate::Environment * m_multiFramePipeline->multiFrameCount << multiFrameCount; // Outputs - *createOutput("ColorOut") << *m_multiFramePipeline->canvasInterface.colorRenderTargetOutput(0); + *createOutput("ColorOut") << *m_multiFramePipeline->canvasInterface.colorRenderTargetOutputs()[0]; } DemoDOFAggregationPipeline::~DemoDOFAggregationPipeline() diff --git a/source/examples/demo-stages-plugins/DemoMultiFrameAggregationPipeline.cpp b/source/examples/demo-stages-plugins/DemoMultiFrameAggregationPipeline.cpp index 6642562c..43bb2d32 100644 --- a/source/examples/demo-stages-plugins/DemoMultiFrameAggregationPipeline.cpp +++ b/source/examples/demo-stages-plugins/DemoMultiFrameAggregationPipeline.cpp @@ -22,7 +22,7 @@ DemoMultiFrameAggregationPipeline::DemoMultiFrameAggregationPipeline(gloperate:: m_renderingPipeline->multiFrameCount << multiFrameCount; // Inputs - *m_multiFramePipeline->canvasInterface.colorRenderTargetInput(0) << *createInput("Color"); + *m_multiFramePipeline->canvasInterface.colorRenderTargetInputs()[0] << *createInput("Color"); m_multiFramePipeline->canvasInterface.viewport << canvasInterface.viewport; m_multiFramePipeline->canvasInterface.backgroundColor << canvasInterface.backgroundColor; @@ -31,7 +31,7 @@ DemoMultiFrameAggregationPipeline::DemoMultiFrameAggregationPipeline(gloperate:: m_multiFramePipeline->multiFrameCount << multiFrameCount; // Outputs - *createOutput("ColorOut") << *m_multiFramePipeline->canvasInterface.colorRenderTargetOutput(0); + *createOutput("ColorOut") << *m_multiFramePipeline->canvasInterface.colorRenderTargetOutputs()[0]; } DemoMultiFrameAggregationPipeline::~DemoMultiFrameAggregationPipeline() diff --git a/source/examples/demo-stages-plugins/DemoSSAOAggregationPipeline.cpp b/source/examples/demo-stages-plugins/DemoSSAOAggregationPipeline.cpp index 91926c34..64afe697 100644 --- a/source/examples/demo-stages-plugins/DemoSSAOAggregationPipeline.cpp +++ b/source/examples/demo-stages-plugins/DemoSSAOAggregationPipeline.cpp @@ -22,7 +22,7 @@ DemoSSAOAggregationPipeline::DemoSSAOAggregationPipeline(gloperate::Environment //m_ssaoPipeline->multiFrameCount << multiFrameCount; // Inputs - *m_multiFramePipeline->canvasInterface.colorRenderTargetInput(0) << *createInput("Color"); + *m_multiFramePipeline->canvasInterface.colorRenderTargetInputs()[0] << *createInput("Color"); m_multiFramePipeline->canvasInterface.viewport << canvasInterface.viewport; m_multiFramePipeline->canvasInterface.backgroundColor << canvasInterface.backgroundColor; @@ -31,7 +31,7 @@ DemoSSAOAggregationPipeline::DemoSSAOAggregationPipeline(gloperate::Environment m_multiFramePipeline->multiFrameCount << multiFrameCount; // Outputs - *createOutput("ColorOut") << *m_multiFramePipeline->canvasInterface.colorRenderTargetOutput(0); + *createOutput("ColorOut") << *m_multiFramePipeline->canvasInterface.colorRenderTargetOutputs()[0]; } DemoSSAOAggregationPipeline::~DemoSSAOAggregationPipeline() diff --git a/source/examples/demo-stages-plugins/DemoTransparencyAggregationPipeline.cpp b/source/examples/demo-stages-plugins/DemoTransparencyAggregationPipeline.cpp index 9c350e83..be327ff1 100644 --- a/source/examples/demo-stages-plugins/DemoTransparencyAggregationPipeline.cpp +++ b/source/examples/demo-stages-plugins/DemoTransparencyAggregationPipeline.cpp @@ -22,8 +22,7 @@ DemoTransparencyAggregationPipeline::DemoTransparencyAggregationPipeline(glopera //m_transparencyPipeline->multiFrameCount << multiFrameCount; // Inputs - // Inputs - *m_multiFramePipeline->canvasInterface.colorRenderTargetInput(0) << *createInput("Color"); + *m_multiFramePipeline->canvasInterface.colorRenderTargetInputs()[0] << *createInput("Color"); m_multiFramePipeline->canvasInterface.viewport << canvasInterface.viewport; m_multiFramePipeline->canvasInterface.backgroundColor << canvasInterface.backgroundColor; @@ -32,7 +31,7 @@ DemoTransparencyAggregationPipeline::DemoTransparencyAggregationPipeline(glopera m_multiFramePipeline->multiFrameCount << multiFrameCount; // Outputs - *createOutput("ColorOut") << *m_multiFramePipeline->canvasInterface.colorRenderTargetOutput(0); + *createOutput("ColorOut") << *m_multiFramePipeline->canvasInterface.colorRenderTargetOutputs()[0]; } DemoTransparencyAggregationPipeline::~DemoTransparencyAggregationPipeline() diff --git a/source/examples/demo-stages-plugins/ShapeDemo.cpp b/source/examples/demo-stages-plugins/ShapeDemo.cpp index 2baa64be..3a7a8495 100644 --- a/source/examples/demo-stages-plugins/ShapeDemo.cpp +++ b/source/examples/demo-stages-plugins/ShapeDemo.cpp @@ -144,12 +144,13 @@ ShapeDemo::ShapeDemo(Environment * environment, const std::string & name) auto shapeColorOutput = m_shapeRasterization->createOutput("ColorAttachmentOut"); - /* Hack Start */ + // [TODO] Remove hack! + // Hack Start shapeColorOutput->valueInvalidated.onFire([=]() { - m_clear->renderInterface.colorRenderTargetOutput(0)->invalidate(); - m_clear->renderInterface.depthRenderTargetOutput(0)->invalidate(); + m_clear->renderInterface.colorRenderTargetOutputs()[0]->invalidate(); + m_clear->renderInterface.depthRenderTargetOutputs()[0]->invalidate(); }); - /* Hack End */ + // Hack End addStage(m_textureExtractionStage.get()); m_textureExtractionStage->colorRenderTarget << *shapeColorOutput; diff --git a/source/gloperate-glkernel/source/stages/IntermediateFramePreparationStage.cpp b/source/gloperate-glkernel/source/stages/IntermediateFramePreparationStage.cpp index 01d2c718..09df118a 100644 --- a/source/gloperate-glkernel/source/stages/IntermediateFramePreparationStage.cpp +++ b/source/gloperate-glkernel/source/stages/IntermediateFramePreparationStage.cpp @@ -49,7 +49,7 @@ void IntermediateFramePreparationStage::onContextDeinit(gloperate::AbstractGLCon void IntermediateFramePreparationStage::onProcess() { - if (!renderInterface.allRenderTargetsCompatible()) + if (!renderInterface.renderTargetsAreCompatible()) { cppassist::warning("gloperate") << "Framebuffer configuration not compatible"; diff --git a/source/gloperate-glkernel/source/stages/MultiFrameAggregationPipeline.cpp b/source/gloperate-glkernel/source/stages/MultiFrameAggregationPipeline.cpp index 2edf518f..5ae271da 100644 --- a/source/gloperate-glkernel/source/stages/MultiFrameAggregationPipeline.cpp +++ b/source/gloperate-glkernel/source/stages/MultiFrameAggregationPipeline.cpp @@ -59,8 +59,8 @@ MultiFrameAggregationPipeline::MultiFrameAggregationPipeline(gloperate::Environm m_framePreparationStage->intermediateFrameTexture << m_colorRenderTargetStage->texture; addStage(m_aggregationStage.get()); - (*m_aggregationStage->createInput("ColorTarget")) << (*canvasInterface.colorRenderTargetInput(0)); - (*canvasInterface.colorRenderTargetOutput(0)) << (*m_aggregationStage->createOutput("ColorTargetOut")); + (*m_aggregationStage->createInput("ColorTarget")) << (*canvasInterface.colorRenderTargetInputs()[0]); + (*canvasInterface.colorRenderTargetOutputs()[0]) << (*m_aggregationStage->createOutput("ColorTargetOut")); m_aggregationStage->intermediateFrame << m_framePreparationStage->intermediateFrameTextureOut; // set by setRenderStage m_aggregationStage->renderInterface.viewport << canvasInterface.viewport; m_aggregationStage->aggregationFactor << m_controlStage->aggregationFactor; diff --git a/source/gloperate-glkernel/source/stages/MultiFrameAggregationStage.cpp b/source/gloperate-glkernel/source/stages/MultiFrameAggregationStage.cpp index 493e8dfc..e10d70f7 100644 --- a/source/gloperate-glkernel/source/stages/MultiFrameAggregationStage.cpp +++ b/source/gloperate-glkernel/source/stages/MultiFrameAggregationStage.cpp @@ -47,7 +47,7 @@ void MultiFrameAggregationStage::onContextDeinit(gloperate::AbstractGLContext * void MultiFrameAggregationStage::onProcess() { - if (!renderInterface.allRenderTargetsCompatible()) + if (!renderInterface.renderTargetsAreCompatible()) { cppassist::warning("gloperate") << "Framebuffer configuration not compatible"; diff --git a/source/gloperate/include/gloperate/rendering/AbstractRenderTarget.h b/source/gloperate/include/gloperate/rendering/AbstractRenderTarget.h index 7257a7ee..3d7090f7 100644 --- a/source/gloperate/include/gloperate/rendering/AbstractRenderTarget.h +++ b/source/gloperate/include/gloperate/rendering/AbstractRenderTarget.h @@ -207,7 +207,7 @@ class GLOPERATE_API AbstractRenderTarget * @return * The attachment type */ - virtual AttachmentType underlyingAttachmentType() const = 0; + virtual AttachmentType attachmentType() const = 0; /** * @brief diff --git a/source/gloperate/include/gloperate/rendering/ColorRenderTarget.h b/source/gloperate/include/gloperate/rendering/ColorRenderTarget.h index 264779d0..4d327dff 100644 --- a/source/gloperate/include/gloperate/rendering/ColorRenderTarget.h +++ b/source/gloperate/include/gloperate/rendering/ColorRenderTarget.h @@ -27,7 +27,7 @@ class GLOPERATE_API ColorRenderTarget : public AbstractRenderTarget // Virtual AbstractRenderTarget interface virtual gl::GLint clearBufferDrawBuffer(size_t index) const override; virtual gl::GLenum drawBufferAttachment(size_t index) const override; - virtual AttachmentType underlyingAttachmentType() const override; + virtual AttachmentType attachmentType() const override; virtual gl::GLenum attachmentGLType() const override; }; diff --git a/source/gloperate/include/gloperate/rendering/DepthRenderTarget.h b/source/gloperate/include/gloperate/rendering/DepthRenderTarget.h index 93d5cc4b..e0790451 100644 --- a/source/gloperate/include/gloperate/rendering/DepthRenderTarget.h +++ b/source/gloperate/include/gloperate/rendering/DepthRenderTarget.h @@ -27,7 +27,7 @@ class GLOPERATE_API DepthRenderTarget : public AbstractRenderTarget // Virtual AbstractRenderTarget interface virtual gl::GLint clearBufferDrawBuffer(size_t index) const override; virtual gl::GLenum drawBufferAttachment(size_t index) const override; - virtual AttachmentType underlyingAttachmentType() const override; + virtual AttachmentType attachmentType() const override; virtual gl::GLenum attachmentGLType() const override; }; diff --git a/source/gloperate/include/gloperate/rendering/DepthStencilRenderTarget.h b/source/gloperate/include/gloperate/rendering/DepthStencilRenderTarget.h index 460f4341..a3d1a794 100644 --- a/source/gloperate/include/gloperate/rendering/DepthStencilRenderTarget.h +++ b/source/gloperate/include/gloperate/rendering/DepthStencilRenderTarget.h @@ -27,7 +27,7 @@ class GLOPERATE_API DepthStencilRenderTarget : public AbstractRenderTarget // Virtual AbstractRenderTarget interface virtual gl::GLint clearBufferDrawBuffer(size_t index) const override; virtual gl::GLenum drawBufferAttachment(size_t index) const override; - virtual AttachmentType underlyingAttachmentType() const override; + virtual AttachmentType attachmentType() const override; virtual gl::GLenum attachmentGLType() const override; }; diff --git a/source/gloperate/include/gloperate/rendering/RenderTargetType.h b/source/gloperate/include/gloperate/rendering/RenderTargetType.h index e524c7ec..c2228a5e 100644 --- a/source/gloperate/include/gloperate/rendering/RenderTargetType.h +++ b/source/gloperate/include/gloperate/rendering/RenderTargetType.h @@ -12,7 +12,7 @@ namespace gloperate /** * @brief -* Type of a render target +* Technical type of a render target */ enum class RenderTargetType : unsigned int { diff --git a/source/gloperate/include/gloperate/rendering/StencilRenderTarget.h b/source/gloperate/include/gloperate/rendering/StencilRenderTarget.h index c8c20e59..0722b58e 100644 --- a/source/gloperate/include/gloperate/rendering/StencilRenderTarget.h +++ b/source/gloperate/include/gloperate/rendering/StencilRenderTarget.h @@ -28,7 +28,7 @@ class GLOPERATE_API StencilRenderTarget : public AbstractRenderTarget // Virtual AbstractRenderTarget interface virtual gl::GLint clearBufferDrawBuffer(size_t index) const override; virtual gl::GLenum drawBufferAttachment(size_t index) const override; - virtual AttachmentType underlyingAttachmentType() const override; + virtual AttachmentType attachmentType() const override; virtual gl::GLenum attachmentGLType() const override; }; diff --git a/source/gloperate/include/gloperate/stages/interfaces/CanvasInterface.h b/source/gloperate/include/gloperate/stages/interfaces/CanvasInterface.h index c89dacca..306eff2c 100644 --- a/source/gloperate/include/gloperate/stages/interfaces/CanvasInterface.h +++ b/source/gloperate/include/gloperate/stages/interfaces/CanvasInterface.h @@ -36,9 +36,10 @@ class GLOPERATE_API CanvasInterface : public RenderInterface { public: // Inputs - Input backgroundColor; ///< Background color (RGBA) - Input frameCounter; ///< Frame counter (number of frames) - Input timeDelta; ///< Time delta since last frame (in seconds) + Input backgroundColor; ///< Background color (RGBA) + Input frameCounter; ///< Frame counter (number of frames) + Input timeDelta; ///< Time delta since last frame (in seconds) + public: /** diff --git a/source/gloperate/include/gloperate/stages/interfaces/RenderInterface.h b/source/gloperate/include/gloperate/stages/interfaces/RenderInterface.h index 9c6cc506..ee7f5f8e 100644 --- a/source/gloperate/include/gloperate/stages/interfaces/RenderInterface.h +++ b/source/gloperate/include/gloperate/stages/interfaces/RenderInterface.h @@ -2,8 +2,6 @@ #pragma once -#include - #include #include #include @@ -32,13 +30,17 @@ class StencilRenderTarget; * Interface that can be used for rendering stages and pipelines * * A render stage is a stage that renders into render targets, given -* a common viewport. -* -* This class can be used to instanciate the necessary inputs and outputs +* a common viewport. This class can be used to instanciate the necessary inputs * for rendering stages. It can just be instanciated on a stage or pipeline * and it will add the inputs and outputs directly to the stage (the interface * itself is not an object in the hierarchy). * +* Render target inputs and outputs must be added dynamically to the stage +* (see Stage::createInput) and will be picked up by the RenderInterface +* automatically. They should reflect the targets the stage wants to render +* into. To render into the specified targets, the stage should call obtainFBO() +* and bind the returned framebuffer object before rendering. +* * The viewport is initialized with an invalid width and height (i.e., -1.0 * per component) which results in no rendering for rasterization stages and * full clearing for clear stages. @@ -82,7 +84,7 @@ class GLOPERATE_API RenderInterface * @return * 'true', if all registered render targets are compatible using one single FBO, else 'false' */ - bool allRenderTargetsCompatible() const; + bool renderTargetsAreCompatible() const; /** * @brief @@ -127,6 +129,8 @@ class GLOPERATE_API RenderInterface * The render target to attach * @param[in] fbo * The user-defined framebuffer used for user-defined attachments + * @param[in] defaultFBO + * Default default FBO for the current configuration * * @return * The matching framebuffer; either fbo or defaultFBO, depending on the type of the render target attachment @@ -135,7 +139,7 @@ class GLOPERATE_API RenderInterface /** * @brief - * Get the vector of all registered color render target inputs + * Get all registered color render target inputs * * @return * The vector of color render target inputs @@ -144,7 +148,7 @@ class GLOPERATE_API RenderInterface /** * @brief - * Get the vector of all registered depth render target inputs + * Get all registered depth render target inputs * * @return * The vector of depth render target inputs @@ -153,7 +157,7 @@ class GLOPERATE_API RenderInterface /** * @brief - * Get the vector of all registered depth-stencil render target inputs + * Get all registered depth-stencil render target inputs * * @return * The vector of depth-stencil render target inputs @@ -162,7 +166,7 @@ class GLOPERATE_API RenderInterface /** * @brief - * Get the vector of all registered stencil render target inputs + * Get all registered stencil render target inputs * * @return * The vector of stencil render target inputs @@ -171,103 +175,7 @@ class GLOPERATE_API RenderInterface /** * @brief - * Get the color render target input at given index - * - * @param[in] index - * The index of the render target - * - * @return - * The color render target input at given index, 'null' if index is invalid - */ - Input * colorRenderTargetInput(size_t index) const; - - /** - * @brief - * Get the depth render target input at given index - * - * @param[in] index - * The index of the render target - * - * @return - * The depth render target input at given index, 'null' if index is invalid - */ - Input * depthRenderTargetInput(size_t index) const; - - /** - * @brief - * Get the depth-stencil render target input at given index - * - * @param[in] index - * The index of the render target - * - * @return - * The depth-stencil render target input at given index, 'null' if index is invalid - */ - Input * depthStencilRenderTargetInput(size_t index) const; - - /** - * @brief - * Get the stencil render target input at given index - * - * @param[in] index - * The index of the render target - * - * @return - * The stencil render target input at given index, 'null' if index is invalid - */ - Input * stencilRenderTargetInput(size_t index) const; - - /** - * @brief - * Get the color render target at given index - * - * @param[in] index - * The index of the render target - * - * @return - * The color render target at given index, 'null' if index is invalid - */ - ColorRenderTarget * colorRenderTarget(size_t index) const; - - /** - * @brief - * Get the depth render target at given index - * - * @param[in] index - * The index of the render target - * - * @return - * The depth render target at given index, 'null' if index is invalid - */ - DepthRenderTarget * depthRenderTarget(size_t index) const; - - /** - * @brief - * Get the depth-stencil render target at given index - * - * @param[in] index - * The index of the render target - * - * @return - * The depth-stencil render target at given index, 'null' if index is invalid - */ - DepthStencilRenderTarget * depthStencilRenderTarget(size_t index) const; - - /** - * @brief - * Get the stencil render target at given index - * - * @param[in] index - * The index of the render target - * - * @return - * The stencil render target at given index, 'null' if index is invalid - */ - StencilRenderTarget * stencilRenderTarget(size_t index) const; - - /** - * @brief - * Get the vector of all registered color render target outputs + * Get all registered color render target outputs * * @return * The vector of color render target outputs @@ -276,7 +184,7 @@ class GLOPERATE_API RenderInterface /** * @brief - * Get the vector of all registered depth render target outputs + * Get all registered depth render target outputs * * @return * The vector of depth render target outputs @@ -285,7 +193,7 @@ class GLOPERATE_API RenderInterface /** * @brief - * Get the vector of all registered depth-stencil render target outputs + * Get all registered depth-stencil render target outputs * * @return * The vector of depth-stencil render target outputs @@ -294,7 +202,7 @@ class GLOPERATE_API RenderInterface /** * @brief - * Get the vector of all registered stencil render target outputs + * Get all registered stencil render target outputs * * @return * The vector of stencil render target outputs @@ -303,130 +211,10 @@ class GLOPERATE_API RenderInterface /** * @brief - * Get the color render target output at given index - * - * @param[in] index - * The index of the render target - * - * @return - * The color render target output at given index, 'null' if index is invalid - */ - Output * colorRenderTargetOutput(size_t index) const; - - /** - * @brief - * Get the depth render target output at given index - * - * @param[in] index - * The index of the render target - * - * @return - * The depth render target output at given index, 'null' if index is invalid - */ - Output * depthRenderTargetOutput(size_t index) const; - - /** - * @brief - * Get the depth-stencil render target output at given index - * - * @param[in] index - * The index of the render target - * - * @return - * The depth render target output at given index, 'null' if index is invalid - */ - Output * depthStencilRenderTargetOutput(size_t index) const; - - /** - * @brief - * Get the stencil render target output at given index - * - * @param[in] index - * The index of the render target - * - * @return - * The stencil render target output at given index, 'null' if index is invalid - */ - Output * stencilRenderTargetOutput(size_t index) const; - - /** - * @brief - * Registers new color render target input - * - * @param[in] input - * New color render target input - */ - void addRenderTargetInput(Input * input); - - /** - * @brief - * Registers new depth render target input - * - * @param[in] input - * New depth render target input - */ - void addRenderTargetInput(Input * input); - - /** - * @brief - * Registers new depth-stencil render target input - * - * @param[in] input - * New depth-stencil render target input - */ - void addRenderTargetInput(Input * input); - - /** - * @brief - * Registers new stencil render target input - * - * @param[in] input - * New stencil render target input - */ - void addRenderTargetInput(Input * input); - - /** - * @brief - * Registers new color render target output - * - * @param[in] input - * New render color target output - */ - void addRenderTargetOutput(Output * output); - - /** - * @brief - * Registers new depth render target output - * - * @param[in] input - * New render depth target output - */ - void addRenderTargetOutput(Output * output); - - /** - * @brief - * Registers new depth-stencil render target output - * - * @param[in] input - * New render depth-stencil target output - */ - void addRenderTargetOutput(Output * output); - - /** - * @brief - * Registers new stencil render target output - * - * @param[in] input - * New render stencil target output - */ - void addRenderTargetOutput(Output * output); - - /** - * @brief - * Iterate over all pairs of color render target inputs and outputs and call the callback + * Call function on each pair of color render target inputs and outputs * * @param[in] callback - * The callback + * Callback function * @param[in] includeIncompletePairs * If 'true', also incomplete pairs are passed to the callback (i.e., either input or output is 'null') */ @@ -434,10 +222,10 @@ class GLOPERATE_API RenderInterface /** * @brief - * Iterate over all pairs of depth render target inputs and outputs and call the callback + * Call function on each pair of depth render target inputs and outputs * * @param[in] callback - * The callback + * Callback function * @param[in] includeIncompletePairs * If 'true', also incomplete pairs are passed to the callback (i.e., either input or output is 'null') */ @@ -445,10 +233,10 @@ class GLOPERATE_API RenderInterface /** * @brief - * Iterate over all pairs of depth-stencil render target inputs and outputs and call the callback + * Call function on each pair of depth-stencil render target inputs and outputs * * @param[in] callback - * The callback + * Callback function * @param[in] includeIncompletePairs * If 'true', also incomplete pairs are passed to the callback (i.e., either input or output is 'null') */ @@ -456,10 +244,10 @@ class GLOPERATE_API RenderInterface /** * @brief - * Iterate over all pairs of stencil render target inputs and outputs and call the callback + * Call function on each pair of stencil render target inputs and outputs * * @param[in] callback - * The callback + * Callback function * @param[in] includeIncompletePairs * If 'true', also incomplete pairs are passed to the callback (i.e., either input or output is 'null') */ @@ -484,6 +272,26 @@ class GLOPERATE_API RenderInterface void onContextDeinit(); +protected: + /** + * @brief + * Register render target input + * + * @param[in] input + * Render target input (must NOT be null!) + */ + void registerRenderTargetInput(AbstractSlot * input); + + /** + * @brief + * Register render target output + * + * @param[in] output + * Render target output (must NOT be null!) + */ + void registerRenderTargetOutput(AbstractSlot * output); + + protected: std::unique_ptr m_defaultFBO; ///< Default FBO for configuration std::unique_ptr m_fbo; ///< Intermediate FBO for configuration diff --git a/source/gloperate/source/rendering/ColorRenderTarget.cpp b/source/gloperate/source/rendering/ColorRenderTarget.cpp index 64b1f699..96a4f9a0 100644 --- a/source/gloperate/source/rendering/ColorRenderTarget.cpp +++ b/source/gloperate/source/rendering/ColorRenderTarget.cpp @@ -11,7 +11,7 @@ namespace gloperate { -AttachmentType ColorRenderTarget::underlyingAttachmentType() const +AttachmentType ColorRenderTarget::attachmentType() const { return AttachmentType::Color; } diff --git a/source/gloperate/source/rendering/DepthRenderTarget.cpp b/source/gloperate/source/rendering/DepthRenderTarget.cpp index 4900b3b1..0603384f 100644 --- a/source/gloperate/source/rendering/DepthRenderTarget.cpp +++ b/source/gloperate/source/rendering/DepthRenderTarget.cpp @@ -10,7 +10,7 @@ namespace gloperate { -AttachmentType DepthRenderTarget::underlyingAttachmentType() const +AttachmentType DepthRenderTarget::attachmentType() const { return AttachmentType::Depth; } diff --git a/source/gloperate/source/rendering/DepthStencilRenderTarget.cpp b/source/gloperate/source/rendering/DepthStencilRenderTarget.cpp index 0de9f4b2..b18b2588 100644 --- a/source/gloperate/source/rendering/DepthStencilRenderTarget.cpp +++ b/source/gloperate/source/rendering/DepthStencilRenderTarget.cpp @@ -10,7 +10,7 @@ namespace gloperate { -AttachmentType DepthStencilRenderTarget::underlyingAttachmentType() const +AttachmentType DepthStencilRenderTarget::attachmentType() const { return AttachmentType::DepthStencil; } diff --git a/source/gloperate/source/rendering/StencilRenderTarget.cpp b/source/gloperate/source/rendering/StencilRenderTarget.cpp index 6f7196b8..23565f07 100644 --- a/source/gloperate/source/rendering/StencilRenderTarget.cpp +++ b/source/gloperate/source/rendering/StencilRenderTarget.cpp @@ -10,7 +10,7 @@ namespace gloperate { -AttachmentType StencilRenderTarget::underlyingAttachmentType() const +AttachmentType StencilRenderTarget::attachmentType() const { return AttachmentType::Stencil; } diff --git a/source/gloperate/source/stages/base/ClearStage.cpp b/source/gloperate/source/stages/base/ClearStage.cpp index b9863198..c8d0bac9 100644 --- a/source/gloperate/source/stages/base/ClearStage.cpp +++ b/source/gloperate/source/stages/base/ClearStage.cpp @@ -117,7 +117,7 @@ void ClearStage::onProcess() return; } - if ((**input)->underlyingAttachmentType() == AttachmentType::Depth) + if ((**input)->attachmentType() == AttachmentType::Depth) { if (m_depthValueInputs.size() <= depthAttachmentIndex) { @@ -130,7 +130,7 @@ void ClearStage::onProcess() ++depthAttachmentIndex; } - else if ((**input)->underlyingAttachmentType() == AttachmentType::DepthStencil) + else if ((**input)->attachmentType() == AttachmentType::DepthStencil) { if (m_depthStencilValueInputs.size() <= depthStencilAttachmentIndex) { @@ -152,7 +152,7 @@ void ClearStage::onProcess() return; } - if ((**input)->underlyingAttachmentType() == AttachmentType::Stencil) + if ((**input)->attachmentType() == AttachmentType::Stencil) { if (m_stencilValueInputs.size() <= stencilAttachmentIndex) { @@ -165,7 +165,7 @@ void ClearStage::onProcess() ++stencilAttachmentIndex; } - else if ((**input)->underlyingAttachmentType() == AttachmentType::DepthStencil) + else if ((**input)->attachmentType() == AttachmentType::DepthStencil) { if (std::find(clearedDepthStencilTargets.begin(), clearedDepthStencilTargets.end(), **input) != clearedDepthStencilTargets.end()) { diff --git a/source/gloperate/source/stages/base/RasterizationStage.cpp b/source/gloperate/source/stages/base/RasterizationStage.cpp index 176b73a5..c2cab67d 100644 --- a/source/gloperate/source/stages/base/RasterizationStage.cpp +++ b/source/gloperate/source/stages/base/RasterizationStage.cpp @@ -39,7 +39,7 @@ void RasterizationStage::onContextDeinit(AbstractGLContext *) void RasterizationStage::onProcess() { - if (!renderInterface.allRenderTargetsCompatible()) + if (!renderInterface.renderTargetsAreCompatible()) { cppassist::warning("gloperate") << "Framebuffer attachments not compatible"; diff --git a/source/gloperate/source/stages/interfaces/RenderInterface.cpp b/source/gloperate/source/stages/interfaces/RenderInterface.cpp index 2a2f5295..4b9be255 100644 --- a/source/gloperate/source/stages/interfaces/RenderInterface.cpp +++ b/source/gloperate/source/stages/interfaces/RenderInterface.cpp @@ -27,213 +27,136 @@ RenderInterface::RenderInterface(Stage * stage) // Hide inputs in property editor viewport.setOption("hidden", true); - stage->inputAdded.connect( [this] (AbstractSlot * connectedInput) { - auto colorRenderTargetInput = dynamic_cast *>(connectedInput); - auto depthRenderTargetInput = dynamic_cast *>(connectedInput); - auto depthStencilRenderTargetInput = dynamic_cast *>(connectedInput); - auto stencilRenderTargetInput = dynamic_cast *>(connectedInput); - - if (colorRenderTargetInput) - { - addRenderTargetInput(colorRenderTargetInput); - } - - if (depthRenderTargetInput) - { - addRenderTargetInput(depthRenderTargetInput); - } - - if (depthStencilRenderTargetInput) - { - addRenderTargetInput(depthStencilRenderTargetInput); - } - - if (stencilRenderTargetInput) - { - addRenderTargetInput(stencilRenderTargetInput); - } - }); - - stage->outputAdded.connect( [this] (AbstractSlot * connectedOutput) { - auto colorRenderTargetOutput = dynamic_cast *>(connectedOutput); - auto depthRenderTargetOutput = dynamic_cast *>(connectedOutput); - auto depthStencilRenderTargetOutput = dynamic_cast *>(connectedOutput); - auto stencilRenderTargetOutput = dynamic_cast *>(connectedOutput); - - if (colorRenderTargetOutput) - { - addRenderTargetOutput(colorRenderTargetOutput); - } - - if (depthRenderTargetOutput) - { - addRenderTargetOutput(depthRenderTargetOutput); - } - - if (depthStencilRenderTargetOutput) - { - addRenderTargetOutput(depthStencilRenderTargetOutput); - } - - if (stencilRenderTargetOutput) - { - addRenderTargetOutput(stencilRenderTargetOutput); - } - }); + // Pick up new render target inputs and outputs + stage->inputAdded .connect(this, &RenderInterface::registerRenderTargetInput); + stage->outputAdded.connect(this, &RenderInterface::registerRenderTargetOutput); } RenderInterface::~RenderInterface() { } -void RenderInterface::updateRenderTargetOutputs() { - pairwiseRenderTargetsDo([](Input * input, Output * output) { +void RenderInterface::updateRenderTargetOutputs() +{ + // Set output of each render target to signal an update to the pipeline + pairwiseRenderTargetsDo([](Input * input, Output * output) + { output->setValue(**input); }); - pairwiseRenderTargetsDo([](Input * input, Output * output) { + + pairwiseRenderTargetsDo([](Input * input, Output * output) + { output->setValue(**input); }); - pairwiseRenderTargetsDo([](Input * input, Output * output) { + + pairwiseRenderTargetsDo([](Input * input, Output * output) + { output->setValue(**input); }); - pairwiseRenderTargetsDo([](Input * input, Output * output) { + + pairwiseRenderTargetsDo([](Input * input, Output * output) + { output->setValue(**input); }); } -bool RenderInterface::allRenderTargetsCompatible() const +bool RenderInterface::renderTargetsAreCompatible() const { + // Quick exit if no render targets are registered if (m_colorRenderTargetInputs.empty() && m_depthRenderTargetInputs.empty() && m_depthStencilRenderTargetInputs.empty() && m_stencilRenderTargetInputs.empty()) { return true; } + // Get number of depth and stencil attachments auto numberOfDepthAttachments = m_depthRenderTargetOutputs.size() + m_depthStencilRenderTargetOutputs.size(); auto numberOfStencilAttachments = m_depthStencilRenderTargetOutputs.size() + m_stencilRenderTargetOutputs.size(); + // Determine if all render targets refer to the default FBO auto allDefaultFramebufferAttachments = - std::all_of(m_colorRenderTargetInputs.begin(), m_colorRenderTargetInputs.end(), [](Input * input) { - if (input == nullptr) - { - return true; - } + std::all_of(m_colorRenderTargetInputs.begin(), m_colorRenderTargetInputs.end(), [] (Input * input) + { + if (input == nullptr) return true; auto renderTarget = **input; - - if (renderTarget == nullptr) - { - return true; - } + if (renderTarget == nullptr) return true; return !renderTarget->attachmentRequiresUserDefinedFramebuffer(); }) - && std::all_of(m_depthRenderTargetInputs.begin(), m_depthRenderTargetInputs.end(), [](Input * input) { - if (input == nullptr) - { - return true; - } - auto renderTarget = **input; + && std::all_of(m_depthRenderTargetInputs.begin(), m_depthRenderTargetInputs.end(), [] (Input * input) + { + if (input == nullptr) return true; - if (renderTarget == nullptr) - { - return true; - } + auto renderTarget = **input; + if (renderTarget == nullptr) return true; return !renderTarget->attachmentRequiresUserDefinedFramebuffer(); }) - && std::all_of(m_depthStencilRenderTargetInputs.begin(), m_depthStencilRenderTargetInputs.end(), [](Input * input) { - if (input == nullptr) - { - return true; - } - auto renderTarget = **input; + && std::all_of(m_depthStencilRenderTargetInputs.begin(), m_depthStencilRenderTargetInputs.end(), [] (Input * input) + { + if (input == nullptr) return true; - if (renderTarget == nullptr) - { - return true; - } + auto renderTarget = **input; + if (renderTarget == nullptr) return true; return !renderTarget->attachmentRequiresUserDefinedFramebuffer(); }) - && std::all_of(m_stencilRenderTargetInputs.begin(), m_stencilRenderTargetInputs.end(), [](Input * input) { - if (input == nullptr) - { - return true; - } - auto renderTarget = **input; + && std::all_of(m_stencilRenderTargetInputs.begin(), m_stencilRenderTargetInputs.end(), [] (Input * input) + { + if (input == nullptr) return true; - if (renderTarget == nullptr) - { - return true; - } + auto renderTarget = **input; + if (renderTarget == nullptr) return true; return !renderTarget->attachmentRequiresUserDefinedFramebuffer(); }); - auto allUserDefinedFramebufferAttachments = std::all_of(m_colorRenderTargetInputs.begin(), m_colorRenderTargetInputs.end(), [](Input * input) { - if (input == nullptr) - { - return true; - } + // Determine if all render targets require a user-defined FBO + auto allUserDefinedFramebufferAttachments = + std::all_of(m_colorRenderTargetInputs.begin(), m_colorRenderTargetInputs.end(), [] (Input * input) + { + if (input == nullptr) return true; auto renderTarget = **input; - - if (renderTarget == nullptr) - { - return true; - } + if (renderTarget == nullptr) return true; return renderTarget->attachmentRequiresUserDefinedFramebuffer(); }) - && std::all_of(m_depthRenderTargetInputs.begin(), m_depthRenderTargetInputs.end(), [](Input * input) { - if (input == nullptr) - { - return true; - } - auto renderTarget = **input; + && std::all_of(m_depthRenderTargetInputs.begin(), m_depthRenderTargetInputs.end(), [](Input * input) + { + if (input == nullptr) return true; - if (renderTarget == nullptr) - { - return true; - } + auto renderTarget = **input; + if (renderTarget == nullptr) return true; return renderTarget->attachmentRequiresUserDefinedFramebuffer(); }) - && std::all_of(m_depthStencilRenderTargetInputs.begin(), m_depthStencilRenderTargetInputs.end(), [](Input * input) { - if (input == nullptr) - { - return true; - } - auto renderTarget = **input; + && std::all_of(m_depthStencilRenderTargetInputs.begin(), m_depthStencilRenderTargetInputs.end(), [](Input * input) + { + if (input == nullptr) return true; - if (renderTarget == nullptr) - { - return true; - } + auto renderTarget = **input; + if (renderTarget == nullptr) return true; return renderTarget->attachmentRequiresUserDefinedFramebuffer(); }) - && std::all_of(m_stencilRenderTargetInputs.begin(), m_stencilRenderTargetInputs.end(), [](Input * input) { - if (input == nullptr) - { - return true; - } - auto renderTarget = **input; + && std::all_of(m_stencilRenderTargetInputs.begin(), m_stencilRenderTargetInputs.end(), [](Input * input) + { + if (input == nullptr) return true; - if (renderTarget == nullptr) - { - return true; - } + auto renderTarget = **input; + if (renderTarget == nullptr) return true; return renderTarget->attachmentRequiresUserDefinedFramebuffer(); }); + // [TODO] Check this condition. If I add the default color-buffer and a user-defined depth buffer, wouldn't both bools be false, hence equal? return allDefaultFramebufferAttachments != allUserDefinedFramebufferAttachments && numberOfDepthAttachments <= 1 && numberOfStencilAttachments <= 1; } @@ -257,54 +180,6 @@ const std::vector *> & RenderInterface::stencilRend return m_stencilRenderTargetInputs; } -Input * RenderInterface::colorRenderTargetInput(size_t index) const -{ - return m_colorRenderTargetInputs.size() > index ? m_colorRenderTargetInputs.at(index) : nullptr; -} - -Input * RenderInterface::depthRenderTargetInput(size_t index) const -{ - return m_depthRenderTargetInputs.size() > index ? m_depthRenderTargetInputs.at(index) : nullptr; -} - -Input * RenderInterface::depthStencilRenderTargetInput(size_t index) const -{ - return m_depthStencilRenderTargetInputs.size() > index ? m_depthStencilRenderTargetInputs.at(index) : nullptr; -} - -Input * RenderInterface::stencilRenderTargetInput(size_t index) const -{ - return m_stencilRenderTargetInputs.size() > index ? m_stencilRenderTargetInputs.at(index) : nullptr; -} - -ColorRenderTarget * RenderInterface::colorRenderTarget(size_t index) const -{ - const auto input = colorRenderTargetInput(index); - - return input ? **input : nullptr; -} - -DepthRenderTarget * RenderInterface::depthRenderTarget(size_t index) const -{ - const auto input = depthRenderTargetInput(index); - - return input ? **input : nullptr; -} - -DepthStencilRenderTarget * RenderInterface::depthStencilRenderTarget(size_t index) const -{ - const auto input = depthStencilRenderTargetInput(index); - - return input ? **input : nullptr; -} - -StencilRenderTarget * RenderInterface::stencilRenderTarget(size_t index) const -{ - const auto input = stencilRenderTargetInput(index); - - return input ? **input : nullptr; -} - const std::vector *> & RenderInterface::colorRenderTargetOutputs() const { return m_colorRenderTargetOutputs; @@ -325,66 +200,6 @@ const std::vector *> & RenderInterface::stencilRen return m_stencilRenderTargetOutputs; } -Output * RenderInterface::colorRenderTargetOutput(size_t index) const -{ - return m_colorRenderTargetOutputs.size() > index ? m_colorRenderTargetOutputs.at(index) : nullptr; -} - -Output * RenderInterface::depthRenderTargetOutput(size_t index) const -{ - return m_depthRenderTargetOutputs.size() > index ? m_depthRenderTargetOutputs.at(index) : nullptr; -} - -Output * RenderInterface::depthStencilRenderTargetOutput(size_t index) const -{ - return m_depthStencilRenderTargetOutputs.size() > index ? m_depthStencilRenderTargetOutputs.at(index) : nullptr; -} - -Output * RenderInterface::stencilRenderTargetOutput(size_t index) const -{ - return m_stencilRenderTargetOutputs.size() > index ? m_stencilRenderTargetOutputs.at(index) : nullptr; -} - -void RenderInterface::addRenderTargetInput(Input * input) -{ - m_colorRenderTargetInputs.push_back(input); -} - -void RenderInterface::addRenderTargetInput(Input * input) -{ - m_depthRenderTargetInputs.push_back(input); -} - -void RenderInterface::addRenderTargetInput(Input * input) -{ - m_depthStencilRenderTargetInputs.push_back(input); -} - -void RenderInterface::addRenderTargetInput(Input * input) -{ - m_stencilRenderTargetInputs.push_back(input); -} - -void RenderInterface::addRenderTargetOutput(Output * input) -{ - m_colorRenderTargetOutputs.push_back(input); -} - -void RenderInterface::addRenderTargetOutput(Output * input) -{ - m_depthRenderTargetOutputs.push_back(input); -} - -void RenderInterface::addRenderTargetOutput(Output * input) -{ - m_depthStencilRenderTargetOutputs.push_back(input); -} - -void RenderInterface::addRenderTargetOutput(Output * input) -{ - m_stencilRenderTargetOutputs.push_back(input); -} - void RenderInterface::pairwiseRenderTargetsDo(std::function *, Output *)> callback, bool includeIncompletePairs) { const auto end = includeIncompletePairs @@ -393,7 +208,10 @@ void RenderInterface::pairwiseRenderTargetsDo(std::function i ? m_colorRenderTargetInputs.at(i) : nullptr, + m_colorRenderTargetOutputs.size() > i ? m_colorRenderTargetOutputs.at(i) : nullptr + ); } } @@ -405,7 +223,10 @@ void RenderInterface::pairwiseRenderTargetsDo(std::function i ? m_depthRenderTargetInputs.at(i) : nullptr, + m_depthRenderTargetOutputs.size() > i ? m_depthRenderTargetOutputs.at(i) : nullptr + ); } } @@ -417,7 +238,10 @@ void RenderInterface::pairwiseRenderTargetsDo(std::function i ? m_depthStencilRenderTargetInputs.at(i) : nullptr, + m_depthStencilRenderTargetOutputs.size() > i ? m_depthStencilRenderTargetOutputs.at(i) : nullptr + ); } } @@ -429,17 +253,21 @@ void RenderInterface::pairwiseRenderTargetsDo(std::function i ? m_stencilRenderTargetInputs.at(i) : nullptr, + m_stencilRenderTargetOutputs.size() > i ? m_stencilRenderTargetOutputs.at(i) : nullptr + ); } } globjects::Framebuffer * RenderInterface::obtainFBO() const { - assert(allRenderTargetsCompatible()); + assert(renderTargetsAreCompatible()); std::vector drawBuffers; globjects::Framebuffer * currentFBO = nullptr; auto colorAttachmentIndex = size_t(0); + for (auto input : m_colorRenderTargetInputs) { auto nextFBO = obtainFBO(colorAttachmentIndex, **input); @@ -525,17 +353,17 @@ globjects::Framebuffer * RenderInterface::obtainFBO(size_t index, AbstractRender { auto attachmentIndex = gl::GL_COLOR_ATTACHMENT0 + index; - if (renderTarget->underlyingAttachmentType() == AttachmentType::Depth) + if (renderTarget->attachmentType() == AttachmentType::Depth) { attachmentIndex = gl::GL_DEPTH_ATTACHMENT; } - if (renderTarget->underlyingAttachmentType() == AttachmentType::Stencil) + else if (renderTarget->attachmentType() == AttachmentType::Stencil) { attachmentIndex = gl::GL_STENCIL_ATTACHMENT; } - if (renderTarget->underlyingAttachmentType() == AttachmentType::DepthStencil) + else if (renderTarget->attachmentType() == AttachmentType::DepthStencil) { attachmentIndex = gl::GL_DEPTH_STENCIL_ATTACHMENT; } @@ -546,66 +374,63 @@ globjects::Framebuffer * RenderInterface::obtainFBO(size_t index, AbstractRender return defaultFBO; case RenderTargetType::UserDefinedFBOAttachment: - { - const auto fboAttachment = fbo->getAttachment(attachmentIndex); - const auto targetAttachment = renderTarget->framebufferAttachment(); + { + const auto fboAttachment = fbo->getAttachment(attachmentIndex); + const auto targetAttachment = renderTarget->framebufferAttachment(); - const auto targetAttachedTexture = static_cast(targetAttachment); - const auto targetAttachedRenderbuffer = static_cast(targetAttachment); - const auto fboAttachedTexture = static_cast(fboAttachment); - const auto fboAttachedRenderbuffer = static_cast(fboAttachment); + const auto targetAttachedTexture = static_cast(targetAttachment); + const auto targetAttachedRenderbuffer = static_cast(targetAttachment); + const auto fboAttachedTexture = static_cast(fboAttachment); + const auto fboAttachedRenderbuffer = static_cast(fboAttachment); - if (!fboAttachment) - { - if (targetAttachment->isTextureAttachment()) - { - fbo->attachTexture(attachmentIndex, targetAttachedTexture->texture()); - } - else - { - fbo->attachRenderBuffer(attachmentIndex, targetAttachedRenderbuffer->renderBuffer()); - } - } - else if (fboAttachment->isTextureAttachment() && (!targetAttachment->isTextureAttachment() || fboAttachedTexture->texture() != targetAttachedTexture->texture())) + if (!fboAttachment) + { + if (targetAttachment->isTextureAttachment()) { fbo->attachTexture(attachmentIndex, targetAttachedTexture->texture()); } - else if (fboAttachment->isRenderBufferAttachment() && (!targetAttachment->isRenderBufferAttachment() || fboAttachedRenderbuffer->renderBuffer() != targetAttachedRenderbuffer->renderBuffer())) + else { fbo->attachRenderBuffer(attachmentIndex, targetAttachedRenderbuffer->renderBuffer()); } - - return fbo; } - break; - - case RenderTargetType::Texture: + else if (fboAttachment->isTextureAttachment() && (!targetAttachment->isTextureAttachment() || fboAttachedTexture->texture() != targetAttachedTexture->texture())) { - const auto attachment = fbo->getAttachment(attachmentIndex); + fbo->attachTexture(attachmentIndex, targetAttachedTexture->texture()); + } + else if (fboAttachment->isRenderBufferAttachment() && (!targetAttachment->isRenderBufferAttachment() || fboAttachedRenderbuffer->renderBuffer() != targetAttachedRenderbuffer->renderBuffer())) + { + fbo->attachRenderBuffer(attachmentIndex, targetAttachedRenderbuffer->renderBuffer()); + } - const auto attachedTexture = static_cast(attachment); - if (!attachment || !attachment->isTextureAttachment() || attachedTexture->texture() != renderTarget->textureAttachment()) - { - fbo->attachTexture(attachmentIndex, renderTarget->textureAttachment()); - } + return fbo; + } - return fbo; - } - break; + case RenderTargetType::Texture: + { + const auto attachment = fbo->getAttachment(attachmentIndex); - case RenderTargetType::Renderbuffer: + const auto attachedTexture = static_cast(attachment); + if (!attachment || !attachment->isTextureAttachment() || attachedTexture->texture() != renderTarget->textureAttachment()) { - const auto attachment = fbo->getAttachment(attachmentIndex); + fbo->attachTexture(attachmentIndex, renderTarget->textureAttachment()); + } - const auto attachedRenderbuffer = static_cast(attachment); - if (!attachment->isRenderBufferAttachment() || attachedRenderbuffer->renderBuffer() != renderTarget->renderbufferAttachment()) - { - fbo->attachRenderBuffer(attachmentIndex, renderTarget->renderbufferAttachment()); - } + return fbo; + } - return fbo; + case RenderTargetType::Renderbuffer: + { + const auto attachment = fbo->getAttachment(attachmentIndex); + + const auto attachedRenderbuffer = static_cast(attachment); + if (!attachment->isRenderBufferAttachment() || attachedRenderbuffer->renderBuffer() != renderTarget->renderbufferAttachment()) + { + fbo->attachRenderBuffer(attachmentIndex, renderTarget->renderbufferAttachment()); } - break; + + return fbo; + } default: return nullptr; @@ -615,13 +440,67 @@ globjects::Framebuffer * RenderInterface::obtainFBO(size_t index, AbstractRender void RenderInterface::onContextInit() { m_defaultFBO = globjects::Framebuffer::defaultFBO(); - m_fbo = cppassist::make_unique(); + m_fbo = cppassist::make_unique(); } void RenderInterface::onContextDeinit() { m_defaultFBO = nullptr; - m_fbo = nullptr; + m_fbo = nullptr; +} + +void RenderInterface::registerRenderTargetInput(AbstractSlot * input) +{ + if (auto colorRenderTargetInput = dynamic_cast *>(input)) + { + m_colorRenderTargetInputs.push_back(colorRenderTargetInput); + return; + } + + if (auto depthRenderTargetInput = dynamic_cast *>(input)) + { + m_depthRenderTargetInputs.push_back(depthRenderTargetInput); + return; + } + + if (auto depthStencilRenderTargetInput = dynamic_cast *>(input)) + { + m_depthStencilRenderTargetInputs.push_back(depthStencilRenderTargetInput); + return; + } + + if (auto stencilRenderTargetInput = dynamic_cast *>(input)) + { + m_stencilRenderTargetInputs.push_back(stencilRenderTargetInput); + return; + } +} + +void RenderInterface::registerRenderTargetOutput(AbstractSlot * output) +{ + if (auto colorRenderTargetOutput = dynamic_cast *>(output)) + { + m_colorRenderTargetOutputs.push_back(colorRenderTargetOutput); + return; + } + + if (auto depthRenderTargetOutput = dynamic_cast *>(output)) + { + m_depthRenderTargetOutputs.push_back(depthRenderTargetOutput); + return; + } + + if (auto depthStencilRenderTargetOutput = dynamic_cast *>(output)) + { + m_depthStencilRenderTargetOutputs.push_back(depthStencilRenderTargetOutput); + return; + } + + if (auto stencilRenderTargetOutput = dynamic_cast *>(output)) + { + m_stencilRenderTargetOutputs.push_back(stencilRenderTargetOutput); + return; + } } From 9ade1fe9957794d868361cef135185e551354245 Mon Sep 17 00:00:00 2001 From: Stefan Buschmann Date: Sun, 16 Jul 2017 16:29:41 +0200 Subject: [PATCH 2/2] Fix bug in blit stage if render target is invalid. We must *never* assume that an input contains a valid value, and always check for nullptr values --- source/gloperate/source/stages/base/BlitStage.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/gloperate/source/stages/base/BlitStage.cpp b/source/gloperate/source/stages/base/BlitStage.cpp index 62c7bdae..06d89e1b 100644 --- a/source/gloperate/source/stages/base/BlitStage.cpp +++ b/source/gloperate/source/stages/base/BlitStage.cpp @@ -40,6 +40,7 @@ void BlitStage::onContextDeinit(AbstractGLContext * /*context*/) void BlitStage::onProcess() { + // Omit blit if source and target are identical if (*source == *target) { targetOut.setValue(*target); @@ -47,6 +48,12 @@ void BlitStage::onProcess() return; } + // Abort if source or target are invalid + if (!*source || !*target) + { + return; + } + std::array sourceRect = {{ static_cast((*sourceViewport).x), static_cast((*sourceViewport).y),