For a while I've been using RGB images in 32 bits floating point precision in textures with QOpenGLTexture. I had no trouble with it. Originally those images have an unsigned short data type, and I'd liketo keep this data type for sending the data to openGL (BTW, does it actually save some memory at all to do that?). After many attempts, I can't get QOpenGLTexture to display the image. All I end up with is a black image. Below is how I setup QOpenGLTexture. The parts that used floating points, and that worked so far, is commented out. The part that assumes images in 16 bits unsigned integers, is right below the latter, uncommented. I'm using OpenGL 3.3, GLSL 330, core profile, on a macbook pro retina with Iris graphics.
QOpenGLTexture *oglt = new QOpenGLTexture(QOpenGLTexture::Target2D);
oglt->setMinificationFilter(QOpenGLTexture::NearestMipMapNearest);
oglt->setMagnificationFilter(QOpenGLTexture::NearestMipMapNearest);
//oglt->setFormat(QOpenGLTexture::RGB32F); // works
oglt->setFormat(QOpenGLTexture::RGB16U);
oglt->setSize(naxis1, naxis2);
oglt->setMipLevels(10);
//oglt->allocateStorage(QOpenGLTexture::RGB, QOpenGLTexture::Float32); // works
//oglt->setData(QOpenGLTexture::RGB, QOpenGLTexture::Float32, tempImageRGB.data); // works
oglt->allocateStorage(QOpenGLTexture::RGB_Integer, QOpenGLTexture::UInt16);
oglt->setData(QOpenGLTexture::RGB_Integer, QOpenGLTexture::UInt16, tempImageRGB.data);
So, in just these lines above, is there something wrong?
My data in tempImageRGB.data
are between [0-65535] when I used UInt16
. When I use QOpenGLTexture::Float32, the values in tempImageRGB.data
are already normalized so they would be within [0-1].
Then, here is my fragment shader:
#version 330 core
in mediump vec2 TexCoord;
out vec4 color;
uniform mediump sampler2D ourTexture;
void main()
{
mediump vec3 textureColor = texture(ourTexture, TexCoord).rgb;
color = vec4(textureColor, 1.0);
}
What am I missing?
It seems I fixed the problem by simply not using NearestMipMapNearest
for magnification filter. Things work if I only use it for the minification. While in general it makes sense but I don't understand why I had no problem when using NearestMipMapNearest
for both Magnification and Minification in the floating point case.
So, the code is working by simply changing 'sampler2D' to 'usampler2D' in the shader, by changing 'setMagnificationFilter(QOpenGLTexture::NearestMipMapNearest)' into 'setMagnificationFilter(QOpenGLTexture::Nearest)'. The minification filter does not need to change. In addition, although it works with and without, I did not need to set the MipMapLevels explicitly so I can remove oglt->setMipLevels(10)
.
To be clear, here is the corrected code:
QOpenGLTexture *oglt = new QOpenGLTexture(QOpenGLTexture::Target2D);
oglt->setMinificationFilter(QOpenGLTexture::NearestMipMapNearest);
oglt->setMagnificationFilter(QOpenGLTexture::Nearest);
//oglt->setFormat(QOpenGLTexture::RGB32F); // works
oglt->setFormat(QOpenGLTexture::RGB16U); // now works with integer images (unsigned)
oglt->setSize(naxis1, naxis2);
//oglt->allocateStorage(QOpenGLTexture::RGB, QOpenGLTexture::Float32); // works
//oglt->setData(QOpenGLTexture::RGB, QOpenGLTexture::Float32, tempImageRGB.data); // works
oglt->allocateStorage(QOpenGLTexture::RGB_Integer, QOpenGLTexture::UInt16); // now works with integer images (unsigned)
oglt->setData(QOpenGLTexture::RGB_Integer, QOpenGLTexture::UInt16, tempImageRGB.data); // now works with integer images (unsigned)
The fragment shader becomes simply:
#version 330 core
in mediump vec2 TexCoord;
out vec4 color;
uniform mediump usampler2D ourTexture;
void main()
{
mediump vec3 textureColor = texture(ourTexture, TexCoord).rgb;
color = vec4(textureColor, 1.0);
}