Commit 37dccfdc authored by schultezub's avatar schultezub
Browse files

* introduced NumericProperty<T>

 * fixed memory leak in ImageDataConverter
 * added usage of Shader::IgnoreUniformLocationError where reasonable
 * fixed shaders

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@189 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 9130371f
......@@ -24,6 +24,7 @@ int main(int argc, char** argv) {
app->addCanvas(canvas);
app->init();
LogMgr.getConsoleLog()->addCat("", true);
if (argc > 0) {
// ugly hack
......
......@@ -9,12 +9,10 @@ namespace TUMVis {
DataHandle::DataHandle(const DataContainer* owner, AbstractData* data)
: _data(data)
{
LDEBUG("DataHandle()");
addOwner(this, owner);
}
DataHandle::~DataHandle() {
LDEBUG("~DataHandle()");
delete _data;
}
......
......@@ -7,11 +7,9 @@ namespace TUMVis {
template<>
TUMVis::ImageDataLocal* ImageDataConverter::convert(const ImageDataDisk* source) {
WeaklyTypedPointer wtp = source->getImageData();
#define DISPATCH_CONVERSION(numChannels) \
if (source->getNumChannels() == (numChannels)) { \
switch (wtp._baseType) { \
switch (source->getBaseType()) { \
case WeaklyTypedPointer::UINT8: \
return convertToGenericLocal<uint8_t, (numChannels)>(source); \
case WeaklyTypedPointer::INT8: \
......
......@@ -73,9 +73,12 @@ namespace TUMVis {
void ImageDataGL::bind(tgt::Shader* shader, const tgt::TextureUnit& texUnit, const std::string& texUniform /*= "_texture"*/, const std::string& textureParametersUniform /*= "_textureParameters"*/) const {
bind(texUnit);
bool tmp = shader->getIgnoreUniformLocationError();
shader->setIgnoreUniformLocationError(true);
shader->setUniform(texUniform, texUnit.getUnitNumber());
shader->setUniform(textureParametersUniform + "._size", tgt::vec2(_size.xy()));
shader->setUniform(textureParametersUniform + "._sizeRCP", tgt::vec2(1.f) / tgt::vec2(_size.xy()));
shader->setIgnoreUniformLocationError(tmp);
}
}
\ No newline at end of file
......@@ -130,10 +130,13 @@ namespace TUMVis {
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 std::string& textureParametersUniform /*= "_textureParameters"*/) const {
bindColorTexture(colorTexUnit);
bindDepthTexture(depthTexUnit);
bool tmp = shader->getIgnoreUniformLocationError();
shader->setIgnoreUniformLocationError(true);
shader->setUniform(colorTexUniform, colorTexUnit.getUnitNumber());
shader->setUniform(depthTexUniform, depthTexUnit.getUnitNumber());
shader->setUniform(textureParametersUniform + "._size", tgt::vec2(_size.xy()));
shader->setUniform(textureParametersUniform + "._sizeRCP", tgt::vec2(1.f) / tgt::vec2(_size.xy()));
shader->setIgnoreUniformLocationError(tmp);
}
ImageDataRenderTarget* ImageDataRenderTarget::clone() const {
......
#include "tools/sampler2d.frag"
uniform vec2 _viewportSize;
uniform vec2 _viewportSizeRCP;
uniform sampler2D _colorTexture;
uniform sampler2D _depthTexture;
uniform TextureParameters _textureParameters;
......
uniform vec2 _viewportSize;
uniform vec2 _viewportSizeRCP;
struct TextureParameters {
vec2 _size;
vec2 _sizeRCP;
......
......@@ -77,8 +77,10 @@ namespace TUMVis {
// activate shader
_copyShader->activate();
_copyShader->setIgnoreUniformLocationError(true);
_copyShader->setUniform("_viewportSize", tgt::vec2(_canvasSize.getValue()));
_copyShader->setUniform("_viewportSizeRCP", 1.f / tgt::vec2(_canvasSize.getValue()));
_copyShader->setIgnoreUniformLocationError(false);
// bind input textures
tgt::TextureUnit colorUnit, depthUnit;
......
......@@ -50,11 +50,12 @@ namespace TUMVis {
const T& getValue() const;
/**
* Sets the property value to \a value and notifies all observers.
* On successful validation it sets the property value to \a value and notifies all observers.
* Depending on the current lock state of the property, the value will either be written to the front or back buffer.
* \sa GenericProperty::validateValue
* \param value New value for this property.
*/
void setValue(const T& value);
virtual void setValue(const T& value);
/**
......@@ -73,6 +74,14 @@ namespace TUMVis {
protected:
/**
* Adapts \a value, so that is is a valid value for this property.
* Default implementation does nothing and always returns \a value, subclasses can overwrite this method to fit their needs.
* \param value value to validate.
*/
virtual T validateValue(const T& value);
/**
* Sets the property value to \a value and notifies all observers.
* \note _localMutex has to be acquired before calling!
......@@ -128,13 +137,14 @@ namespace TUMVis {
template<typename T>
void TUMVis::GenericProperty<T>::setValue(const T& value) {
T vv = validateValue(value);
tbb::spin_mutex::scoped_lock lock(_localMutex);
if (_inUse)
setBackValue(value);
setBackValue(vv);
else {
setFrontValue(value);
setBackValue(value);
setFrontValue(vv);
setBackValue(vv);
}
}
......@@ -172,6 +182,11 @@ namespace TUMVis {
_backBuffer = value;
}
template<typename T>
T TUMVis::GenericProperty<T>::validateValue(const T& value) {
return value;
}
template<typename T>
const std::string TUMVis::GenericProperty<T>::loggerCat_ = "TUMVis.core.datastructures.GenericProperty";
}
......
#ifndef NUMERICPROPERTY_H__
#define NUMERICPROPERTY_H__
#include "tbb/include/tbb/spin_mutex.h"
#include "tgt/logmanager.h"
#include "core/properties/genericproperty.h"
namespace TUMVis {
/**
* Generic class for numeric properties.
* Numeric properties manage a minimum and maximum value and ensure, that the property's
* value is within these bounds.
*
* \tparam T Base type of the property's value.
*/
template<typename T>
class NumericProperty : public GenericProperty<T> {
public:
/**
* Creates a new NumericProperty.
* \param name Property name
* \param title Property title (e.g. used for GUI)
* \param value Initial value of the property
* \param minValue Minimum value for this property
* \param maxValue Maximum value for this property
* \param il Invalidation level that this property triggers
*/
NumericProperty(
const std::string& name,
const std::string& title,
const T& value,
const T& minValue,
const T& maxValue,
InvalidationLevel il = InvalidationLevel::INVALID_RESULT);
/**
* Virtual Destructor
**/
virtual ~NumericProperty();
/**
* Adds the given property \a prop to the set of shared properties.
* All shared properties will be changed when this property changes.
* \note Make sure not to build circular sharing or you will encounter endless loops!
* \param prop Property to add, must be of the same type as this property.
*/
virtual void addSharedProperty(AbstractProperty* prop);
/**
* Returns the minimum value of this property.
* \return _minValue
*/
const T& getMinValue() const;
/**
* Returns the minimum value of this property.
* \return _minValue
*/
const T& getMaxValue() const;
/**
* Sets the minimum value if this property.
* \param value New minimum value for this property.
*/
virtual void setMinValue(const T& value);
/**
* Sets the minimum value if this property.
* \param value New minimum value for this property.
*/
virtual void setMaxValue(const T& value);
void increment();
void decrement();
protected:
/**
* Checks, whether \a value is a valid value for this property.
* Default implementation always returns true, subclasses can overwrite this method to fit their needs.
* \param value value to validate.
* \return true if \a value is a valid value for this property.
*/
virtual T validateValue(const T& value);
T _value; ///< value of the property
T _backBuffer; ///< back buffer for values when property is in use
T _minValue; ///< Minimum value for this property
T _maxValue; ///< Maximum value for this property
static const std::string loggerCat_;
};
// - template implementation ----------------------------------------------------------------------
template<typename T>
TUMVis::NumericProperty<T>::NumericProperty(const std::string& name, const std::string& title, const T& value, const T& minValue, const T& maxValue, InvalidationLevel il /*= InvalidationLevel::INVALID_RESULT*/)
: GenericProperty<T>(name, title, value, il)
, _minValue(minValue)
, _maxValue(maxValue)
{
}
template<typename T>
TUMVis::NumericProperty<T>::~NumericProperty() {
}
template<typename T>
void TUMVis::NumericProperty<T>::addSharedProperty(AbstractProperty* prop) {
// make type check first, then call base method.
tgtAssert(prop != 0, "Shared property must not be 0!");
if (NumericProperty<T>* tmp = dynamic_cast< NumericProperty<T>* >(prop)) {
AbstractProperty::addSharedProperty(prop);
tmp->setValue(getValue());
return;
}
tgtAssert(false, "Shared property must be of the same type as this property!");
}
template<typename T>
T TUMVis::NumericProperty<T>::validateValue(const T& value) {
if (value >= _minValue && value <= _maxValue)
return value;
else {
return (value < _minValue) ? _minValue : _maxValue;
}
}
template<typename T>
const T& TUMVis::NumericProperty<T>::getMinValue() const {
return _minValue;
}
template<typename T>
const T& TUMVis::NumericProperty<T>::getMaxValue() const {
return _maxValue;
}
template<typename T>
void TUMVis::NumericProperty<T>::setMinValue(const T& value) {
_minValue = value;
setValue(validateValue(getValue()));
}
template<typename T>
void TUMVis::NumericProperty<T>::setMaxValue(const T& value) {
_maxValue = value;
setValue(validateValue(getValue()));
}
template<typename T>
void TUMVis::NumericProperty<T>::increment() {
setValue(getValue() + T(1));
}
template<typename T>
void TUMVis::NumericProperty<T>::decrement() {
setValue(getValue() - T(1));
}
}
#endif // NUMERICPROPERTY_H__
......@@ -20,12 +20,9 @@ namespace TUMVis {
, _targetImageID("targetImageName", "Target Image ID", "MhdImageReader.output")
{
_properties.addProperty(&_url);
_url.addObserver(this);
_properties.addProperty(&_targetImageID);
// just testing some type traits...
tgt::Vector3<int8_t>* v = new tgt::Vector3<int8_t>[6];
GenericImageDataLocal<int8_t, 3> data(3, tgt::svec3(1, 2, 3), v);
data.clone();
_targetImageID.addObserver(this);
}
MhdImageReader::~MhdImageReader() {
......@@ -138,5 +135,6 @@ namespace TUMVis {
return;
}
_invalidationLevel.setValid();
}
}
\ No newline at end of file
......@@ -27,19 +27,24 @@ namespace TUMVis {
_imageReader->_targetImageID.setValue("reader.output");
_sliceExtractor->_sourceImageID.setValue("se.input");
_sliceExtractor->_sliceNumber.setValue(0);
_renderTargetID.setValue("renderTarget");
_renderTargetID.addSharedProperty(&(_sliceExtractor->_targetImageID));
}
void SliceVis::execute() {
_imageReader->process(_data);
if (! _imageReader->getInvalidationLevel().isValid()) {
_imageReader->process(_data);
// convert data
const ImageData* img = _data.getTypedData<ImageData>("reader.output");
ImageDataLocal* local = ImageDataConverter::tryConvert<ImageDataLocal>(img);
if (local != 0) {
_data.addData("se.input", local);
// convert data
const ImageData* img = _data.getTypedData<ImageData>("reader.output");
ImageDataLocal* local = ImageDataConverter::tryConvert<ImageDataLocal>(img);
if (local != 0) {
_data.addData("se.input", local);
}
}
if (! _sliceExtractor->getInvalidationLevel().isValid()) {
_sliceExtractor->process(_data);
}
}
......@@ -48,10 +53,10 @@ namespace TUMVis {
if (e->pressed()) {
switch (e->keyCode()) {
case tgt::KeyEvent::K_UP:
_sliceExtractor->_sliceNumber.setValue(_sliceExtractor->_sliceNumber.getValue()+1);
_sliceExtractor->_sliceNumber.increment();
break;
case tgt::KeyEvent::K_DOWN:
_sliceExtractor->_sliceNumber.setValue(_sliceExtractor->_sliceNumber.getValue()-1);
_sliceExtractor->_sliceNumber.decrement();
break;
}
}
......
......@@ -14,12 +14,13 @@ namespace TUMVis {
: VisualizationProcessor(canvasSize)
, _sourceImageID("sourceImageID", "Input Image", "")
, _targetImageID("targetImageID", "Output Image", "")
, _sliceNumber("sliceNumber", "Slice Number", 0)
, _sliceNumber("sliceNumber", "Slice Number", 0, 0, 0)
, _shader(0)
{
_properties.addProperty(&_sourceImageID);
_properties.addProperty(&_targetImageID);
_properties.addProperty(&_sliceNumber);
_sliceNumber.addObserver(this);
}
SliceExtractor::~SliceExtractor() {
......@@ -35,6 +36,7 @@ namespace TUMVis {
if (img != 0) {
if (img->getDimensionality() == 3) {
updateProperties(img);
const tgt::svec3& imgSize = img->getSize();
ImageDataLocal* slice = img->getSubImage(tgt::svec3(0, 0, _sliceNumber.getValue()), tgt::svec3(imgSize.x-1, imgSize.y-1, _sliceNumber.getValue()));
ImageDataGL* glData = ImageDataConverter::tryConvert<ImageDataGL>(slice);
......@@ -62,5 +64,15 @@ namespace TUMVis {
else {
LERROR("No suitable input image found.");
}
_invalidationLevel.setValid();
}
void SliceExtractor::updateProperties(const ImageData* img) {
const tgt::svec3& imgSize = img->getSize();
if (_sliceNumber.getMaxValue() != imgSize.z - 1){
_sliceNumber.setMaxValue(imgSize.z - 1);
}
}
}
......@@ -5,7 +5,6 @@ uniform sampler2D _texture;
uniform TextureParameters _textureParameters;
void main() {
//vec2 fragCoord = gl_FragCoord.xy * _viewportSizeRCP;
float intensity = getElement2DNormalized(_texture, _textureParameters, gl_TexCoord[0]).a * 10.0;
float intensity = getElement2DNormalized(_texture, _textureParameters, gl_TexCoord[0].xy).a * 10.0;
gl_FragData[0] = vec4(intensity, intensity, intensity, 1.0);
}
......@@ -6,8 +6,11 @@
#include "tgt/shadermanager.h"
#include "core/pipeline/visualizationprocessor.h"
#include "core/properties/genericproperty.h"
#include "core/properties/numericproperty.h"
namespace TUMVis {
class ImageData;
/**
* Extracts a slice from a 3D image and renders it into a rendertarget.
*/
......@@ -31,9 +34,11 @@ namespace TUMVis {
GenericProperty<std::string> _sourceImageID; ///< image ID for input image
GenericProperty<std::string> _targetImageID; ///< image ID for output image
GenericProperty<size_t> _sliceNumber; ///< number of the slice to extract
NumericProperty<size_t> _sliceNumber; ///< number of the slice to extract
protected:
void updateProperties(const ImageData* img);
tgt::Shader* _shader; ///< Shader for slice rendering
static const std::string loggerCat_;
......
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