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

* Fixed GLReduction computing wrong values due to missing texture clamping

* Updated DepthDarkening to use GlReduction to compute min/max depth
parent 8fa3a1ab
......@@ -195,7 +195,7 @@ namespace campvis {
}
_texture->uploadTexture();
_texture->setWrapping(tgt::Texture::CLAMP);
_texture->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
if (isInteger && isSigned) {
// restore default
......
......@@ -33,17 +33,15 @@ out vec4 out_Color;
#include "tools/texture2d.frag"
uniform sampler2D _texture;
uniform TextureParameters2D _textureParams;
uniform vec2 _texCoordsMultiplier;
uniform vec2 _texCoordsShift;
void main() {
vec2 tmp = ex_TexCoord.xy * _texCoordsMultiplier * 2.0;
ivec2 texel = ivec2((tmp * _textureParams._size));
vec2 tmp = ex_TexCoord.xy - _texCoordsShift;
vec4 a = texelFetch(_texture, texel, 0);
vec4 b = texelFetch(_texture, texel + ivec2(1, 0), 0);
vec4 c = texelFetch(_texture, texel + ivec2(0, 1), 0);
vec4 d = texelFetch(_texture, texel + ivec2(1, 1), 0);
vec4 a = texture(_texture, tmp);
vec4 b = textureOffset(_texture, tmp, ivec2(1, 0));
vec4 c = textureOffset(_texture, tmp, ivec2(0, 1));
vec4 d = textureOffset(_texture, tmp, ivec2(1, 1));
out_Color = REDUCTION_OP(a, b, c, d);
}
......@@ -108,6 +108,7 @@ namespace campvis {
break;
#ifdef GL_DEPTH_COMPONENT32F
case GL_DEPTH_COMPONENT32F:
tex = new tgt::Texture(0, getRenderTargetSize(), GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT32F, GL_FLOAT, tgt::Texture::LINEAR);
break;
#endif
......
......@@ -102,11 +102,11 @@ namespace campvis {
tgtAssert(texture->getDimensions().z == 1, "Reduction of 3D images not yet implemented! Somebody was too lazy (or stressed - deadline was close) to do that...");
std::vector<float> readBackBuffer;
const tgt::ivec3& size = texture->getDimensions();
tgt::vec2 texCoordMultiplier(1.f);
tgt::vec2 texCoordShift = tgt::vec2(.5f) / tgt::vec2(size.xy());
tgt::ivec2 currentSize = size.xy();
reduceSizes(currentSize, texCoordMultiplier);
reduceSizes(currentSize, texCoordShift);
tgt::ivec2 startSize = currentSize;
// Set OpenGL pixel alignment to 1 to avoid problems with NPOT textures
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
......@@ -119,7 +119,7 @@ namespace campvis {
for (size_t i = 0; i < 2; ++i) {
tempTextures[i] = new tgt::Texture(0, tgt::ivec3(currentSize, 1), GL_RGBA, GL_RGBA32F, GL_FLOAT, tgt::Texture::NEAREST);
tempTextures[i]->uploadTexture();
tempTextures[i]->setWrapping(tgt::Texture::CLAMP);
tempTextures[i]->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
}
size_t readTex = 0;
size_t writeTex = 1;
......@@ -133,33 +133,27 @@ namespace campvis {
_shader->activate();
_fbo->attachTexture(tempTextures[readTex]);
_shader->setIgnoreUniformLocationError(true);
inputUnit.activate();
texture->bind();
_shader->setUniform("_texture", inputUnit.getUnitNumber());
_shader->setUniform("_textureParams._size", tgt::vec2(size.xy()));
_shader->setUniform("_textureParams._sizeRCP", tgt::vec2(1.f) / tgt::vec2(size.xy()));
_shader->setUniform("_textureParams._numChannels", static_cast<int>(texture->getNumChannels()));
_shader->setIgnoreUniformLocationError(false);
glViewport(0, 0, currentSize.x, currentSize.y);
_shader->setUniform("_texCoordsMultiplier", texCoordMultiplier);
_shader->setUniform("_texCoordsShift", texCoordShift);
glViewport(startSize.x - currentSize.x, startSize.y - currentSize.y, currentSize.x, currentSize.y);
QuadRdr.renderQuad();
LGL_ERROR;
reduceSizes(currentSize, texCoordShift);
glViewport(startSize.x - currentSize.x, startSize.y - currentSize.y, currentSize.x, currentSize.y);
// perform reduction until 1x1 texture remains
while (currentSize.x > 1 || currentSize.y > 1) {
reduceSizes(currentSize, texCoordMultiplier);
_fbo->attachTexture(tempTextures[writeTex]);
tempTextures[readTex]->bind();
glViewport(0, 0, currentSize.x, currentSize.y);
_shader->setUniform("_texCoordsMultiplier", texCoordMultiplier);
_shader->setUniform("_texCoordsShift", texCoordShift);
QuadRdr.renderQuad();
LGL_ERROR;
//_fbo->detachTexture(GL_COLOR_ATTACHMENT0);
reduceSizes(currentSize, texCoordShift);
std::swap(writeTex, readTex);
}
......@@ -171,7 +165,7 @@ namespace campvis {
size_t channels = tempTextures[readTex]->getNumChannels();
toReturn.resize(currentSize.x * currentSize.y * channels);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(0, 0, currentSize.x, currentSize.y, readBackFormat, GL_FLOAT, &toReturn.front());
glReadPixels(startSize.x - currentSize.x, startSize.y - currentSize.y, currentSize.x, currentSize.y, readBackFormat, GL_FLOAT, &toReturn.front());
LGL_ERROR;
// clean up...
......@@ -187,14 +181,16 @@ namespace campvis {
return toReturn;
}
void GlReduction::reduceSizes(tgt::ivec2& currentSize, tgt::vec2& texCoordMultiplier) {
void GlReduction::reduceSizes(tgt::ivec2& currentSize, tgt::vec2& texCoordShift) {
if (currentSize.x > 1) {
currentSize.x = DIV_CEIL(currentSize.x, 2);
texCoordMultiplier.x /= 2.f;
if (currentSize.x == 1)
texCoordShift.x *= -1.f;
}
if (currentSize.y > 1) {
currentSize.y = DIV_CEIL(currentSize.y, 2);
texCoordMultiplier.y /= 2.f;
if (currentSize.y == 1)
texCoordShift.y *= -1.f;
}
}
......@@ -213,6 +209,9 @@ namespace campvis {
case MULTIPLICATION:
return "#define REDUCTION_OP(a, b, c, d) a*b*c*d";
break;
case MIN_MAX:
return "#define REDUCTION_OP(a, b, c, d) vec4(min(a.r, min(b.r, min(c.r, d.r))), max(a.g, max(b.g, max(c.g, d.g))), 0.0, 0.0)";
break;
default:
tgtAssert(false, "Should not reach this, wrong enum value?");
return "";
......
......@@ -58,7 +58,8 @@ namespace campvis {
MIN, ///< Minimum
MAX, ///< Maximum
PLUS, ///< Sum (plus)
MULTIPLICATION ///< Product (multiplication)
MULTIPLICATION, ///< Product (multiplication)
MIN_MAX ///< Minimum/Maximum (WORKS ONLY with single channel images!)
};
/**
......
......@@ -35,7 +35,7 @@
#include "core/datastructures/imagedata.h"
#include "core/datastructures/imagerepresentationgl.h"
#include "core/datastructures/renderdata.h"
#include "core/tools/glreduction.h"
#include "core/classification/simpletransferfunction.h"
......@@ -50,10 +50,11 @@ namespace campvis {
, p_outputImage("OutputImage", "Output Image", "dd.output", DataNameProperty::WRITE)
, p_sigma("Sigma", "Sigma of Gaussian Filter", 2.f, 0.f, 10.f, 0.1f)
, p_lambda("Lambda", "Strength of Depth Darkening Effect", 10.f, 0.f, 50.f, 0.1f)
, p_useColorCoding("UseColorCoding", "Cold/Warm Color Coding", false, AbstractProcessor::INVALID_SHADER)
, p_useColorCoding("UseColorCoding", "Cold/Warm Color Coding", false, AbstractProcessor::INVALID_RESULT | AbstractProcessor::INVALID_SHADER)
, p_coldColor("ColdColor", "Cold Color (Far Objects)", tgt::vec3(0.f, 0.f, 1.f), tgt::vec3(0.f), tgt::vec3(1.f))
, p_warmColor("WarmColor", "Warm Color (Near Objects)", tgt::vec3(1.f, 0.f, 0.f), tgt::vec3(0.f), tgt::vec3(1.f))
, _shader(0)
, _glReduction(0)
{
addProperty(&p_inputImage);
addProperty(&p_outputImage);
......@@ -73,11 +74,14 @@ namespace campvis {
_shader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "modules/vis/glsl/depthdarkening.frag", generateHeader(), false);
_shader->setAttributeLocation(0, "in_Position");
_shader->setAttributeLocation(1, "in_TexCoord");
_glReduction = new GlReduction(GlReduction::MIN_MAX);
}
void DepthDarkening::deinit() {
VisualizationProcessor::deinit();
ShdrMgr.dispose(_shader);
delete _glReduction;
VisualizationProcessor::deinit();
}
void DepthDarkening::process(DataContainer& data) {
......@@ -90,19 +94,10 @@ namespace campvis {
validate(INVALID_SHADER);
}
// TODO: const cast is ugly...
const tgt::Texture* tex = inputImage->getDepthTexture()->getRepresentation<ImageRepresentationGL>()->getTexture();
const_cast<tgt::Texture*>(tex)->downloadTexture();
const float* pixels = reinterpret_cast<const float*>(tex->getPixelData());
float curDepth = *(pixels);
float minDepth = curDepth;
float maxDepth = curDepth;
size_t numPixels = inputImage->getDepthTexture()->getNumElements();
for (size_t i = 1; i < numPixels; ++i) {
curDepth = pixels[i];
minDepth = std::min(minDepth, curDepth);
maxDepth = std::max(maxDepth, curDepth);
}
std::vector<float> tmp = _glReduction->reduce(tex);
float minDepth = tmp[0];
float maxDepth = tmp[1];
FramebufferActivationGuard fag(this);
glEnable(GL_DEPTH_TEST);
......
......@@ -42,6 +42,7 @@ namespace tgt {
namespace campvis {
class ImageData;
class GlReduction;
/**
* Extracts a slice from a 3D image and renders it into a rendertarget.
......@@ -93,6 +94,7 @@ namespace campvis {
std::string generateHeader() const;
tgt::Shader* _shader; ///< Shader for slice rendering
GlReduction* _glReduction;
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