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