Date
1  9 of 9
Problems using OCIO with QT and QtOpenGLWidget
haggi@...
Hi,
I try to make a simple imageviewer with the help of QT and ocio. From the ociodisplay.cpp I tried to extract the needed pieces and transfer it to a Qt workflow. Displaying pictures with OpenGl seems to work fine. But since the QtOpengl workflow is a little bit different, I suppose I make some mistakes because as soon as I try to use the ocio fragment shader, the image becomes black. If someone could give me a hint I'd really appreciate it. The cpp code of an example and the whole question can be found here. https://stackoverflow.com/questions/58857698/qtopenglwidgetwithopencoloriogpuresultsinblackimage


haggi@...
Found a possible reason for the black image. In the fragment shader code generated by ocio which look like this:
vec4 OCIODisplayA(vec4 inPixel, sampler3D lut3d){ vec4 out_pixel = inPixel; out_pixel.rgb = max(vec3(1.17549e38, 1.17549e38, 1.17549e38), vec3(1, 1, 1) * out_pixel.rgb + vec3(0, 0, 0)); out_pixel.rgb = vec3(1.4427, 1.4427, 1.4427) * log(out_pixel.rgb) + vec3(0, 0, 0); out_pixel = vec4(0.047619, 0.047619, 0.047619, 1) * out_pixel; out_pixel = vec4(0.714286, 0.714286, 0.714286, 0) + out_pixel; out_pixel.rgb = texture3D(lut3d, 0.96875 * out_pixel.rgb + 0.015625).rgb; return out_pixel; } The line line out_pixel.rgb = vec3(1.4427, 1.4427, 1.4427) * log(out_pixel.rgb) + vec3(0, 0, 0); results in a black color what means log(out_pixel.rgb) is zero. Any ideas why this is the case?


Patrick Hodoul
Hi,
As a first investigation step, did you try using `ociodisplay` directly (i.e. asis):
The fragment shader code is perfectly fine (MatrixOp + LogOp + Lut3DOp), and it compiles so I can only think of something related to the OpenGL setup and/or Input texture definition. Regards, Patrick


haggi@...
Thanks Patrick,
you are right, the result of the log is black because the values are negative, it works correclty.. stupid me. So it has something to do with the lookup table. Is there any way to check the content of the 3d texture in opengl? I tried it with this fragement shader: varying vec2 vTexCoord; uniform sampler2D tex1; uniform sampler3D tex2; void main() { vec3 t = vec3(vTexCoord, 0.0); gl_FragColor = abs(texture3D(tex2, t)); } to get part of the content of the 3d texture. Even if the content does not make any sense, I should see something if the content is not 0.0, is this correct? So if I see nothing, the 3d texture is black.


haggi@...
The above code gives me black pixels even if the lut3dTex is filled with values of 1.0 so there must be a problem with the usage of the 3dtexture and Qt.


haggi@...
So I was able to find out that the 3d texture behaves correctly as much as I can say. At least if I fill it with random values and read it in the fragment shader with:
vec4 col = texture3D(tex1, vec3(vTexCoord.st, 0)); I get the expected results. So if I now use the ocio generated shader I get an GL_INVALID_OPERATION during drawing. The problem lies here: vec4 OCIODisplay(vec4 inPixel, sampler3D lut3d) { vec4 out_pixel = inPixel; out_pixel.rgb = max(vec3(1.17549e38, 1.17549e38, 1.17549e38), vec3(1, 1, 1) * out_pixel.rgb + vec3(0, 0, 0)); out_pixel.rgb = vec3(1.4427, 1.4427, 1.4427) * log(out_pixel.rgb) + vec3(0, 0, 0); out_pixel = vec4(0.047619, 0.047619, 0.047619, 1) * out_pixel; out_pixel = vec4(0.714286, 0.714286, 0.714286, 0) + out_pixel; out_pixel.rgb = texture3D(lut3d, 0.96875 * out_pixel.rgb + 0.015625).rgb; return out_pixel; } The line: out_pixel.rgb = texture3D(lut3d, 0.96875 * out_pixel.rgb + 0.015625).rgb; produces the GL_INVALID_OPERATION error. If I exchange the 0.96875 * out_pixel.rgb + 0.015625 with something like vec3(.5, .5, .5) I get no error and a solid color as expected. So now I have no idea what I can do.


Patrick Hodoul
Hi Haggi,
https://stackoverflow.com/questions/58857698/qtopenglwidgetwithopencoloriogpuresultsinblackimageThe thread disappeared from stackoverflow so I do not have access to all the source code anymore. vec4 col = texture3D(tex1, vec3(vTexCoord.st, 0));The default implementation from ociodisplay is tex1 for the image texture (the 2D texture), and tex2 for the 3D LUT texture (the 3D texture). Here is the default GLSL ociodisplay fragment shader code: // Generated by OpenColorIO
vec4 OCIODisplay(vec4 inPixel,
sampler3D lut3d)
{
vec4 out_pixel = inPixel;
out_pixel.rgb = max(vec3(1.17549e38, 1.17549e38, 1.17549e38), vec3(1, 1, 1) * out_pixel.rgb + vec3(0.00390625, 0.00390625, 0.00390625));
out_pixel.rgb = vec3(1.4427, 1.4427, 1.4427) * log(out_pixel.rgb) + vec3(0, 0, 0);
out_pixel = vec4(0.0769231, 0.0769231, 0.0769231, 1) * out_pixel;
out_pixel = vec4(0.615385, 0.615385, 0.615385, 0) + out_pixel;
out_pixel.rgb = texture3D(lut3d, 0.96875 * out_pixel.rgb + 0.015625).rgb;
return out_pixel;
}
uniform sampler2D tex1;
uniform sampler3D tex2;
void main()
{
vec4 col = texture2D(tex1, gl_TexCoord[0].st);
gl_FragColor = OCIODisplay(col, tex2);
}
Using the wrong sampler could be an explanation as well as not binding resources. In plain OpenGL, the code for the latter is: glUseProgram(g_program);
glUniform1i(glGetUniformLocation(g_program, "tex1"), 1);
glUniform1i(glGetUniformLocation(g_program, "tex2"), 2);
Note: There is another similar thread on stackoverflow, is that the same problem? https://stackoverflow.com/questions/58879364/howcanisolveglinvalidoperationerrorwithqopenglwidget Regards, Patrick


haggi@...
Sorry, that's my fault. Yes, indeed, I deleted the original question because the problem has a completely different reason I think. I added some more glGerError() functions and discovered an error during openGl drawing process which is called GL_INVALID_OPERATION. The 2d and 3d textures are fine, the only remaining problem is the described one in the new stackoverflow question you mentioned. I removed the ocio code to reduce it to a minimum code. So the problem is simply my insufficient knowledge of OpenGL I suppose.


Patrick Hodoul
No problem. Asking a question is also a way to learn.

