Commit 36131eb6 authored by schultezub's avatar schultezub
Browse files

improved transferfunction GLSL header and adapted AbstractTransferFunction class


git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@334 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 6b96a855
......@@ -84,7 +84,7 @@ namespace campvis {
_texture = 0;
}
void AbstractTransferFunction::bind(tgt::Shader* shader, const tgt::TextureUnit& texUnit, const std::string& textureUniform /*= "_tfTex"*/, const std::string& textureParametersUniform /*= "_tgTextureParameters"*/) {
void AbstractTransferFunction::bind(tgt::Shader* shader, const tgt::TextureUnit& texUnit, const std::string& transFuncUniform /*= "_transferFunction"*/) {
// TODO: lock here or in createTexture?
{
tbb::mutex::scoped_lock lock(_localMutex);
......@@ -99,8 +99,19 @@ namespace campvis {
bool tmp = shader->getIgnoreUniformLocationError();
shader->setIgnoreUniformLocationError(true);
// TODO: set domain mapping uniforms
shader->setUniform(textureUniform, texUnit.getUnitNumber());
shader->setUniform(textureParametersUniform + "._intensityDomain", tgt::vec2(_intensityDomain));
shader->setUniform(transFuncUniform + "._texture", texUnit.getUnitNumber());
switch (getDimensionality()) {
case 1:
shader->setUniform(transFuncUniform + "._intensityDomain", tgt::vec2(_intensityDomain));
break;
case 2:
shader->setUniform(transFuncUniform + "._intensityDomainX", tgt::vec2(_intensityDomain));
break;
default:
tgtAssert(false, "Unsupported TF dimensionality!");
break;
}
shader->setIgnoreUniformLocationError(tmp);
}
......
......@@ -94,10 +94,9 @@ namespace campvis {
* \note Calling thread must have a valid OpenGL context.
* \param shader Shader used for rendering
* \param texUnit Texture unit to bind texture to
* \param textureUniform Uniform name to store texture unit number
* \param textureParametersUniform Uniform name to store texture parameters
* \param transFuncUniform Uniform name to store the TF struct
*/
void bind(tgt::Shader* shader, const tgt::TextureUnit& texUnit, const std::string& textureUniform = "_tfTex", const std::string& textureParametersUniform = "_tfTextureParameters");
void bind(tgt::Shader* shader, const tgt::TextureUnit& texUnit, const std::string& transFuncUniform = "_transferFunction");
/**
* Creates the OpenGL texture.
......
......@@ -26,48 +26,52 @@
//
// ================================================================================================
struct TFParameters {
vec2 _intensityDomain;
struct TransferFunction1D {
sampler1D _texture; ///< The texture containing the TF LUT
vec2 _intensityDomain; ///< The intensity domain to map the LUT to
};
struct TransferFunction2D {
sampler2D _texture; ///< The texture containing the TF LUT
vec2 _intensityDomainX; ///< The intensity domain for mapping the x value to the LUT
};
/**
* Linearly maps the image intensity \a intensity to the domain of the transfer function as defined in the TF parameters \a p.
* \param p Transfer function parameters struct
* \param intensity Image intensity (normalized to [0, 1])
* \return Intensity mapped to transfer function domain.
* \param intensityDomain The intensity domain to map the intensity to
* \param intensity Image intensity (normalized to [0, 1])
* \return Intensity mapped to transfer function domain for LUT.
*/
float mapIntensityToTFDomain(in TFParameters p, in float intensity) {
if(intensity <= p._intensityDomain.x)
float mapIntensityToTFDomain(in vec2 intensityDomain, in float intensity) {
if(intensity <= intensityDomain.x)
return -1.0;
else if(intensity >= p._intensityDomain.y)
else if(intensity >= intensityDomain.y)
return -1.0;
else
return (intensity - p._intensityDomain.x) / (p._intensityDomain.y - p._intensityDomain.x);
return (intensity - intensityDomain.x) / (intensityDomain.y - intensityDomain.x);
}
/**
* Performs a 1D transfer function lookup for the given TF and intensity.
* Before lookup \a intensity will be mapped to the TF domain.
* \param p Transfer function parameters struct
* \param tex Transfer function texture
* \param tf 1D Transfer function struct
* \param intensity Image intensity (normalized to [0, 1])
* \return The color of the transfer function at the given intensity.
*/
vec4 lookupTF(in TFParameters p, in sampler1D tex, in float intensity) {
intensity = mapIntensityToTFDomain(p, intensity);
return (intensity >= 0.0 ? texture(tex, intensity) : vec4(0.0, 0.0, 0.0, 0.0));
vec4 lookupTF(in TransferFunction1D tf, in float intensity) {
intensity = mapIntensityToTFDomain(tf._intensityDomain, intensity);
return (intensity >= 0.0 ? texture(tf._texture, intensity) : vec4(0.0, 0.0, 0.0, 0.0));
}
/**
* Performs a 2D transfer function lookup for the given TF, intensity and y-value.
* Before lookup \a intensity will be mapped to the TF domain.
* \param p Transfer function parameters struct
* \param tex Transfer function texture
* \param tf 2D Transfer function struct
* \param intensity Image intensity (normalized to [0, 1])
* \param y y-value for lookup
* \return The color of the transfer function at the given intensity and y-value.
*/
vec4 lookupTF(in TFParameters p, in sampler2D tex, in float intensity, in float y) {
intensity = mapIntensityToTFDomain(p, intensity);
return (intensity >= 0.0 ? texture(tex, vec2(intensity, y)) : vec4(0.0, 0.0, 0.0, 0.0));
vec4 lookupTF(in TransferFunction2D tf, in float intensity, in float y) {
intensity = mapIntensityToTFDomain(tf._intensityDomainX, intensity);
return (intensity >= 0.0 ? texture(tf._texture, vec2(intensity, y)) : vec4(0.0, 0.0, 0.0, 0.0));
}
......@@ -151,6 +151,7 @@ namespace campvis {
// all parsing done - lets create the image:
ImageDataDisk* image = new ImageDataDisk(url, dimensionality, size, pt, 1, offset, e);
data.addData(_targetImageID.getValue(), image);
_targetImageID.issueWrite();
}
catch (tgt::Exception& e) {
LERROR("Error while parsing MHD header: " << e.what());
......
......@@ -65,7 +65,7 @@ namespace campvis {
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Reads an MHD image into the pipeline."; };
GenericProperty<std::string> _url; ///< URL for file to read
StringProperty _url; ///< URL for file to read
DataNameProperty _targetImageID; ///< image ID for read image
protected:
......
......@@ -42,8 +42,8 @@ namespace campvis {
, _wheelHandler(&_sliceExtractor._sliceNumber)
{
_processors.push_back(&_imageReader);
_processors.push_back(&_gvg);
_processors.push_back(&_lhh);
// _processors.push_back(&_gvg);
// _processors.push_back(&_lhh);
_processors.push_back(&_sliceExtractor);
_eventHandlers.push_back(&_wheelHandler);
}
......@@ -59,8 +59,8 @@ namespace campvis {
_gvg._inputVolume.setValue("se.input");
_lhh._inputVolume.setValue("se.input");
_gvg._outputGradients.connect(&_lhh._inputGradients);
// _lhh._inputVolume.setValue("se.input");
// _gvg._outputGradients.connect(&_lhh._inputGradients);
_sliceExtractor._sourceImageID.setValue("se.input");
_sliceExtractor._sliceNumber.setValue(0);
......@@ -91,12 +91,12 @@ namespace campvis {
_data.addData("se.input", local);
}
}
if (! _gvg.getInvalidationLevel().isValid()) {
executeProcessor(&_gvg);
}
if (! _lhh.getInvalidationLevel().isValid()) {
lockGLContextAndExecuteProcessor(&_lhh);
}
// if (! _gvg.getInvalidationLevel().isValid()) {
// executeProcessor(&_gvg);
// }
// if (! _lhh.getInvalidationLevel().isValid()) {
// lockGLContextAndExecuteProcessor(&_lhh);
// }
if (! _sliceExtractor.getInvalidationLevel().isValid()) {
lockGLContextAndExecuteProcessor(&_sliceExtractor);
}
......
......@@ -49,8 +49,7 @@ uniform Texture2D _exitPoints; // ray exit points
uniform Texture2D _exitPointsDepth; // ray exit points depth
uniform Texture3D _volume; // texture lookup parameters for volume_
uniform sampler1D _tfTex;
uniform TFParameters _tfTextureParameters;
uniform TransferFunction1D _transferFunction;
uniform LightSource _lightSource;
uniform vec3 _cameraPosition;
......@@ -84,7 +83,7 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
vec3 samplePosition = entryPoint.rgb + t * direction;
float intensity = getElement3DNormalized(_volume, samplePosition).a;
vec3 gradient = computeGradient(_volume, samplePosition);
vec4 color = lookupTF(_tfTextureParameters, _tfTex, intensity);
vec4 color = lookupTF(_transferFunction, intensity);
#ifdef ENABLE_SHADOWING
// simple and expensive implementation of hard shadows
......@@ -100,7 +99,7 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
while (! finished) {
// grab intensity and TF opacity
intensity = getElement3DNormalized(_volume, position).a;
shadowFactor += lookupTF(_tfTextureParameters, _tfTex, intensity).a;
shadowFactor += lookupTF(_transferFunction, intensity).a;
position += L;
finished = (shadowFactor > 0.95)
......
......@@ -35,11 +35,9 @@ out vec4 out_Color;
#include "tools/transferfunction.frag"
uniform Texture2D _texture;
uniform sampler1D _tfTex;
uniform TFParameters _tfTextureParameters;
uniform TransferFunction1D _transferFunction;
void main() {
float intensity = getElement2DNormalized(_texture, ex_TexCoord.xy).a;
out_Color = lookupTF(_tfTextureParameters, _tfTex, intensity);
out_Color = lookupTF(_transferFunction, intensity);
}
......@@ -69,15 +69,17 @@ namespace campvis {
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Extracts a single slice from the input image and renders it using a transfer function."; };
/// \see AbstractProcessor::process()
virtual void process(DataContainer& data);
GenericProperty<std::string> _sourceImageID; ///< image ID for input image
GenericProperty<std::string> _targetImageID; ///< image ID for output image
StringProperty _sourceImageID; ///< image ID for input image
StringProperty _targetImageID; ///< image ID for output image
IntProperty _sliceNumber; ///< number of the slice to extract
TransferFunctionProperty _transferFunction; ///< Transfer function
protected:
/// adapts the range of the _sliceNumber property to the image
void updateProperties(const ImageData* img);
tgt::Shader* _shader; ///< Shader for slice rendering
......
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