Commit 1175aee0 authored by schultezub's avatar schultezub

* changed ImageDataRenderTarget to support multiple color texture attachments

 * implemented first hitpoint calculation to SimpleRaycaster

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@293 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 383898a8
......@@ -141,7 +141,8 @@ namespace TUMVis {
}
else if (const ImageDataRenderTarget* imgRT = dynamic_cast<const ImageDataRenderTarget*>(it->second->getData())) {
if (imgRT->getDimensionality() == 2) {
textures.push_back(imgRT->getColorTexture());
for (size_t i = 0; i < imgRT->getNumColorTextures(); ++i)
textures.push_back(imgRT->getColorTexture(i));
textures.push_back(imgRT->getDepthTexture());
}
}
......
......@@ -40,100 +40,37 @@ namespace TUMVis {
ImageDataRenderTarget::ImageDataRenderTarget(const tgt::svec3& size, GLint internalFormatColor /*= GL_RGBA8*/, GLint internalFormatDepth /*= GL_DEPTH_COMPONENT24*/)
: ImageData(2, size)
, _colorTexture(0)
, _colorTextures(0)
, _depthTexture(0)
, _fbo(0)
{
tgtAssert(size.z == 1, "RenderTargets are only two-dimensional, expected size.z == 1.");
initRenderTarget(internalFormatColor, internalFormatDepth);
tgtAssert(_colorTexture != 0, "Color texture is 0, something went terribly wrong...");
tgtAssert(_depthTexture != 0, "Depth texture is 0, something went terribly wrong...");
tgtAssert(_fbo != 0, "Framebuffer object is 0, something went terribly wrong...");
}
ImageDataRenderTarget::~ImageDataRenderTarget() {
delete _fbo;
delete _colorTexture;
delete _depthTexture;
}
void ImageDataRenderTarget::initRenderTarget(GLint internalFormatColor, GLint internalFormatDepth) {
if (!GpuCaps.isNpotSupported() && !GpuCaps.areTextureRectanglesSupported()) {
LWARNING("Neither non-power-of-two textures nor texture rectangles seem to be supported!");
}
{
// acqiure a new TextureUnit, so that we don't mess with other currently bound textures during texture upload...
tgt::TextureUnit rtUnit;
rtUnit.activate();
switch(internalFormatColor) {
case GL_RGB:
_colorTexture = new tgt::Texture(0, _size, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
break;
case GL_RGB16F_ARB:
_colorTexture = new tgt::Texture(0, _size, GL_RGB, GL_RGB16F_ARB, GL_FLOAT, tgt::Texture::LINEAR);
break;
case GL_RGBA:
_colorTexture = new tgt::Texture(0, _size, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
break;
case GL_RGBA8:
_colorTexture = new tgt::Texture(0, _size, GL_RGBA, GL_RGBA8, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
break;
case GL_RGBA16:
_colorTexture = new tgt::Texture(0, _size, GL_RGBA, GL_RGBA16, GL_UNSIGNED_SHORT, tgt::Texture::LINEAR);
break;
case GL_RGBA16F:
_colorTexture = new tgt::Texture(0, _size, GL_RGBA, GL_RGBA16F, GL_FLOAT, tgt::Texture::LINEAR);
break;
case GL_RGBA32F:
_colorTexture = new tgt::Texture(0, _size, GL_RGBA, GL_RGBA32F, GL_FLOAT, tgt::Texture::LINEAR);
break;
default:
tgtAssert(false, "Unknown internal format!");
}
_colorTexture->uploadTexture();
_colorTexture->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
switch(internalFormatDepth) {
case GL_DEPTH_COMPONENT16:
_depthTexture = new tgt::Texture(0, _size, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT16, GL_FLOAT, tgt::Texture::LINEAR);
break;
case GL_DEPTH_COMPONENT24:
_depthTexture = new tgt::Texture(0, _size, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24, GL_FLOAT, tgt::Texture::LINEAR);
break;
case GL_DEPTH_COMPONENT32:
_depthTexture = new tgt::Texture(0, _size, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT32, GL_FLOAT, tgt::Texture::LINEAR);
break;
#ifdef GL_DEPTH_COMPONENT32F
case GL_DEPTH_COMPONENT32F:
_depthTexture = new tgt::Texture(0, _size, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT32F, GL_FLOAT, tgt::Texture::LINEAR);
break;
#endif
default:
tgtAssert(false, "Unknown internal depth format!");
}
_depthTexture->uploadTexture();
_depthTexture->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
}
_fbo = new tgt::FramebufferObject();
if (!_fbo) {
LERROR("Failed to initialize framebuffer object!");
return;
}
_fbo->activate();
_fbo->attachTexture(_colorTexture);
_fbo->isComplete();
_fbo->attachTexture(_depthTexture, GL_DEPTH_ATTACHMENT_EXT);
_fbo->isComplete();
createAndAttachTexture(internalFormatColor);
createAndAttachTexture(internalFormatDepth);
_fbo->deactivate();
tgtAssert(_colorTextures.front() != 0, "Color texture is 0, something went terribly wrong...");
tgtAssert(_depthTexture != 0, "Depth texture is 0, something went terribly wrong...");
tgtAssert(_fbo != 0, "Framebuffer object is 0, something went terribly wrong...");
}
ImageDataRenderTarget::~ImageDataRenderTarget() {
delete _fbo;
for (std::vector<tgt::Texture*>::iterator it = _colorTextures.begin(); it != _colorTextures.end(); ++it)
delete *it;
delete _depthTexture;
}
void ImageDataRenderTarget::activate() {
_fbo->activate();
glViewport(0, 0, _size.x, _size.y);
......@@ -143,13 +80,15 @@ namespace TUMVis {
_fbo->deactivate();
}
void ImageDataRenderTarget::bindColorTexture() const {
_colorTexture->bind();
void ImageDataRenderTarget::bindColorTexture(size_t index /*= 0*/) const {
tgtAssert(index < _colorTextures.size(), "Color texture index out of bounds!");
_colorTextures[index]->bind();
}
void ImageDataRenderTarget::bindColorTexture(const tgt::TextureUnit& texUnit) const {
void ImageDataRenderTarget::bindColorTexture(const tgt::TextureUnit& texUnit, size_t index /*= 0*/) const {
tgtAssert(index < _colorTextures.size(), "Color texture index out of bounds!");
texUnit.activate();
_colorTexture->bind();
_colorTextures[index]->bind();
}
void ImageDataRenderTarget::bindDepthTexture() const {
......@@ -161,11 +100,12 @@ namespace TUMVis {
_depthTexture->bind();
}
void ImageDataRenderTarget::bind(tgt::Shader* shader, const tgt::TextureUnit* colorTexUnit, const tgt::TextureUnit* depthTexUnit, const std::string& colorTexUniform /*= "_colorTexture"*/, const std::string& depthTexUniform /*= "_depthTexture"*/) const {
void ImageDataRenderTarget::bind(tgt::Shader* shader, const tgt::TextureUnit* colorTexUnit, const tgt::TextureUnit* depthTexUnit, const std::string& colorTexUniform /*= "_colorTextures"*/, const std::string& depthTexUniform /*= "_depthTexture"*/, size_t index /*= 0*/) const {
tgtAssert(index < _colorTextures.size(), "Color texture index out of bounds!");
bool tmp = shader->getIgnoreUniformLocationError();
shader->setIgnoreUniformLocationError(true);
if (colorTexUnit != 0) {
bindColorTexture(*colorTexUnit);
bindColorTexture(*colorTexUnit, index);
shader->setUniform(colorTexUniform + "._texture", colorTexUnit->getUnitNumber());
shader->setUniform(colorTexUniform + "._size", tgt::vec2(_size.xy()));
shader->setUniform(colorTexUniform + "._sizeRCP", tgt::vec2(1.f) / tgt::vec2(_size.xy()));
......@@ -189,12 +129,112 @@ namespace TUMVis {
return 0;
}
const tgt::Texture* ImageDataRenderTarget::getColorTexture() const {
return _colorTexture;
const tgt::Texture* ImageDataRenderTarget::getColorTexture(size_t index /*= 0*/) const {
tgtAssert(index < _colorTextures.size(), "Color texture index out of bounds!");
return _colorTextures[index];
}
const tgt::Texture* ImageDataRenderTarget::getDepthTexture() const {
return _depthTexture;
}
size_t ImageDataRenderTarget::getNumColorTextures() const {
return _colorTextures.size();
}
void ImageDataRenderTarget::createAndAttachTexture(GLint internalFormat) {
// do sanity tests:
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 (_colorTextures.size() >= 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 = GL_COLOR_ATTACHMENT0 + _colorTextures.size();
break;
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
#ifdef GL_DEPTH_COMPONENT32F
case GL_DEPTH_COMPONENT32F:
#endif
tgtAssert(_depthTexture == 0, "Tried to attach more than one depth texture.");
attachment = GL_DEPTH_ATTACHMENT;
break;
default:
tgtAssert(false, "Unknown internal format!");
}
// acqiure a new TextureUnit, so that we don't mess with other currently bound textures during texture upload...
tgt::TextureUnit rtUnit;
rtUnit.activate();
// create texture
tgt::Texture* tex = 0;
switch(internalFormat) {
case GL_RGB:
tex = new tgt::Texture(0, _size, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
_colorTextures.push_back(tex);
break;
case GL_RGB16F_ARB:
tex = new tgt::Texture(0, _size, GL_RGB, GL_RGB16F_ARB, GL_FLOAT, tgt::Texture::LINEAR);
_colorTextures.push_back(tex);
break;
case GL_RGBA:
tex = new tgt::Texture(0, _size, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
_colorTextures.push_back(tex);
break;
case GL_RGBA8:
tex = new tgt::Texture(0, _size, GL_RGBA, GL_RGBA8, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
_colorTextures.push_back(tex);
break;
case GL_RGBA16:
tex = new tgt::Texture(0, _size, GL_RGBA, GL_RGBA16, GL_UNSIGNED_SHORT, tgt::Texture::LINEAR);
_colorTextures.push_back(tex);
break;
case GL_RGBA16F:
tex = new tgt::Texture(0, _size, GL_RGBA, GL_RGBA16F, GL_FLOAT, tgt::Texture::LINEAR);
_colorTextures.push_back(tex);
break;
case GL_RGBA32F:
tex = new tgt::Texture(0, _size, GL_RGBA, GL_RGBA32F, GL_FLOAT, tgt::Texture::LINEAR);
_colorTextures.push_back(tex);
break;
case GL_DEPTH_COMPONENT16:
tex = new tgt::Texture(0, _size, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT16, GL_FLOAT, tgt::Texture::LINEAR);
_depthTexture = tex;
break;
case GL_DEPTH_COMPONENT24:
tex = new tgt::Texture(0, _size, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24, GL_FLOAT, tgt::Texture::LINEAR);
_depthTexture = tex;
break;
#ifdef GL_DEPTH_COMPONENT32F
case GL_DEPTH_COMPONENT32F:
tex = new tgt::Texture(0, _size, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT32F, GL_FLOAT, tgt::Texture::LINEAR);
break;
#endif
default:
tgtAssert(false, "Unknown internal format!");
}
tex->uploadTexture();
tex->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
// attach texture to FBO
_fbo->activate();
_fbo->attachTexture(tex, attachment);
_fbo->isComplete();
_fbo->deactivate();
}
}
\ No newline at end of file
......@@ -35,6 +35,8 @@
#include "tgt/vector.h"
#include "core/datastructures/imagedata.h"
#include <vector>
namespace tgt {
class Shader;
}
......@@ -43,7 +45,8 @@ namespace TUMVis {
/**
* Stores render target data.
* This is basically a wrapper for two OpenGL textures (color + depth) and their attachment to the framebuffer.
* This is basically a wrapper for multiple OpenGL textures (color + depth) and their attachment to the framebuffer.
* Each ImageDataRenderTarget has at least one color texture and exactly one depth texture attachment.
*
* \note Its dimensionality must be 2.
*
......@@ -54,7 +57,7 @@ namespace TUMVis {
class ImageDataRenderTarget : public ImageData {
public:
/**
* Creates a new ImageDataRenderTarget representation.
* Creates a new ImageDataRenderTarget representation with one color and one depth attachment.
*
* \param size Size of this image (number of elements per dimension)
* \param internalFormatColor Internal OpenGL format for the color texture.
......@@ -77,12 +80,20 @@ namespace TUMVis {
*/
virtual ImageDataRenderTarget* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const;
/**
* Creates and initializes a new OpenGL texture according to \a internalFormat and attaches it to the FBO.
* \note The amout of attachable color textures is limited by the driver/hardware - check
* GpuCaps.getMaxColorAttachments(). You can only attach one depth texture.
* \param internalFormat Internal OpenGL format for the texture to create.
*/
void createAndAttachTexture(GLint internalFormat);
/**
* Gets the color texture of this render target
* \return _colorTexture
* \param index Index of the color texture attachment to return.
* \return _colorTextures[index]
*/
const tgt::Texture* getColorTexture() const;
const tgt::Texture* getColorTexture(size_t index = 0) const;
/**
* Gets the depth texture of this render target
......@@ -103,7 +114,7 @@ namespace TUMVis {
/**
* Binds the color texture without activating a texture unit.
*/
void bindColorTexture() const;
void bindColorTexture(size_t index = 0) const;
/**
* Binds the depth texture without activating a texture unit.
......@@ -114,7 +125,7 @@ namespace TUMVis {
* Activates the texture unit \a texUnit and binds the color texture.
* \param texUnit Texture unit to activate
*/
void bindColorTexture(const tgt::TextureUnit& texUnit) const;
void bindColorTexture(const tgt::TextureUnit& texUnit, size_t index = 0) const;
/**
* Activates the texture unit \a texUnit and binds the depth texture.
......@@ -122,6 +133,12 @@ namespace TUMVis {
*/
void bindDepthTexture(const tgt::TextureUnit& texUnit) const;
/**
* Gets the number of color textures/attachments of this render target.
* \return _colorTextures.size()
*/
size_t getNumColorTextures() const;
/**
* Binds the textures of this render target and sets the according shader uniforms.
* Of \a colorTexUnit or \a depthTexUnit is 0, the corresponding texture will not be bound
......@@ -137,21 +154,16 @@ namespace TUMVis {
tgt::Shader* shader,
const tgt::TextureUnit* colorTexUnit,
const tgt::TextureUnit* depthTexUnit,
const std::string& colorTexUniform = "_colorTexture",
const std::string& depthTexUniform = "_depthTexture") const;
const std::string& colorTexUniform = "_colorTextures",
const std::string& depthTexUniform = "_depthTexture",
size_t index = 0) const;
protected:
/**
* Initializes the textures as well as the FBO.
* \param internalFormatColor Internal OpenGL format for the color texture.
* \param internalFormatDepth Internal OpenGL format for the depth texture.
*/
void initRenderTarget(GLint internalFormatColor, GLint internalFormatDepth);
tgt::Texture* _colorTexture; ///< color texture
tgt::Texture* _depthTexture; ///< depth texture
tgt::FramebufferObject* _fbo; ///< Framebuffer object coordinating color and depth texture
std::vector<tgt::Texture*> _colorTextures; ///< color textures
tgt::Texture* _depthTexture; ///< depth texture
tgt::FramebufferObject* _fbo; ///< Framebuffer object color and depth textures are attached to
static const std::string loggerCat_;
......
......@@ -49,16 +49,20 @@ namespace TUMVis {
}
void SimpleRaycaster::processImpl(DataContainer& data) {
ImageDataRenderTarget* rt = new ImageDataRenderTarget(tgt::svec3(_renderTargetSize.getValue(), 1));
rt->activate();
ImageDataRenderTarget* output = new ImageDataRenderTarget(tgt::svec3(_renderTargetSize.getValue(), 1));
output->createAndAttachTexture(GL_RGBA32F);
output->activate();
GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
glDrawBuffers(2, buffers);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthFunc(GL_ALWAYS);
QuadRdr.renderQuad();
LGL_ERROR;
rt->deactivate();
data.addData(_targetImageID.getValue(), rt);
output->deactivate();
data.addData(_targetImageID.getValue(), output);
_targetImageID.issueWrite();
}
}
......@@ -28,7 +28,8 @@
#version 330
out vec4 out_Color; ///< outgoing fragment color
layout(location = 0) out vec4 out_Color; ///< outgoing fragment color
layout(location = 1) out vec4 out_FHP; ///< outgoing fragment first hitpoint
#include "tools/raycasting.frag"
#include "tools/texture2d.frag"
......@@ -83,8 +84,10 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
}
// save first hit ray parameter for depth value calculation
if (firstHitT < 0.0 && result.a > 0.0)
if (firstHitT < 0.0 && result.a > 0.0) {
firstHitT = t;
out_FHP = vec4(samplePosition, 1.0);
}
// early ray termination
if (result.a >= 1.0) {
......
......@@ -64,7 +64,7 @@ namespace TUMVis {
virtual const std::string getDescription() const { return "Performs a simple volume ray casting."; };
DataNameProperty _targetImageID; ///< image ID for output image
protected:
/// \see RaycastingProcessor::processImpl()
virtual void processImpl(DataContainer& data);
......
......@@ -72,7 +72,7 @@ namespace TUMVis {
// assure that mirror is faced to camera
if (tgt::sign(tgt::dot(cam.getLook(), n)) == 1)
n *= -1.f;
//_mirrorNormal.setValue(n);
_mirrorNormal.setValue(n);
std::vector<tgt::vec3> vertices;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment