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 Qt-Opengl 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/qtopenglwidget-with-opencolorio-gpu-results-in-black-image

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 Qt-Opengl 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/qtopenglwidget-with-opencolorio-gpu-results-in-black-image

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.17549e-38, 1.17549e-38, 1.17549e-38), 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?

vec4 OCIODisplayA(vec4 inPixel, sampler3D lut3d){

vec4 out_pixel = inPixel;

out_pixel.rgb = max(vec3(1.17549e-38, 1.17549e-38, 1.17549e-38), 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. as-is):

Regards,

Patrick

As a first investigation step, did you try using `ociodisplay` directly (i.e. as-is):

- `set OCIO=C:/daten/coding/imgview/imgView/AE_OCIO/config.ocio`
- `ociodisplay.exe -v c:/daten/testBilder/bake.jpg` where `-v` displays extra information
- Select the same color space

**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.

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@...

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.17549e-38, 1.17549e-38, 1.17549e-38), 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.

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.17549e-38, 1.17549e-38, 1.17549e-38), 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,

Here is the default GLSL ociodisplay fragment shader code:

Using the wrong sampler could be an explanation as well as not binding resources. In plain OpenGL, the code for the latter is:

There is another similar thread on stackoverflow, is that the same problem?

https://stackoverflow.com/questions/58879364/how-can-i-solve-gl-invalid-operation-error-with-qopenglwidget

Regards,

Patrick

https://stackoverflow.com/questions/58857698/qtopenglwidget-with-opencolorio-gpu-results-in-black-imageThe 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.17549e-38, 1.17549e-38, 1.17549e-38), 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/how-can-i-solve-gl-invalid-operation-error-with-qopenglwidget

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.