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;
#include "tools/texture2d.frag"
uniform sampler2D _texture;
uniform vec2 _texCoordsShift;
#ifdef REDUCTION_2D
uniform sampler2D _texture;
uniform vec2 _texCoordsShift;
#endif
#ifdef REDUCTION_3D
uniform sampler3D _texture;
uniform vec2 _texCoordsShift;
uniform int _textureDepth;
#endif
void main() {
vec2 tmp = ex_TexCoord.xy - _texCoordsShift;
#ifdef REDUCTION_2D
// 2D reduction:
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));
#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 {
GlReduction::GlReduction(ReductionOperator reductionOperator)
: _reductionOperator(reductionOperator)
, _shader(0)
, _shader2d(0)
, _shader3d(0)
, _fbo(0)
{
_shader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "core/glsl/tools/glreduction.frag", generateGlslHeader(_reductionOperator), false);
if (_shader == 0) {
_shader2d = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "core/glsl/tools/glreduction.frag", generateGlslHeader(_reductionOperator) + "#define REDUCTION_2D\n", false);
_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!");
return;
}
_shader->setAttributeLocation(0, "in_Position");
_shader->setAttributeLocation(1, "in_TexCoord");
_shader2d->setAttributeLocation(0, "in_Position");
_shader2d->setAttributeLocation(1, "in_TexCoord");
_shader3d->setAttributeLocation(0, "in_Position");
_shader3d->setAttributeLocation(1, "in_TexCoord");
}
GlReduction::~GlReduction() {
ShdrMgr.dispose(_shader);
ShdrMgr.dispose(_shader2d);
ShdrMgr.dispose(_shader3d);
}
std::vector<float> GlReduction::reduce(const ImageData* image) {
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!");
return std::vector<float>();
}
......@@ -91,7 +96,7 @@ namespace campvis {
std::vector<float> toReturn;
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!");
return toReturn;
}
......@@ -100,8 +105,6 @@ namespace campvis {
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();
tgt::vec2 texCoordShift = tgt::vec2(.5f) / tgt::vec2(size.xy());
tgt::ivec2 currentSize = size.xy();
......@@ -130,17 +133,24 @@ namespace campvis {
LGL_ERROR;
// perform first reduction step outside:
_shader->activate();
tgt::Shader* leShader = (texture->getDimensions().z == 1) ? _shader2d : _shader3d;
leShader->activate();
_fbo->attachTexture(tempTextures[readTex]);
inputUnit.activate();
texture->bind();
_shader->setUniform("_texture", inputUnit.getUnitNumber());
_shader->setUniform("_texCoordsShift", texCoordShift);
leShader->setUniform("_texture", inputUnit.getUnitNumber());
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);
QuadRdr.renderQuad();
leShader->deactivate();
LGL_ERROR;
_shader2d->activate();
_shader2d->setUniform("_texture", inputUnit.getUnitNumber());
reduceSizes(currentSize, texCoordShift);
glViewport(startSize.x - currentSize.x, startSize.y - currentSize.y, currentSize.x, currentSize.y);
......@@ -149,7 +159,7 @@ namespace campvis {
_fbo->attachTexture(tempTextures[writeTex]);
tempTextures[readTex]->bind();
_shader->setUniform("_texCoordsShift", texCoordShift);
_shader2d->setUniform("_texCoordsShift", texCoordShift);
QuadRdr.renderQuad();
LGL_ERROR;
......@@ -157,7 +167,7 @@ namespace campvis {
std::swap(writeTex, readTex);
}
_shader->deactivate();
_shader2d->deactivate();
// read back stuff
......@@ -198,19 +208,29 @@ namespace campvis {
std::string GlReduction::generateGlslHeader(ReductionOperator reductionOperator) {
switch (reductionOperator) {
case MIN:
return "#define REDUCTION_OP(a, b, c, d) min(a, min(b, min(c, d)))";
return
"#define REDUCTION_OP_2(a, b) min(a, b)\n"
"#define REDUCTION_OP_4(a, b, c, d) min(a, min(b, min(c, d)))\n";
break;
case MAX:
return "#define REDUCTION_OP(a, b, c, d) max(a, max(b, max(c, d)))";
return
"#define REDUCTION_OP_2(a, b) max(a, b)\n"
"#define REDUCTION_OP_4(a, b, c, d) max(a, max(b, max(c, d)))\n";
break;
case PLUS:
return "#define REDUCTION_OP(a, b, c, d) a+b+c+d";
return
"#define REDUCTION_OP_2(a, b) a+b\n"
"#define REDUCTION_OP_4(a, b, c, d) a+b+c+d\n";
break;
case MULTIPLICATION:
return "#define REDUCTION_OP(a, b, c, d) a*b*c*d";
return
"#define REDUCTION_OP_2(a, b) a*b\n"
"#define REDUCTION_OP_4(a, b, c, d) a*b*c*d\n";
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)";
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?");
......
......@@ -59,7 +59,7 @@ namespace campvis {
MAX, ///< Maximum
PLUS, ///< Sum (plus)
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 {
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
const static std::string loggerCat_;
......
......@@ -306,9 +306,9 @@ namespace campvis {
referenceUnit.activate();
// create temporary texture for result
tgt::Texture* similarityTex = new tgt::Texture(0, tgt::ivec3(size), GL_RED, GL_R32F, GL_FLOAT, tgt::Texture::NEAREST);
similarityTex->uploadTexture();
similarityTex->setWrapping(tgt::Texture::CLAMP);
tgt::Texture* differenceImage = new tgt::Texture(0, tgt::ivec3(size), GL_RED, GL_R32F, GL_FLOAT, tgt::Texture::LINEAR);
differenceImage->uploadTexture();
differenceImage->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
// bind input images
_differenceShader->activate();
......@@ -328,7 +328,7 @@ namespace campvis {
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);
_differenceShader->setUniform("_zTex", texZ);
_fbo->attachTexture(similarityTex, GL_COLOR_ATTACHMENT0, 0, z);
_fbo->attachTexture(differenceImage, GL_COLOR_ATTACHMENT0, 0, z);
QuadRdr.renderQuad();
}
_differenceShader->deactivate();
......@@ -336,7 +336,7 @@ namespace campvis {
// put difference image into DataContainer
ImageData* id = new ImageData(3, size, 1);
ImageRepresentationGL::create(id, similarityTex);
ImageRepresentationGL::create(id, differenceImage);
id->setMappingInformation(referenceImage->getParent()->getMappingInformation());
dc->addData(p_differenceImageId.getValue(), id);
......
......@@ -75,7 +75,7 @@ namespace campvis {
_shader->setAttributeLocation(0, "in_Position");
_shader->setAttributeLocation(1, "in_TexCoord");
_glReduction = new GlReduction(GlReduction::MIN_MAX);
_glReduction = new GlReduction(GlReduction::MIN_MAX_DEPTH_ONLY);
}
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