Notice to GitKraken users: A vulnerability has been found in the SSH key generation of GitKraken versions 7.6.0 to 8.0.0 (https://www.gitkraken.com/blog/weak-ssh-key-fix). If you use GitKraken and have generated a SSH key using one of these versions, please remove it both from your local workstation and from your LRZ GitLab profile.

21.10.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit 42480c65 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Branching work to introduce new FBO handling concept:

 * each VisualizationProcessor manages its own FBO
 * instead of creating a whole new FBO each process(), the processors shall only create and attach textures to the FBO
 * the FramebufferActivationGuard offers automatic (de)activation and detachment of all textures

SimpleRaycaster already uses the new concept, the rest still uses the legacy API
parent 63ea46dc
......@@ -45,6 +45,7 @@
#include "application/campvispainter.h"
#include "application/gui/mainwindow.h"
#include "core/datastructures/imagerepresentationrendertarget.h"
#include "core/tools/opengljobprocessor.h"
#include "core/tools/simplejobprocessor.h"
#include "core/tools/quadrenderer.h"
......@@ -106,10 +107,13 @@ namespace campvis {
// ensure matching OpenGL specs
if (GpuCaps.getGlVersion() < tgt::GpuCapabilities::GlVersion::TGT_GL_VERSION_3_3) {
LERROR("Your system does not support OpenGL 3.3, which is mandatory. CAMPVis will probably not work as intendet.");
LERROR("Your system does not support OpenGL 3.3, which is mandatory. CAMPVis will probably not work as intended.");
}
if (GpuCaps.getShaderVersion() < tgt::GpuCapabilities::GlVersion::SHADER_VERSION_330) {
LERROR("Your system does not support GLSL Shader Version 3.30, which is mandatory. CAMPVis will probably not work as intendet.");
LERROR("Your system does not support GLSL Shader Version 3.30, which is mandatory. CAMPVis will probably not work as intended.");
}
if (!GpuCaps.isNpotSupported() && !GpuCaps.areTextureRectanglesSupported()) {
LERROR("Neither non-power-of-two textures nor texture rectangles seem to be supported. CAMPVis will probably not work as intended.");
}
QuadRenderer::init();
......
......@@ -39,7 +39,7 @@
#include "core/datastructures/imagerepresentationgl.h"
namespace campvis {
const std::string ImageRepresentationRenderTarget::loggerCat_ = "CAMPVis.core.datastructures.ImageRepresentationRenderTarget";
ImageRepresentationRenderTarget* ImageRepresentationRenderTarget::create(ImageData* parent, GLint internalFormatColor /*= GL_RGBA8*/, GLint internalFormatDepth /*= GL_DEPTH_COMPONENT24*/) {
......@@ -55,6 +55,19 @@ namespace campvis {
return std::make_pair(id, toReturn);
}
ImageRepresentationRenderTarget* ImageRepresentationRenderTarget::create(ImageData* parent, const tgt::FramebufferObject* fbo) {
ImageRepresentationRenderTarget* toReturn = new ImageRepresentationRenderTarget(parent, fbo);
toReturn->addToParent();
return toReturn;
}
std::pair<ImageData*, ImageRepresentationRenderTarget*> ImageRepresentationRenderTarget::createWithImageData(const tgt::svec2& size, const tgt::FramebufferObject* fbo) {
ImageData* id = new ImageData(2, tgt::svec3(size, 1), 4);
ImageRepresentationRenderTarget* toReturn = new ImageRepresentationRenderTarget(id, fbo);
toReturn->addToParent();
return std::make_pair(id, toReturn);
}
ImageRepresentationRenderTarget::ImageRepresentationRenderTarget(ImageData* parent, GLint internalFormatColor /*= GL_RGBA8*/, GLint internalFormatDepth /*= GL_DEPTH_COMPONENT24*/)
: GenericAbstractImageRepresentation<ImageRepresentationRenderTarget>(parent)
, _colorTextures(0)
......@@ -63,10 +76,6 @@ namespace campvis {
{
tgtAssert(parent->getSize().z == 1, "RenderTargets are only two-dimensional, expected parent image size.z == 1.");
if (!GpuCaps.isNpotSupported() && !GpuCaps.areTextureRectanglesSupported()) {
LWARNING("Neither non-power-of-two textures nor texture rectangles seem to be supported!");
}
_fbo = new tgt::FramebufferObject();
if (!_fbo) {
LERROR("Failed to initialize framebuffer object!");
......@@ -113,6 +122,23 @@ namespace campvis {
// _fbo->attachTexture(cc, GL_COLOR_ATTACHMENT0);
}
ImageRepresentationRenderTarget::ImageRepresentationRenderTarget(ImageData* parent, const tgt::FramebufferObject* fbo)
: GenericAbstractImageRepresentation<ImageRepresentationRenderTarget>(parent)
, _colorTextures(0)
, _depthTexture(0)
, _fbo(0)
{
tgtAssert(parent->getSize().z == 1, "RenderTargets are only two-dimensional, expected parent image size.z == 1.");
tgt::Texture *const *const attachments = fbo->getAttachments();
for (size_t i = 0; i < TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS; ++i) {
if (attachments[i] != 0)
_colorTextures.push_back(attachments[i]);
}
if (attachments[TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS] != 0)
_depthTexture = attachments[TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS];
}
ImageRepresentationRenderTarget::~ImageRepresentationRenderTarget() {
// TODO: double check whether deleting FBOs without detaching their attachments is not harmful
// if (_fbo != 0) {
......@@ -346,4 +372,7 @@ namespace campvis {
}
}
\ No newline at end of file
......@@ -31,22 +31,29 @@
#define IMAGEREPRESENTATIONRENDERTARGET_H__
#include "tgt/framebufferobject.h"
#include "tgt/singleton.h"
#include "tgt/texture.h"
#include "tgt/textureunit.h"
#include "tgt/vector.h"
#include "core/datastructures/genericabstractimagerepresentation.h"
#include "core/datastructures/imagerepresentationgl.h"
#include "tbb/atomic.h"
#include "tbb/spin_mutex.h"
#include <list>
#include <utility>
#include <vector>
namespace tgt {
class Shader;
class FramebufferObject;
}
namespace campvis {
class ImageRepresentationGL;
class ImageRepresentationRenderTarget;
/**
* Stores render target data.
* This is basically a wrapper for multiple OpenGL textures (color + depth) and their attachment to the framebuffer.
......@@ -70,7 +77,7 @@ namespace campvis {
* \param internalFormatColor Internal OpenGL format for the color texture.
* \param internalFormatDepth Internal OpenGL format for the depth texture.
* \return A pointer to the newly created ImageRepresentationRenderTarget, you do \b not own this pointer!
*/
*/
static ImageRepresentationRenderTarget* create(ImageData* parent, GLint internalFormatColor = GL_RGBA8, GLint internalFormatDepth = GL_DEPTH_COMPONENT24);
/**
......@@ -84,6 +91,32 @@ namespace campvis {
*/
static std::pair<ImageData*, ImageRepresentationRenderTarget*> createWithImageData(const tgt::svec2& size, GLint internalFormatColor = GL_RGBA8, GLint internalFormatDepth = GL_DEPTH_COMPONENT24);
/**
* Creates a new ImageRepresentationRenderTarget representation with one color and one depth attachment
* and automatically adds it to \a parent which will take ownerwhip.
*
* \note You do \b not own the returned pointer..
* \note ImageRepresentationRenderTarget will take ownership of all textures attached to \a fbo.
*
* \param parent Image this representation represents, must not be 0.
* \param fbo FrameBufferObject to use the attachements from.
* \return A pointer to the newly created ImageRepresentationRenderTarget, you do \b not own this pointer!
*/
static ImageRepresentationRenderTarget* create(ImageData* parent, const tgt::FramebufferObject* fbo);
/**
* Creates a new ImageRepresentationRenderTarget and a new ImageData with the given specifications.
* Assigns the representation to the image.
*
* \note ImageRepresentationRenderTarget will take ownership of all textures attached to \a fbo.
*
* \param parent Image this representation represents, must not be 0.
* \param fbo FrameBufferObject to use the attachements from.
*
* \return A pair of the created ImageData and the created RenderTarget image representation.
*/
static std::pair<ImageData*, ImageRepresentationRenderTarget*> createWithImageData(const tgt::svec2& size, const tgt::FramebufferObject* fbo);
/**
* Destructor
*/
......@@ -212,11 +245,20 @@ namespace campvis {
/**
* Creates a new ImageRepresentationRenderTarget from one color texture and one optional depth texture.
* \param parent Image this representation represents, must not be 0.
* \param colorTexture Color texture, must not be 0
* \param depthTexture Depth texture, optional, must have valid internal format and same dimensions as \a colorTexture
*/
ImageRepresentationRenderTarget(ImageData* parent, const ImageRepresentationGL* colorTexture, const ImageRepresentationGL* depthTexture = 0);
/**
* Creates a new ImageRepresentationRenderTarget from one color texture and one optional depth texture.
* \note ImageRepresentationRenderTarget will take ownership of all textures attached to \a fbo.
* \param parent Image this representation represents, must not be 0.
* \param fbo FrameBufferObject to use the attachements from.
*/
ImageRepresentationRenderTarget(ImageData* parent, const tgt::FramebufferObject* fbo);
/**
* Activates the texture unit \a texUnit and binds the color texture.
* \param texUnit Texture unit to activate
......
......@@ -29,10 +29,19 @@
#include "visualizationprocessor.h"
#include "tgt/textureunit.h"
#include "core/datastructures/imagedata.h"
#include "core/datastructures/imagerepresentationrendertarget.h"
namespace campvis {
const std::string VisualizationProcessor::loggerCat_ = "CAMPVis.core.datastructures.VisualizationProcessor";
// ================================================================================================
VisualizationProcessor::VisualizationProcessor(IVec2Property& renderTargetSize)
: AbstractProcessor()
, _fbo(0)
, _renderTargetSize("renderTargetSize", "Canvas Size", renderTargetSize.getValue(), renderTargetSize.getMinValue(), renderTargetSize.getMaxValue())
{
renderTargetSize.addSharedProperty(&_renderTargetSize);
......@@ -43,4 +52,122 @@ namespace campvis {
}
void VisualizationProcessor::init() {
AbstractProcessor::init();
_fbo = new tgt::FramebufferObject();
}
void VisualizationProcessor::deinit() {
_fbo->detachAll();
delete _fbo;
AbstractProcessor::deinit();
}
void VisualizationProcessor::createAndAttachTexture(GLint internalFormat, GLenum attachment) {
tgtAssert(_fbo->isActive(), "Trying to attach a texture while FBO is not bound!");
// acqiure a new TextureUnit, so that we don't mess with other currently bound textures during texture upload...
tgt::TextureUnit rtUnit;
rtUnit.activate();
// Set OpenGL pixel alignment to 1 to avoid problems with NPOT textures
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// create texture
tgt::Texture* tex = 0;
switch(internalFormat) {
case GL_RGB:
tex = new tgt::Texture(0, getRenderTargetSize(), GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
break;
case GL_RGB16F_ARB:
tex = new tgt::Texture(0, getRenderTargetSize(), GL_RGB, GL_RGB16F_ARB, GL_FLOAT, tgt::Texture::LINEAR);
break;
case GL_RGBA:
tex = new tgt::Texture(0, getRenderTargetSize(), GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
break;
case GL_RGBA8:
tex = new tgt::Texture(0, getRenderTargetSize(), GL_RGBA, GL_RGBA8, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
break;
case GL_RGBA16:
tex = new tgt::Texture(0, getRenderTargetSize(), GL_RGBA, GL_RGBA16, GL_UNSIGNED_SHORT, tgt::Texture::LINEAR);
break;
case GL_RGBA16F:
tex = new tgt::Texture(0, getRenderTargetSize(), GL_RGBA, GL_RGBA16F, GL_FLOAT, tgt::Texture::LINEAR);
break;
case GL_RGBA32F:
tex = new tgt::Texture(0, getRenderTargetSize(), GL_RGBA, GL_RGBA32F, GL_FLOAT, tgt::Texture::LINEAR);
break;
case GL_DEPTH_COMPONENT16:
tex = new tgt::Texture(0, getRenderTargetSize(), GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT16, GL_FLOAT, tgt::Texture::LINEAR);
break;
case GL_DEPTH_COMPONENT24:
tex = new tgt::Texture(0, getRenderTargetSize(), GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24, GL_FLOAT, tgt::Texture::LINEAR);
break;
#ifdef GL_DEPTH_COMPONENT32F
case GL_DEPTH_COMPONENT32F:
break;
#endif
default:
tgtAssert(false, "Unknown internal format!");
}
tex->uploadTexture();
tex->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
// attach texture to FBO
_fbo->attachTexture(tex, attachment);
}
void VisualizationProcessor::createAndAttachTexture(GLint internalFormat) {
GLenum attachment = 0;
switch(internalFormat) {
case GL_RGB:
case GL_RGB16F_ARB:
case GL_RGBA:
case GL_RGBA8:
case GL_RGBA16:
case GL_RGBA16F:
case GL_RGBA32F:
if (_fbo->getNumColorAttachments() >= static_cast<size_t>(GpuCaps.getMaxColorAttachments())) {
tgtAssert(false, "Tried to attach more color textures to FBO than supported!");
LWARNING("Tried to attach more color textures to FBO than supported, aborted.");
return;
}
attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + _fbo->getNumColorAttachments());
break;
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
#ifdef GL_DEPTH_COMPONENT32F
case GL_DEPTH_COMPONENT32F:
#endif
tgtAssert(_fbo->getDepthAttachment() == 0, "Tried to attach more than one depth texture.");
attachment = GL_DEPTH_ATTACHMENT;
break;
default:
tgtAssert(false, "Unknown internal format!");
}
createAndAttachTexture(internalFormat, attachment);
}
tgt::ivec3 VisualizationProcessor::getRenderTargetSize() const {
return tgt::ivec3(_renderTargetSize.getValue(), 1);
}
void VisualizationProcessor::createAndAttachColorTexture() {
createAndAttachTexture(GL_RGBA8);
}
void VisualizationProcessor::createAndAttachDepthTexture() {
createAndAttachTexture(GL_DEPTH_COMPONENT24);
}
ImageData* VisualizationProcessor::createImageDataFromFbo() const {
ImageData* toReturn = new ImageData(2, getRenderTargetSize(), 4);
ImageRepresentationRenderTarget::create(toReturn, _fbo);
return toReturn;
}
}
......@@ -30,24 +30,51 @@
#ifndef VISUALIZATIONPROCESSOR_H__
#define VISUALIZATIONPROCESSOR_H__
#include "tgt/framebufferobject.h"
#include "tgt/texture.h"
#include "tgt/vector.h"
#include "core/pipeline/abstractprocessor.h"
#include "core/properties/numericproperty.h"
namespace campvis {
class ImageData;
/**
* Specialization of AbstractProcessor for visualization purposes.
*
* VisualizationProcessors are required to be called by a VisualizationPipeline which ensure
* to provide a valid OpenGL context when calling the processor's process() method. Hence, a
* VisualizationProcessor is allowed/capable of performing OpenGl operations.
* For determining the canvas/viewport size, a VisualizationProcessor gets a reference to the
* parent pipeline's render target size property during instantiation.
*
* Each VisualizationProcessor has its own OpenGL FramebufferObject, which is created during
* init(). For determining the canvas/viewport size, a VisualizationProcessor gets a reference
* to the parent pipeline's render target size property during instantiation.
*
* \sa VisualizationPipeline
*/
class VisualizationProcessor : public AbstractProcessor {
public:
struct FramebufferActivationGuard {
public:
FramebufferActivationGuard(VisualizationProcessor* vp)
: _parentProcessor(vp)
, _fbo(vp->_fbo)
{
tgtAssert(_fbo != 0, "FBO must not be 0.");
_fbo->activate();
}
~FramebufferActivationGuard() {
_fbo->detachAll();
_fbo->deactivate();
}
private:
VisualizationProcessor* _parentProcessor;
tgt::FramebufferObject* _fbo;
};
/**
* Creates a VisualizationProcessor.
......@@ -62,11 +89,55 @@ namespace campvis {
**/
virtual ~VisualizationProcessor();
/// \see AbstractProcessor::init()
virtual void init();
/// \see AbstractProcessor::deinit()
virtual void deinit();
/**
* Creates a texture with the given format and attaches it to the FBO to \a attachment.
* \param internalFormat Internal OpenGL texture format
* \param attachment Target attachment for texture
*/
void createAndAttachTexture(GLint internalFormat, GLenum attachment);
/**
* Creates a texture with the given format and attaches it to the FBO using the default attachments.
* \note Default attachment are GL_DEPTH_ATTACHMENT for depth textures and
* GL_COLOR_ATTACHMENT_0 + <number of color textures attached>.
* \param internalFormat Internal OpenGL texture format
*/
void createAndAttachTexture(GLint internalFormat);
/**
* Creates a color texture with format GL_RGBA8 and attaches it to the FBO using the
* default attachment.
*/
void createAndAttachColorTexture();
/**
* Creates a depth texture with format GL_DEPTH_COMPONENT24 and attaches it to the FBO
* using the default attachment.
*/
void createAndAttachDepthTexture();
//protected:
// protected:
/**
* Creates an ImageData object from the textures currently attached to the FBO.
* \note The caller takes ownership of the returned pointer.
* \return A pointer to the created ImageData object.
*/
ImageData* createImageDataFromFbo() const;
tgt::ivec3 getRenderTargetSize() const;
tgt::FramebufferObject* _fbo;
IVec2Property _renderTargetSize; ///< Viewport size of target canvas
static const std::string loggerCat_;
};
}
......
......@@ -32,7 +32,9 @@ const std::string FramebufferObject::loggerCat_("tgt.FramebufferObject");
FramebufferObject::FramebufferObject()
: id_(0)
, numColorAttachments_(0)
{
memset(attachments_, 0, sizeof(Texture*) * (TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS+2));
generateId();
}
......@@ -67,22 +69,24 @@ void FramebufferObject::attachTexture(Texture* texture, GLenum attachment, int m
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, attachment, texture->getType(), texture->getId(), mipLevel );
break;
}
attachedTextures_[attachment] = texture;
size_t index = decodeAttachment(attachment);
attachments_[index] = texture;
if (index < TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS)
++numColorAttachments_;
}
Texture* FramebufferObject::getTextureAtAttachment(GLenum attachment) {
std::map<GLenum, Texture*>::iterator iter = attachedTextures_.find(attachment);
if( iter != attachedTextures_.end() ) {
return attachedTextures_[attachment];
}
else
return 0;
return attachments_[decodeAttachment(attachment)];
}
void FramebufferObject::detachTexture(GLenum attachment) {
std::map<GLenum, Texture*>::iterator iter = attachedTextures_.find(attachment);
if( iter != attachedTextures_.end() ) {
attachedTextures_.erase(iter);
size_t index = decodeAttachment(attachment);
if (attachments_[index] != 0) {
attachments_[index] = 0;
if (index < TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS)
--numColorAttachments_;
}
else {
LWARNING("Trying to detach unknown texture!");
......@@ -92,9 +96,16 @@ void FramebufferObject::detachTexture(GLenum attachment) {
}
void FramebufferObject::detachAll() {
while(!attachedTextures_.empty()) {
detachTexture(attachedTextures_.begin()->first);
for (GLenum i = 0; i < TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS; ++i) {
if (colorAttachments_[i] != 0)
detachTexture(GL_COLOR_ATTACHMENT0 + i);
}
if (depthAttachment_ != 0)
detachTexture(GL_DEPTH_ATTACHMENT);
if (stencilAttachment_ != 0)
detachTexture(GL_STENCIL_ATTACHMENT);
numColorAttachments_ = 0;
}
bool FramebufferObject::isComplete() const
......@@ -149,4 +160,25 @@ GLuint FramebufferObject::generateId() {
return id_;
}
Texture*const *const FramebufferObject::getAttachments() const {
return attachments_;
}
const Texture* FramebufferObject::getColorAttachment(size_t index /*= 0*/) const {
tgtAssert(index < TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS, "Index out of bounds!");
return attachments_[index];
}
const Texture* FramebufferObject::getDepthAttachment() const {
return attachments_[TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS];
}
const Texture* FramebufferObject::getStencilAttachment() const {
return attachments_[TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS+1];
}
size_t FramebufferObject::getNumColorAttachments() const {
return numColorAttachments_;
}
} // namespace
......@@ -25,6 +25,10 @@
#ifndef TGT_FRAMEBUFFEROBJECT_H
#define TGT_FRAMEBUFFEROBJECT_H
/// if you run out of FBO color attachments, edit this value o_O
#define TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS 6
#include "tgt/assert.h"
#include "tgt/texture.h"
#include "tgt/types.h"
......@@ -46,7 +50,7 @@ public:
/// Bind a texture to the "attachment" point of this FBO
void attachTexture(Texture* texture,
GLenum attachment = GL_COLOR_ATTACHMENT0_EXT,
GLenum attachment = GL_COLOR_ATTACHMENT0,
int mipLevel = 0,
int zSlice = 0);
......@@ -60,12 +64,42 @@ public:
GLuint getId() const { return id_; };
Texture *const *const getAttachments() const;
size_t getNumColorAttachments() const;
const Texture* getColorAttachment(size_t index = 0) const;
const Texture* getDepthAttachment() const;
const Texture* getStencilAttachment() const;
protected:
GLuint generateId();
GLuint id_;
std::map<GLenum, Texture*> attachedTextures_;
size_t decodeAttachment(GLenum attachment) {
switch (attachment) {
case GL_DEPTH_ATTACHMENT:
return TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS;
case GL_STENCIL_ATTACHMENT:
return TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS + 1;
default:
tgtAssert((attachment - GL_COLOR_ATTACHMENT0) < TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS, "Color attachments out of bounds - adjust TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS define!");
return attachment - GL_COLOR_ATTACHMENT0;
}
}
union {
struct {
Texture* colorAttachments_[TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS];
Texture* depthAttachment_;
Texture* stencilAttachment_;
};
Texture* attachments_[TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS+2];
};
size_t numColorAttachments_;
static const std::string loggerCat_; ///< category used in logging
};
......
......@@ -57,12 +57,13 @@ namespace campvis {
}
void SimpleRaycaster::processImpl(DataContainer& data, ImageRepresentationGL::ScopedRepresentation& image) {
std::pair<ImageData*, ImageRepresentationRenderTarget*> output = ImageRepresentationRenderTarget::createWithImageData(_renderTargetSize.getValue());
output.second->createAndAttachTexture(GL_RGBA32F);
output.second->createAndAttachTexture(GL_RGBA32F);
output.second->activate();
FramebufferActivationGuard fag(this);
createAndAttachTexture(GL_RGBA8);
createAndAttachTexture(GL_RGBA32F);
createAndAttachTexture(GL_RGBA32F);
createAndAttachDepthTexture();
GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 , GL_COLOR_ATTACHMENT2 };
static const GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 , GL_COLOR_ATTACHMENT2 };
glDrawBuffers(3, buffers);