Commit 4f18b0b6 authored by schultezub's avatar schultezub
Browse files

Fixed handling of signed integer images:

 * enabled correct scaling during OpenGL upload
 * changed TypeNormalizer::normalizeToFloat() and TypeNormalizer::denormalizeFromFloat() to normalize signed integers to [0.0, 1.0] (as OpenGL does)
 * adapted TransferFunctionPropertyWidget (still a hack yet)

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@387 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 8ae09f18
......@@ -60,19 +60,17 @@ namespace campvis {
_spinDomainLeft = new QDoubleSpinBox(_widget);
_spinDomainLeft->setMinimum(0);
_spinDomainLeft->setMinimum(-10000);
_spinDomainLeft->setDecimals(2);
_spinDomainLeft->setSingleStep(0.01);
_gridLayout->addWidget(_spinDomainLeft, 0, 1);
_spinDomainRight = new QDoubleSpinBox(_widget);
_spinDomainRight->setMaximum(1);
_spinDomainRight->setMaximum(10000);
_spinDomainRight->setDecimals(2);
_spinDomainRight->setSingleStep(0.01);
_gridLayout->addWidget(_spinDomainRight, 0, 2);
updateWidgetFromProperty();
_btnFitDomainToImage = new QPushButton("Fit Intensity Domain to Image", _widget);
_gridLayout->addWidget(_btnFitDomainToImage, 1, 0, 1, 3);
......@@ -82,6 +80,7 @@ namespace campvis {
addWidget(_widget);
onTransferFunctionImageHandleChanged();
updateWidgetFromProperty();
property->getTF()->s_imageHandleChanged.connect(this, &TransferFunctionPropertyWidget::onTransferFunctionImageHandleChanged);
connect(_spinDomainLeft, SIGNAL(valueChanged(double)), this, SLOT(onDomainChanged(double)));
......@@ -101,8 +100,8 @@ namespace campvis {
const ImageDataLocal* idl = dynamic_cast<const ImageDataLocal*>(dh.getData());
if (idl != 0) {
Interval<float> intensityInterval = idl->getNormalizedIntensityRange();
_spinDomainLeft->setMinimum(intensityInterval.getLeft());
_spinDomainRight->setMaximum(intensityInterval.getRight());
// _spinDomainLeft->setMinimum(intensityInterval.getLeft());
// _spinDomainRight->setMaximum(intensityInterval.getRight());
}
}
}
......@@ -113,12 +112,12 @@ namespace campvis {
const tgt::vec2& domain = tf->getIntensityDomain();
_spinDomainLeft->blockSignals(true);
_spinDomainLeft->setMaximum(domain.y);
//_spinDomainLeft->setMaximum(domain.y);
_spinDomainLeft->setValue(domain.x);
_spinDomainLeft->blockSignals(false);
_spinDomainRight->blockSignals(true);
_spinDomainRight->setMinimum(domain.x);
/*_spinDomainRight->setMinimum(domain.x);*/
_spinDomainRight->setValue(domain.y);
_spinDomainRight->blockSignals(false);
}
......@@ -126,8 +125,8 @@ namespace campvis {
void TransferFunctionPropertyWidget::onDomainChanged(double value) {
TransferFunctionProperty* prop = static_cast<TransferFunctionProperty*>(_property);
_ignorePropertyUpdates = true;
_spinDomainLeft->setMaximum(_spinDomainRight->value());
_spinDomainRight->setMinimum(_spinDomainLeft->value());
// _spinDomainLeft->setMaximum(_spinDomainRight->value());
// _spinDomainRight->setMinimum(_spinDomainLeft->value());
tgt::vec2 newDomain(static_cast<float>(_spinDomainLeft->value()), static_cast<float>(_spinDomainRight->value()));
prop->getTF()->setIntensityDomain(newDomain);
_ignorePropertyUpdates = false;
......
......@@ -102,10 +102,31 @@ namespace campvis {
}
_texture->bind();
// TODO: map signed types
// map signed integer types from [-1.0:1.0] to [0.0:1.0] in order to avoid clamping of negative values
if (wtp.isInteger() && wtp.isSigned()) {
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPixelTransferf(GL_RED_SCALE, 0.5f);
glPixelTransferf(GL_GREEN_SCALE, 0.5f);
glPixelTransferf(GL_BLUE_SCALE, 0.5f);
glPixelTransferf(GL_ALPHA_SCALE, 0.5f);
glPixelTransferf(GL_RED_BIAS, 0.5f);
glPixelTransferf(GL_GREEN_BIAS, 0.5f);
glPixelTransferf(GL_BLUE_BIAS, 0.5f);
glPixelTransferf(GL_ALPHA_BIAS, 0.5f);
//pixelTransferMapping_ = RealWorldMapping(0.5f, 0.5f, "");
_mappingInformation.setRealWorldMapping(LinearMapping<float>(.5f, .5f));
}
_texture->uploadTexture();
_texture->setWrapping(tgt::Texture::CLAMP);
// TODO: map signed types
if (wtp.isInteger() && wtp.isSigned()) {
glPopAttrib();
}
// revoke ownership of local pixel data from the texture
_texture->setPixelData(0);
......@@ -145,6 +166,7 @@ namespace campvis {
shader->setUniform(texUniform + "._voxelSize", _mappingInformation.getVoxelSize());
shader->setUniform(texUniform + "._voxelSizeRCP", tgt::vec3(1.f) / _mappingInformation.getVoxelSize());
shader->setUniform(texUniform + "._textureToWorldMatrix", _mappingInformation.getTextureToWorldMatrix());
shader->setUniform(texUniform + "._realWorldMapping", tgt::vec2(_mappingInformation.getRealWorldMapping()._shift, _mappingInformation.getRealWorldMapping()._scale));
break;
default:
......
......@@ -43,6 +43,8 @@ struct Texture3D {
// Transformation matrices
mat4 _textureToWorldMatrix;
vec2 _realWorldMapping;
};
/**
......@@ -77,4 +79,12 @@ vec4 getElement3DNormalized(in Texture3D tex, in vec3 texCoords) {
*/
vec4 textureToWorld(in Texture3D tex, in vec3 texCoords) {
return tex._textureToWorldMatrix * vec4(texCoords, 1.0);
}
\ No newline at end of file
}
float applyRealWorldMapping(Texture3D tex, float value) {
return (value + tex._realWorldMapping.x) * tex._realWorldMapping.y;
}
float applyInverseRealWorldMapping(Texture3D tex, float value) {
return (value - tex._realWorldMapping.x) / tex._realWorldMapping.y;
}
......@@ -315,21 +315,21 @@ namespace {
};
/**
* Template specialization for unsigned integer types, map from [min, max] to [-1.0, 1.0]
* Template specialization for unsigned integer types, map from [min, max] to [0.0, 1.0]
*/
template<>
struct TypeNormalizerHelper<false, true> {
template<typename T>
static float normalizeToFloat(T value) {
if (value >= 0)
return static_cast<float>(value) / std::numeric_limits<T>::max();
return (static_cast<float>(value) / std::numeric_limits<T>::max()) * .5f + .5f;
else
return static_cast<float>(value) / -std::numeric_limits<T>::min();
return (static_cast<float>(value) / -std::numeric_limits<T>::min()) * .5f + .5f;
}
template<typename T>
static T denormalizeFromFloat(float value) {
value = tgt::clamp(value, -1.0f, 1.0f);
value = (tgt::clamp(value, 0.0f, 1.0f) - .5f) * 2.f;
if(value >= 0.0f)
return static_cast<T>(value * std::numeric_limits<T>::max());
else
......
......@@ -264,6 +264,15 @@ namespace campvis {
return CL_A;
}
}
bool WeaklyTypedPointer::isInteger() const {
return (_baseType != FLOAT);
}
bool WeaklyTypedPointer::isSigned() const {
return (_baseType == INT8) || (_baseType == INT16) || (_baseType == INT32);
}
#endif
}
......@@ -120,6 +120,10 @@ namespace campvis {
GLint getGlInternalFormat() const;
bool isInteger() const;
bool isSigned() const;
#ifdef HAS_KISSCL
cl_channel_type getClChannelType() const;
......
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