C++ Qt5,带QOpenGLTexture和16位整数图像
一段时间以来,我一直在使用32位浮点精度的RGB图像和QOpenGLTexture纹理。我对此没有任何问题。 最初,这些图像有一个无符号的短数据类型,我想保留这个数据类型,以便将数据发送到openGL(顺便说一句,这样做是否真的节省了一些内存?)。经过多次尝试后,我无法让QOpenGLTexture显示图像。我最后得到的只是一张黑色的照片。 下面是我如何设置QOpenGLTexture的。使用浮点的部分,以及到目前为止有效的部分,都被注释掉了。假定图像为16位无符号整数的部分位于后者的正下方,未注释。我正在MacBookPro视网膜上使用OpenGL3.3、GLSL330、核心配置文件和虹膜图形C++ Qt5,带QOpenGLTexture和16位整数图像,c++,opengl,textures,qt5,C++,Opengl,Textures,Qt5,一段时间以来,我一直在使用32位浮点精度的RGB图像和QOpenGLTexture纹理。我对此没有任何问题。 最初,这些图像有一个无符号的短数据类型,我想保留这个数据类型,以便将数据发送到openGL(顺便说一句,这样做是否真的节省了一些内存?)。经过多次尝试后,我无法让QOpenGLTexture显示图像。我最后得到的只是一张黑色的照片。 下面是我如何设置QOpenGLTexture的。使用浮点的部分,以及到目前为止有效的部分,都被注释掉了。假定图像为16位无符号整数的部分位于后者的正下方,未
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);
那么,就在上面这几行,有什么问题吗?
使用UInt16
时,我在tempmagergb.data
中的数据介于[0-65535]之间。当我使用QOpenGLTexture::Float32时,tempImageRGB.data
中的值已经标准化,因此它们将在[0-1]范围内
然后,这里是我的片段着色器:
#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);
}
我错过了什么 我似乎通过简单地不使用放大过滤器的
nearestmipmappnearest
解决了这个问题。如果我只用它来缩小尺寸,一切都会好起来的。虽然一般来说这是有道理的,但我不明白为什么在浮点情况下使用nearestmipmappnearest
进行放大和缩小时没有问题
因此,代码只需在着色器中将“sampler2D”更改为“usampler2D”,将“Set放大过滤器(QOpenGLTexture::NearestMipMapNearest)”更改为“Set放大过滤器(QOpenGLTexture::NearestMipMapNearest)”。缩小过滤器不需要更改。此外,尽管它可以使用和不使用MipMapLevels,但我不需要显式设置MipMapLevels,这样我就可以删除oglt->setMipLevels(10)
为了清楚起见,以下是更正的代码:
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)
片段着色器变得简单:
#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);
}
我似乎通过简单地不使用放大过滤器的
nearestmipmappnearest
解决了这个问题。如果我只用它来缩小尺寸,一切都会好起来的。虽然一般来说这是有道理的,但我不明白为什么在浮点情况下使用nearestmipmappnearest
进行放大和缩小时没有问题
因此,代码只需在着色器中将“sampler2D”更改为“usampler2D”,将“Set放大过滤器(QOpenGLTexture::NearestMipMapNearest)”更改为“Set放大过滤器(QOpenGLTexture::NearestMipMapNearest)”。缩小过滤器不需要更改。此外,尽管它可以使用和不使用MipMapLevels,但我不需要显式设置MipMapLevels,这样我就可以删除oglt->setMipLevels(10)
为了清楚起见,以下是更正的代码:
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)
片段着色器变得简单:
#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);
}
我只是好奇为什么像第一种情况那样使用
QOpenGLTexture::RGB_Integer
而不是QOpenGLTexture::RGB
?我没有太多地使用这种想法,因为opengl文档告诉我要使用它。事实上我两个都试过了。使用以下纯gl命令:GLTEXAGE2D(gl_纹理_2D,0,gl_RGB16UI,naxis1,naxis2,0,gl_RGB_整数,gl_无符号_短,matImageRGB16.data)代码>工作正常。使用“纯”openGL命令(使用glTexImage2D等),我意识到我必须使用usampler2D
而不是sample2D
。但这仍然不能解决使用QOpenGLTexture时的问题。好吧,只是一个想法-您是否尝试创建QImage并在setData方法中使用它进行更改?QImage有零拷贝构造函数。@很遗憾,QImage不支持每个通道16位的图像。我只是好奇为什么您使用QOpenGLTexture::RGB_Integer
而不是第一种情况下的QOpenGLTexture::RGB
?我没有太多地使用这种想法,因为opengl文档告诉我要使用它。事实上我两个都试过了。使用以下纯gl命令:GLTEXAGE2D(gl_纹理_2D,0,gl_RGB16UI,naxis1,naxis2,0,gl_RGB_整数,gl_无符号_短,matImageRGB16.data)代码>工作正常。使用“纯”openGL命令(使用glTexImage2D等),我意识到我必须使用usampler2D
而不是sample2D
。但这仍然不能解决使用QOpenGLTexture时的问题。好吧,只是一个想法-您是否尝试创建QImage并在setData方法中使用它进行更改?QImage有零拷贝构造函数。@rightaway717不幸的是,QImage不支持每个通道16位的图像。请注意。通过在mac上使用openGL profiler,我发现放大过滤器是罪魁祸首。“OpenGL错误中断”的设置向我显示OpenGL在glTexParameteri停止,并证明放大过滤器设置存在问题。只是一个旁注。通过在mac上使用openGL profiler,我发现放大过滤器是罪魁祸首。“OpenGL错误中断”的设置向我显示OpenGL在glTexParameteri停止,并证明放大过滤器设置存在问题。