Commit 51764877 authored by schultezub's avatar schultezub

More work on IxpvDemo pipeline:

 * Introducing RenderTargetCompositor
 * fixed DRRRaycaster


git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@388 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 4f18b0b6
......@@ -61,25 +61,14 @@ namespace campvis {
}
void DevilImageReader::process(DataContainer& data) {
try {
tgt::Texture* tex = _devilTextureReader->loadTexture(p_url.getValue(), tgt::Texture::LINEAR, false, true, true, false);
if (tex == 0) {
LERROR("Unknown error while loading image.");
return;
}
// all parsing done - lets create the image:
tgt::Texture* tex = _devilTextureReader->loadTexture(p_url.getValue(), tgt::Texture::LINEAR, false, true, true, false);
if (tex != 0) {
ImageDataGL* image = ImageDataGL::createFromTexture(tex);
data.addData(p_targetImageID.getValue(), image);
p_targetImageID.issueWrite();
}
catch (tgt::Exception& e) {
LERROR("Error while loading image: " << e.what());
return;
}
catch (std::exception& e) {
LERROR("Error while loading image: " << e.what());
return;
else {
LERROR("Could not load image.");
}
_invalidationLevel.setValid();
......
......@@ -44,8 +44,7 @@ uniform Texture2D _entryPoints; // ray entry points
uniform Texture2D _exitPoints; // ray exit points
uniform Texture3D _volume; // texture lookup parameters for volume_
uniform sampler1D _tfTex;
uniform TFParameters _tfTextureParameters;
uniform TransferFunction1D _transferFunction;
uniform float _samplingStepSize;
uniform float _shift;
......@@ -70,9 +69,12 @@ vec4 raycastDRR(in vec3 entryPoint, in vec3 exitPoint) {
jitterEntryPoint(entryPoint, direction, _samplingStepSize * _jitterStepSizeMultiplier);
while (t < tend) {
// compute sample position
vec3 samplePosition = entryPoint.rgb + t * direction;
vec4 voxel = getElement3DNormalized(_volume, samplePosition);
vec4 color = lookupTF(_tfTextureParameters, _tfTex, voxel.a);
// lookup intensity and TF
float intensity = getElement3DNormalized(_volume, samplePosition).a;
vec4 color = lookupTF(_transferFunction, intensity);
#ifdef DEPTH_MAPPING
// use Bernstein Polynomials for depth-color mapping
......@@ -101,9 +103,6 @@ vec4 raycastDRR(in vec3 entryPoint, in vec3 exitPoint) {
t += _samplingStepSize;
}
// DRR images don't have a meaningful depth value
gl_FragDepth = 1.0;
#ifdef DEPTH_MAPPING
result.rgb = result.rgb * vec3(exp(-result.a + _shift));
//result.rgb = exp(-result.rgb * result.a + shift_);
......
/**********************************************************************
* *
* Voreen - The Volume Rendering Engine *
* *
* Copyright (C) 2005-2012 Visualization and Computer Graphics Group, *
* Department of Computer Science, University of Muenster, Germany. *
* <http://viscg.uni-muenster.de> *
* *
* This file is part of the Voreen software package. Voreen is free *
* software: you can redistribute it and/or modify it under the terms *
* of the GNU General Public License version 2 as published by the *
* Free Software Foundation. *
* *
* Voreen is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* in the file "LICENSE.txt" along with this program. *
* If not, see <http://www.gnu.org/licenses/>. *
* *
* The authors reserve all rights not expressly granted herein. For *
* non-commercial academic use see the license exception specified in *
* the file "LICENSE-academic.txt". To get information about *
* commercial licensing please contact the authors. *
* *
**********************************************************************/
#version 330
in vec3 ex_TexCoord;
out vec4 out_Color;
#include "tools/texture2d.frag"
#include "tools/background.frag"
uniform Texture2D _firstColor;
uniform Texture2D _firstDepth;
uniform Texture2D _secondColor;
uniform Texture2D _secondDepth;
uniform int _compositingMethod;
uniform float _alpha;
void main() {
if (_compositingMethod == 0) {
// only first
out_Color = getElement2DNormalized(_firstColor, ex_TexCoord.xy);
gl_FragDepth = getElement2DNormalized(_firstDepth, ex_TexCoord.xy).z;
}
else if (_compositingMethod == 1) {
// only second
out_Color = getElement2DNormalized(_secondColor, ex_TexCoord.xy);
gl_FragDepth = getElement2DNormalized(_secondDepth, ex_TexCoord.xy).z;
}
else if (_compositingMethod == 2) {
// alpha blending
vec4 firstColor = getElement2DNormalized(_firstColor, ex_TexCoord.xy);
float firstDepth = getElement2DNormalized(_firstDepth, ex_TexCoord.xy).z;
vec4 secondColor = getElement2DNormalized(_secondColor, ex_TexCoord.xy);
float secondDepth = getElement2DNormalized(_secondDepth, ex_TexCoord.xy).z;
out_Color = mix(firstColor, secondColor, _alpha);
gl_FragDepth = min(firstDepth, secondDepth);
}
if (out_Color.a == 0) {
renderBackground(ex_TexCoord.xy, out_Color);
}
}
......@@ -30,6 +30,7 @@
#include "ixpvdemo.h"
#include "tgt/event/keyevent.h"
#include "tgt/qt/qtcontextmanager.h"
#include "core/datastructures/imagedataconverter.h"
#include "core/classification/geometry1dtransferfunction.h"
#include "core/classification/tfgeometry1d.h"
......@@ -40,68 +41,161 @@ namespace campvis {
: VisualizationPipeline()
, _xrayReader()
, _ctReader()
, _ctProxy()
, _ctFullEEP(_effectiveRenderTargetSize)
, _ctClippedEEP(_effectiveRenderTargetSize)
, _ctFullDRR(_effectiveRenderTargetSize)
, _ctClippedDRR(_effectiveRenderTargetSize)
, _usReader()
, _usSliceExtractor(_effectiveRenderTargetSize)
, _wheelHandler(&_usSliceExtractor.p_sliceNumber)
, _tfWindowingHandler(&_usSliceExtractor.p_transferFunction)
, _compositor(_effectiveRenderTargetSize)
, _camera("camera", "Camera")
, _trackballHandler(0)
{
addProcessor(&_xrayReader);
addProcessor(&_ctReader);
addProcessor(&_ctProxy);
addProcessor(&_ctFullEEP);
addProcessor(&_ctClippedEEP);
addProcessor(&_ctFullDRR);
addProcessor(&_ctClippedDRR);
addProcessor(&_usReader);
addProcessor(&_usSliceExtractor);
addEventHandler(&_wheelHandler);
addEventHandler(&_tfWindowingHandler);
addProcessor(&_compositor);
addProperty(&_camera);
_trackballHandler = new TrackballNavigationEventHandler(this, &_camera, _renderTargetSize);
addEventHandler(_trackballHandler);
//addEventHandler(&_tfWindowingHandler);
}
IxpvDemo::~IxpvDemo() {
delete _trackballHandler;
}
void IxpvDemo::init() {
VisualizationPipeline::init();
// = Camera Setup =================================================================================
_camera.addSharedProperty(&_ctFullEEP.p_camera);
_camera.addSharedProperty(&_ctClippedEEP.p_camera);
_camera.addSharedProperty(&_ctFullDRR.p_camera);
_camera.addSharedProperty(&_ctClippedDRR.p_camera);
// = X-Ray Setup ==================================================================================
_xrayReader.p_url.setValue("D:\\Medical Data\\XrayDepthPerception\\DataCowLeg\\Cowleg_CarmXrayImages\\APView_1.jpg");
_xrayReader.p_targetImageID.setValue("xray");
_xrayReader.p_targetImageID.setValue("xray.image");
_usSliceExtractor.p_sliceNumber.setValue(0);
// = CT Setup =====================================================================================
_ctReader.p_url.setValue("D:\\Medical Data\\XrayDepthPerception\\DataCowLeg\\Cowleg_CT_8007_003_5mm_STD_20110224\\Fantome_20110224_8007_003_6_1_ABD-_portalvens_X_S___5mm_STD.mhd");
_ctReader.p_targetImageID.setValue("ct.image");
_ctReader.p_targetImageID.connect(&_ctProxy.p_sourceImageID);
_ctReader.p_targetImageID.connect(&_ctFullEEP.p_sourceImageID);
_ctReader.p_targetImageID.connect(&_ctClippedEEP.p_sourceImageID);
_ctReader.p_targetImageID.connect(&_ctFullDRR.p_sourceImageID);
_ctReader.p_targetImageID.connect(&_ctClippedDRR.p_sourceImageID);
_ctProxy.p_geometryID.setValue("ct.proxy");
_ctProxy.p_geometryID.connect(&_ctFullEEP.p_geometryID);
_ctProxy.p_geometryID.connect(&_ctClippedEEP.p_geometryID);
_ctFullEEP.p_entryImageID.setValue("ct.entry.full");
_ctFullEEP.p_entryImageID.connect(&_ctFullDRR.p_entryImageID);
_ctFullEEP.p_exitImageID.setValue("ct.exit.full");
_ctFullEEP.p_exitImageID.connect(&_ctFullDRR.p_exitImageID);
// TODO: replace this hardcoded domain by automatically determined from image min/max values
Geometry1DTransferFunction* tf = new Geometry1DTransferFunction(128, tgt::vec2(0.f, .08f));
tf->addGeometry(TFGeometry1D::createQuad(tgt::vec2(0.f, 1.f), tgt::col4(0, 0, 0, 0), tgt::col4(255, 255, 255, 255)));
_usSliceExtractor.p_transferFunction.replaceTF(tf);
tf->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.5f, 1.f), tgt::col4(0, 0, 0, 0), tgt::col4(0, 0, 0, 180)));
_ctFullDRR.p_transferFunction.replaceTF(tf);
_ctFullDRR.p_targetImageID.setValue("ct.drr.full");
_ctFullDRR.p_samplingRate.setValue(1.f);
Geometry1DTransferFunction* tf2 = new Geometry1DTransferFunction(128, tgt::vec2(0.f, 1.f));
tf2->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.5f, 1.f), tgt::col4(0, 0, 0, 0), tgt::col4(0, 0, 0, 180)));
_ctClippedDRR.p_transferFunction.replaceTF(tf2);
_ctClippedDRR.p_targetImageID.setValue("ct.drr.clipped");
_ctClippedDRR.p_samplingRate.setValue(1.f);
_renderTargetID.setValue("renderTarget");
_renderTargetID.addSharedProperty(&(_usSliceExtractor.p_targetImageID));
// = US Setup =====================================================================================
_usSliceExtractor.p_sliceNumber.setValue(0);
// = Compositing Setup ============================================================================
_xrayReader.p_targetImageID.connect(&_compositor.p_firstImageId);
_ctFullDRR.p_targetImageID.connect(&_compositor.p_secondImageId);
_compositor.p_targetImageId.setValue("composed");
_compositor.p_compositingMethod.selectById("alpha");
_renderTargetID.setValue("ct.drr.full");
_trackballHandler->setViewportSize(_renderTargetSize);
}
void IxpvDemo::execute() {
{
tbb::spin_mutex::scoped_lock lock(_localMutex);
_invalidationLevel.setValid();
// TODO: think whether we want to lock all processors already here.
}
if (! _xrayReader.getInvalidationLevel().isValid()) {
lockGLContextAndExecuteProcessor(&_xrayReader);
if (! _ctReader.getInvalidationLevel().isValid()) {
executeProcessor(&_ctReader);
// convert data
DataContainer::ScopedTypedData<ImageData> img(_data, _xrayReader.p_targetImageID.getValue());
ImageDataLocal* local = ImageDataConverter::tryConvert<ImageDataLocal>(img);
if (local != 0) {
DataHandle dh = _data.addData("se.input", local);
_usSliceExtractor.p_transferFunction.getTF()->setImageHandle(dh);
DataContainer::ScopedTypedData<ImageData> img(_data, _ctReader.p_targetImageID.getValue());
if (img != 0) {
ImageDataLocal* local = ImageDataConverter::tryConvert<ImageDataLocal>(img);
if (local != 0) {
DataHandle dh = _data.addData("ct.image.local", local);
Interval<float> ii = local->getNormalizedIntensityRange();
_ctFullDRR.p_transferFunction.getTF()->setImageHandle(dh);
_ctFullDRR.p_transferFunction.getTF()->setIntensityDomain(tgt::vec2(ii.getLeft(), ii.getRight()));
_ctClippedDRR.p_transferFunction.getTF()->setImageHandle(dh);
_ctClippedDRR.p_transferFunction.getTF()->setIntensityDomain(tgt::vec2(ii.getLeft(), ii.getRight()));
}
{
tgt::GLContextScopedLock lock(_canvas->getContext());
ImageDataGL* gl = ImageDataConverter::tryConvert<ImageDataGL>(local);
if (gl != 0) {
_data.addData(_ctReader.p_targetImageID.getValue(), gl);
}
}
CtxtMgr.releaseCurrentContext();
tgt::Bounds volumeExtent = img->getWorldBounds();
tgt::vec3 pos = volumeExtent.center() - tgt::vec3(0, 0, tgt::length(volumeExtent.diagonal()));
_trackballHandler->setSceneBounds(volumeExtent);
_trackballHandler->setCenter(volumeExtent.center());
_trackballHandler->reinitializeCamera(pos, volumeExtent.center(), _camera.getValue().getUpVector());
}
}
if (! _usSliceExtractor.getInvalidationLevel().isValid()) {
lockGLContextAndExecuteProcessor(&_usSliceExtractor);
}
}
void IxpvDemo::keyEvent(tgt::KeyEvent* e) {
if (e->pressed()) {
for (std::vector<AbstractProcessor*>::iterator it = _processors.begin(); it != _processors.end(); ++it) {
if (! (*it)->getInvalidationLevel().isValid())
lockGLContextAndExecuteProcessor(*it);
}
}
//
// void IxpvDemo::keyEvent(tgt::KeyEvent* e) {
// if (e->pressed()) {
// }
// }
const std::string IxpvDemo::getName() const {
return "IXPV Demo";
}
void IxpvDemo::onRenderTargetSizeChanged(const AbstractProperty* prop) {
_trackballHandler->setViewportSize(_renderTargetSize);
float ratio = static_cast<float>(_effectiveRenderTargetSize.getValue().x) / static_cast<float>(_effectiveRenderTargetSize.getValue().y);
_camera.setWindowRatio(ratio);
}
}
\ No newline at end of file
......@@ -31,12 +31,21 @@
#define IXPVDEMO_H__
#include "core/datastructures/imagedatalocal.h"
#include "core/eventhandlers/mwheeltonumericpropertyeventhandler.h"
#include "core/eventhandlers/trackballnavigationeventhandler.h"
#include "core/eventhandlers/transfuncwindowingeventhandler.h"
#include "core/properties/cameraproperty.h"
#include "core/pipeline/visualizationpipeline.h"
#include "modules/io/processors/mhdimagereader.h"
#include "modules/devil/processors/devilimagereader.h"
#include "modules/vis/processors/sliceextractor.h"
#include "modules/vis/processors/proxygeometrygenerator.h"
#include "modules/vis/processors/geometryrenderer.h"
#include "modules/vis/processors/eepgenerator.h"
#include "modules/vis/processors/drrraycaster.h"
#include "modules/vis/processors/simpleraycaster.h"
#include "modules/vis/processors/rendertargetcompositor.h"
namespace campvis {
class IxpvDemo : public VisualizationPipeline {
......@@ -62,17 +71,28 @@ namespace campvis {
**/
virtual void execute();
virtual void keyEvent(tgt::KeyEvent* e);
//virtual void keyEvent(tgt::KeyEvent* e);
void onRenderTargetSizeChanged(const AbstractProperty* prop);
protected:
DevilImageReader _xrayReader;
MhdImageReader _ctReader;
ProxyGeometryGenerator _ctProxy;
EEPGenerator _ctFullEEP;
EEPGenerator _ctClippedEEP;
DRRRaycaster _ctFullDRR;
DRRRaycaster _ctClippedDRR;
MhdImageReader _usReader;
SliceExtractor _usSliceExtractor;
MWheelToNumericPropertyEventHandler _wheelHandler;
TransFuncWindowingEventHandler _tfWindowingHandler;
RenderTargetCompositor _compositor;
CameraProperty _camera;
TrackballNavigationEventHandler* _trackballHandler;
};
}
......
......@@ -59,12 +59,15 @@ namespace campvis {
ImageDataRenderTarget* rt = new ImageDataRenderTarget(tgt::svec3(_renderTargetSize.getValue(), 1));
rt->activate();
glPushAttrib(GL_ALL_ATTRIB_BITS);
glDisable(GL_DEPTH_TEST);
if (p_invertMapping.getValue())
glClearColor(0.f, 0.f, 0.f, 1.f);
else
glClearColor(1.f, 1.f, 1.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QuadRdr.renderQuad();
glPopAttrib();
LGL_ERROR;
rt->deactivate();
......
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitt Mnchen
// Boltzmannstr. 3, 85748 Garching b. Mnchen, Germany
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#include "rendertargetcompositor.h"
#include "tgt/logmanager.h"
#include "tgt/shadermanager.h"
#include "tgt/textureunit.h"
#include "core/datastructures/imagedata.h"
#include "core/datastructures/imagedatagl.h"
#include "core/datastructures/imagedatarendertarget.h"
#include "core/datastructures/imagedataconverter.h"
#include "core/classification/simpletransferfunction.h"
#include "core/tools/quadrenderer.h"
namespace campvis {
static const GenericOption<CompositingMode> compositingOptions[3] = {
GenericOption<CompositingMode>("first", "Only First", CompositingModeFirst),
GenericOption<CompositingMode>("second", "Only Second", CompositingModeSecond),
GenericOption<CompositingMode>("alpha", "Alpha Blending", CompositingModeAlpha)
};
const std::string RenderTargetCompositor::loggerCat_ = "CAMPVis.modules.vis.RenderTargetCompositor";
RenderTargetCompositor::RenderTargetCompositor(GenericProperty<tgt::ivec2>& canvasSize)
: VisualizationProcessor(canvasSize)
, p_firstImageId("FirstImageId", "First Input Image", "", DataNameProperty::READ)
, p_secondImageId("SecondImageId", "Second Input Image", "", DataNameProperty::READ)
, p_targetImageId("TargetImageId", "Output Image", "", DataNameProperty::WRITE)
, p_compositingMethod("CompositingMethod", "Compositing Method", compositingOptions, 3)
, p_alphaValue("AlphaValue", "AlphaValue", .5f, 0.f, 1.f)
, _shader(0)
{
addProperty(&p_firstImageId);
addProperty(&p_secondImageId);
addProperty(&p_targetImageId);
addProperty(&p_compositingMethod);
addProperty(&p_alphaValue);
addDecorator(new ProcessorDecoratorBackground());
decoratePropertyCollection(this);
}
RenderTargetCompositor::~RenderTargetCompositor() {
}
void RenderTargetCompositor::init() {
VisualizationProcessor::init();
_shader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "modules/vis/glsl/rendertargetcompositor.frag", "", false);
_shader->setAttributeLocation(0, "in_Position");
_shader->setAttributeLocation(1, "in_TexCoord");
}
void RenderTargetCompositor::deinit() {
VisualizationProcessor::deinit();
ShdrMgr.dispose(_shader);
}
void RenderTargetCompositor::process(DataContainer& data) {
DataContainer::ScopedTypedData<ImageDataRenderTarget> firstImage(data, p_firstImageId.getValue());
DataContainer::ScopedTypedData<ImageDataRenderTarget> secondImage(data, p_secondImageId.getValue());
if (firstImage != 0 && secondImage != 0 ) {
ImageDataRenderTarget* rt = new ImageDataRenderTarget(tgt::svec3(_renderTargetSize.getValue(), 1));
glPushAttrib(GL_ALL_ATTRIB_BITS);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
_shader->activate();
tgt::TextureUnit firstColorUnit, firstDepthUnit, secondColorUnit, secondDepthUnit;
firstImage->bind(_shader, &firstColorUnit, &firstDepthUnit, "_firstColor", "_firstDepth");
secondImage->bind(_shader, &secondColorUnit, &secondDepthUnit, "_secondColor", "_secondDepth");
_shader->setUniform("_compositingMethod", p_compositingMethod.getValue());
_shader->setUniform("_alpha", p_alphaValue.getValue());
decorateRenderProlog(data, _shader);
rt->activate();
LGL_ERROR;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QuadRdr.renderQuad();
rt->deactivate();
_shader->deactivate();
tgt::TextureUnit::setZeroUnit();
glPopAttrib();
LGL_ERROR;
data.addData(p_targetImageId.getValue(), rt);
p_targetImageId.issueWrite();
}
else {
LERROR("No suitable input images found.");
}
_invalidationLevel.setValid();
}
}
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universität München
// Boltzmannstr. 3, 85748 Garching b. München, Germany
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#ifndef RENDERTARGETCOMPOSITOR_H__
#define RENDERTARGETCOMPOSITOR_H__
#include <string>
#include "core/pipeline/abstractprocessordecorator.h"
#include "core/pipeline/processordecoratorbackground.h"
#include "core/pipeline/visualizationprocessor.h"
#include "core/properties/datanameproperty.h"
#include "core/properties/optionproperty.h"
namespace tgt {
class Shader;
}
namespace campvis {
class ImageData;
namespace {
enum CompositingMode {
CompositingModeFirst = 0,
CompositingModeSecond = 1,
CompositingModeAlpha = 2,
};
}
/**
* Performs the composition of a multiple render targets
*/
class RenderTargetCompositor : public VisualizationProcessor, public HasProcessorDecorators {
public:
/**
* Constructs a new RenderTargetCompositor Processor
**/