Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

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

Extended GlReduction to also support the reduction of 3D images.

parent bcdae20a
...@@ -32,16 +32,45 @@ out vec4 out_Color; ...@@ -32,16 +32,45 @@ out vec4 out_Color;
#include "tools/texture2d.frag" #include "tools/texture2d.frag"
uniform sampler2D _texture; #ifdef REDUCTION_2D
uniform vec2 _texCoordsShift; uniform sampler2D _texture;
uniform vec2 _texCoordsShift;
#endif
#ifdef REDUCTION_3D
uniform sampler3D _texture;
uniform vec2 _texCoordsShift;
uniform int _textureDepth;
#endif
void main() { void main() {
vec2 tmp = ex_TexCoord.xy - _texCoordsShift; vec2 tmp = ex_TexCoord.xy - _texCoordsShift;
#ifdef REDUCTION_2D
// 2D reduction:
vec4 a = texture(_texture, tmp); vec4 a = texture(_texture, tmp);
vec4 b = textureOffset(_texture, tmp, ivec2(1, 0)); vec4 b = textureOffset(_texture, tmp, ivec2(1, 0));
vec4 c = textureOffset(_texture, tmp, ivec2(0, 1)); vec4 c = textureOffset(_texture, tmp, ivec2(0, 1));
vec4 d = textureOffset(_texture, tmp, ivec2(1, 1)); vec4 d = textureOffset(_texture, tmp, ivec2(1, 1));
#endif
#ifdef REDUCTION_3D
// 3D reduction along depth:
float textureDepthRCP = 1.0 / _textureDepth;
vec4 a = texture(_texture, vec3(tmp, textureDepthRCP/2.0));
vec4 b = textureOffset(_texture, vec3(tmp, textureDepthRCP/2.0), ivec3(1, 0, 0));
vec4 c = textureOffset(_texture, vec3(tmp, textureDepthRCP/2.0), ivec3(0, 1, 0));
vec4 d = textureOffset(_texture, vec3(tmp, textureDepthRCP/2.0), ivec3(1, 1, 0));
for (float z = 3.0 * textureDepthRCP / 2.0; z < 1.0; z += textureDepthRCP) {
a = REDUCTION_OP_2(a, texture(_texture, vec3(tmp, z)));
b = REDUCTION_OP_2(b, textureOffset(_texture, vec3(tmp, z), ivec3(1, 0, 0)));
c = REDUCTION_OP_2(c, textureOffset(_texture, vec3(tmp, z), ivec3(0, 1, 0)));
d = REDUCTION_OP_2(d, textureOffset(_texture, vec3(tmp, z), ivec3(1, 1, 0)));
}
#endif
out_Color = REDUCTION_OP(a, b, c, d); // final reduction of the four pixels
out_Color = REDUCTION_OP_4(a, b, c, d);
} }
...@@ -50,26 +50,31 @@ namespace campvis { ...@@ -50,26 +50,31 @@ namespace campvis {
GlReduction::GlReduction(ReductionOperator reductionOperator) GlReduction::GlReduction(ReductionOperator reductionOperator)
: _reductionOperator(reductionOperator) : _reductionOperator(reductionOperator)
, _shader(0) , _shader2d(0)
, _shader3d(0)
, _fbo(0) , _fbo(0)
{ {
_shader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "core/glsl/tools/glreduction.frag", generateGlslHeader(_reductionOperator), false); _shader2d = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "core/glsl/tools/glreduction.frag", generateGlslHeader(_reductionOperator) + "#define REDUCTION_2D\n", false);
if (_shader == 0) { _shader3d = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "core/glsl/tools/glreduction.frag", generateGlslHeader(_reductionOperator) + "#define REDUCTION_3D\n", false);
if (_shader2d == 0 || _shader3d == 0) {
LERROR("Could not load Shader for OpenGL reduction. Reduction will not work!"); LERROR("Could not load Shader for OpenGL reduction. Reduction will not work!");
return; return;
} }
_shader->setAttributeLocation(0, "in_Position"); _shader2d->setAttributeLocation(0, "in_Position");
_shader->setAttributeLocation(1, "in_TexCoord"); _shader2d->setAttributeLocation(1, "in_TexCoord");
_shader3d->setAttributeLocation(0, "in_Position");
_shader3d->setAttributeLocation(1, "in_TexCoord");
} }
GlReduction::~GlReduction() { GlReduction::~GlReduction() {
ShdrMgr.dispose(_shader); ShdrMgr.dispose(_shader2d);
ShdrMgr.dispose(_shader3d);
} }
std::vector<float> GlReduction::reduce(const ImageData* image) { std::vector<float> GlReduction::reduce(const ImageData* image) {
tgtAssert(image != 0, "Image must not be 0!"); tgtAssert(image != 0, "Image must not be 0!");
if (_shader == 0) { if (_shader2d == 0 || _shader3d == 0) {
LERROR("Could not load Shader for OpenGL reduction. Reduction will not work!"); LERROR("Could not load Shader for OpenGL reduction. Reduction will not work!");
return std::vector<float>(); return std::vector<float>();
} }
...@@ -91,7 +96,7 @@ namespace campvis { ...@@ -91,7 +96,7 @@ namespace campvis {
std::vector<float> toReturn; std::vector<float> toReturn;
tgtAssert(texture != 0, "Image must not be 0!"); tgtAssert(texture != 0, "Image must not be 0!");
if (_shader == 0) { if (_shader2d == 0 || _shader3d == 0) {
LERROR("Could not load Shader for OpenGL reduction. Reduction will not work!"); LERROR("Could not load Shader for OpenGL reduction. Reduction will not work!");
return toReturn; return toReturn;
} }
...@@ -100,8 +105,6 @@ namespace campvis { ...@@ -100,8 +105,6 @@ namespace campvis {
return toReturn; return toReturn;
} }
tgtAssert(texture->getDimensions().z == 1, "Reduction of 3D images not yet implemented! Somebody was too lazy (or stressed - deadline was close) to do that...");
const tgt::ivec3& size = texture->getDimensions(); const tgt::ivec3& size = texture->getDimensions();
tgt::vec2 texCoordShift = tgt::vec2(.5f) / tgt::vec2(size.xy()); tgt::vec2 texCoordShift = tgt::vec2(.5f) / tgt::vec2(size.xy());
tgt::ivec2 currentSize = size.xy(); tgt::ivec2 currentSize = size.xy();
...@@ -130,17 +133,24 @@ namespace campvis { ...@@ -130,17 +133,24 @@ namespace campvis {
LGL_ERROR; LGL_ERROR;
// perform first reduction step outside: // perform first reduction step outside:
_shader->activate(); tgt::Shader* leShader = (texture->getDimensions().z == 1) ? _shader2d : _shader3d;
leShader->activate();
_fbo->attachTexture(tempTextures[readTex]); _fbo->attachTexture(tempTextures[readTex]);
inputUnit.activate(); inputUnit.activate();
texture->bind(); texture->bind();
_shader->setUniform("_texture", inputUnit.getUnitNumber()); leShader->setUniform("_texture", inputUnit.getUnitNumber());
_shader->setUniform("_texCoordsShift", texCoordShift); leShader->setUniform("_texCoordsShift", texCoordShift);
if (leShader == _shader3d)
leShader->setUniform("_textureDepth", texture->getDimensions().z);
glViewport(startSize.x - currentSize.x, startSize.y - currentSize.y, currentSize.x, currentSize.y); glViewport(startSize.x - currentSize.x, startSize.y - currentSize.y, currentSize.x, currentSize.y);
QuadRdr.renderQuad(); QuadRdr.renderQuad();
leShader->deactivate();
LGL_ERROR; LGL_ERROR;
_shader2d->activate();
_shader2d->setUniform("_texture", inputUnit.getUnitNumber());
reduceSizes(currentSize, texCoordShift); reduceSizes(currentSize, texCoordShift);
glViewport(startSize.x - currentSize.x, startSize.y - currentSize.y, currentSize.x, currentSize.y); glViewport(startSize.x - currentSize.x, startSize.y - currentSize.y, currentSize.x, currentSize.y);
...@@ -149,7 +159,7 @@ namespace campvis { ...@@ -149,7 +159,7 @@ namespace campvis {
_fbo->attachTexture(tempTextures[writeTex]); _fbo->attachTexture(tempTextures[writeTex]);
tempTextures[readTex]->bind(); tempTextures[readTex]->bind();
_shader->setUniform("_texCoordsShift", texCoordShift); _shader2d->setUniform("_texCoordsShift", texCoordShift);
QuadRdr.renderQuad(); QuadRdr.renderQuad();
LGL_ERROR; LGL_ERROR;
...@@ -157,7 +167,7 @@ namespace campvis { ...@@ -157,7 +167,7 @@ namespace campvis {
std::swap(writeTex, readTex); std::swap(writeTex, readTex);
} }
_shader->deactivate(); _shader2d->deactivate();
// read back stuff // read back stuff
...@@ -197,25 +207,35 @@ namespace campvis { ...@@ -197,25 +207,35 @@ namespace campvis {
std::string GlReduction::generateGlslHeader(ReductionOperator reductionOperator) { std::string GlReduction::generateGlslHeader(ReductionOperator reductionOperator) {
switch (reductionOperator) { switch (reductionOperator) {
case MIN: case MIN:
return "#define REDUCTION_OP(a, b, c, d) min(a, min(b, min(c, d)))"; return
break; "#define REDUCTION_OP_2(a, b) min(a, b)\n"
case MAX: "#define REDUCTION_OP_4(a, b, c, d) min(a, min(b, min(c, d)))\n";
return "#define REDUCTION_OP(a, b, c, d) max(a, max(b, max(c, d)))"; break;
break; case MAX:
case PLUS: return
return "#define REDUCTION_OP(a, b, c, d) a+b+c+d"; "#define REDUCTION_OP_2(a, b) max(a, b)\n"
break; "#define REDUCTION_OP_4(a, b, c, d) max(a, max(b, max(c, d)))\n";
case MULTIPLICATION: break;
return "#define REDUCTION_OP(a, b, c, d) a*b*c*d"; case PLUS:
break; return
case MIN_MAX: "#define REDUCTION_OP_2(a, b) a+b\n"
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)"; "#define REDUCTION_OP_4(a, b, c, d) a+b+c+d\n";
break; break;
default: case MULTIPLICATION:
tgtAssert(false, "Should not reach this, wrong enum value?"); return
return ""; "#define REDUCTION_OP_2(a, b) a*b\n"
break; "#define REDUCTION_OP_4(a, b, c, d) a*b*c*d\n";
break;
case MIN_MAX_DEPTH_ONLY:
return
"#define REDUCTION_OP_2(a, b) vec4(min(a.r, b.r), max(a.g, b.g), 0.0, 0.0)\n"
"#define REDUCTION_OP_4(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)\n";
break;
default:
tgtAssert(false, "Should not reach this, wrong enum value?");
return "";
break;
} }
} }
......
...@@ -59,7 +59,7 @@ namespace campvis { ...@@ -59,7 +59,7 @@ namespace campvis {
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!) MIN_MAX_DEPTH_ONLY ///< Minimum/Maximum (CAUTION: WORKS ONLY with depth images!!!)
}; };
/** /**
...@@ -109,7 +109,8 @@ namespace campvis { ...@@ -109,7 +109,8 @@ namespace campvis {
ReductionOperator _reductionOperator; ///< Operation to be performed by reduction ReductionOperator _reductionOperator; ///< Operation to be performed by reduction
tgt::Shader* _shader; ///< OpenGL shader performing the reduction tgt::Shader* _shader2d; ///< OpenGL shader performing 2D reduction
tgt::Shader* _shader3d; ///< OpenGL shader performing 3D reduction
tgt::FramebufferObject* _fbo; ///< FBO performing the reduction tgt::FramebufferObject* _fbo; ///< FBO performing the reduction
const static std::string loggerCat_; const static std::string loggerCat_;
......
...@@ -306,9 +306,9 @@ namespace campvis { ...@@ -306,9 +306,9 @@ namespace campvis {
referenceUnit.activate(); referenceUnit.activate();
// create temporary texture for result // create temporary texture for result
tgt::Texture* similarityTex = new tgt::Texture(0, tgt::ivec3(size), GL_RED, GL_R32F, GL_FLOAT, tgt::Texture::NEAREST); tgt::Texture* differenceImage = new tgt::Texture(0, tgt::ivec3(size), GL_RED, GL_R32F, GL_FLOAT, tgt::Texture::LINEAR);
similarityTex->uploadTexture(); differenceImage->uploadTexture();
similarityTex->setWrapping(tgt::Texture::CLAMP); differenceImage->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
// bind input images // bind input images
_differenceShader->activate(); _differenceShader->activate();
...@@ -328,7 +328,7 @@ namespace campvis { ...@@ -328,7 +328,7 @@ namespace campvis {
for (int z = 0; z < size.z; ++z) { for (int z = 0; z < size.z; ++z) {
float texZ = static_cast<float>(z)/static_cast<float>(size.z) + .5f/static_cast<float>(size.z); float texZ = static_cast<float>(z)/static_cast<float>(size.z) + .5f/static_cast<float>(size.z);
_differenceShader->setUniform("_zTex", texZ); _differenceShader->setUniform("_zTex", texZ);
_fbo->attachTexture(similarityTex, GL_COLOR_ATTACHMENT0, 0, z); _fbo->attachTexture(differenceImage, GL_COLOR_ATTACHMENT0, 0, z);
QuadRdr.renderQuad(); QuadRdr.renderQuad();
} }
_differenceShader->deactivate(); _differenceShader->deactivate();
...@@ -336,7 +336,7 @@ namespace campvis { ...@@ -336,7 +336,7 @@ namespace campvis {
// put difference image into DataContainer // put difference image into DataContainer
ImageData* id = new ImageData(3, size, 1); ImageData* id = new ImageData(3, size, 1);
ImageRepresentationGL::create(id, similarityTex); ImageRepresentationGL::create(id, differenceImage);
id->setMappingInformation(referenceImage->getParent()->getMappingInformation()); id->setMappingInformation(referenceImage->getParent()->getMappingInformation());
dc->addData(p_differenceImageId.getValue(), id); dc->addData(p_differenceImageId.getValue(), id);
......
...@@ -75,7 +75,7 @@ namespace campvis { ...@@ -75,7 +75,7 @@ namespace campvis {
_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); _glReduction = new GlReduction(GlReduction::MIN_MAX_DEPTH_ONLY);
} }
void DepthDarkening::deinit() { void DepthDarkening::deinit() {
......
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