每次我尝试使用 Qt QOpenGLTexture
上传具有多个 mipmap 级别的 DXT1
纹理时,我都会收到 GL_INVALID_OPERATION
。对于 mipmap 级别 0,一切正常,但对于任何其他级别,我在 Qt 库中的 glCompressedTexSubImage2DEXT()
处得到 GL_INVALID_OPERATION
。我的错误在哪里?
代码:
QOpenGLVertexArrayObject::Binder vaoBinder(&mVAO);
bindProgram();
glActiveTexture(GL_TEXTURE0);
const dds::Image *base = parser.getImageData(0);
mTexture.setFormat(QOpenGLTexture::RGB_DXT1);
mTexture.setSize(base->width, base->height);
mTexture.setMipLevelRange(0, parser.getMipmapCount());
mTexture.allocateStorage();
mTexture.bind();
for (size_t i = 0; i < parser.getMipmapCount(); i++)
{
// Image data represents a single mipmap level of a texture.
const dds::Image *img = parser.getImageData(i);
mTexture.setCompressedData(i, img->dataSize, img->data);
qDebug() << "size: " << img->width << img->height;
qDebug() << "i: " << i << " error: " << glGetError();
}
mTexture.setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
mProgram.setUniformValue("objectTexture", 0);
unbindProgram();
这是程序日志:
size: 2048 2048
i: 0 error: 0
size: 1024 1024
i: 1 error: 1282
size: 512 512
i: 2 error: 1282
size: 256 256
i: 3 error: 1282
...
size: 1 1
i: 11 error: 1282
这是 glIntercept 日志的一部分:
glGenTextures(1,00000000006DCE68)
glTextureParameteriEXT(1,GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0)
glTextureParameteriEXT(1,GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,11)
glTextureStorage2DEXT(1,GL_TEXTURE_2D,1,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,2048,2048)
glBindTexture(GL_TEXTURE_2D,1)
glCompressedTextureSubImage2DEXT(1,GL_TEXTURE_2D,0,0,0,2048,2048,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,2097152,00000000147A0080)
glGetError()=GL_NO_ERROR
glCompressedTextureSubImage2DEXT(1,GL_TEXTURE_2D,1,0,0,1024,1024,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,524288,00000000149A0080) glGetError() = GL_INVALID_OPERATION
glGetError()=GL_INVALID_OPERATION
glCompressedTextureSubImage2DEXT(1,GL_TEXTURE_2D,2,0,0,512,512,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,131072,0000000014A20080) glGetError() = GL_INVALID_OPERATION
glGetError()=GL_INVALID_OPERATION
glCompressedTextureSubImage2DEXT(1,GL_TEXTURE_2D,3,0,0,256,256,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,32768,0000000014A40080) glGetError() = GL_INVALID_OPERATION
glGetError()=GL_INVALID_OPERATION
glCompressedTextureSubImage2DEXT(1,GL_TEXTURE_2D,4,0,0,128,128,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,8192,0000000014A48080) glGetError() = GL_INVALID_OPERATION
glGetError()=GL_INVALID_OPERATION
glCompressedTextureSubImage2DEXT(1,GL_TEXTURE_2D,5,0,0,64,64,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,2048,0000000014A4A080) glGetError() = GL_INVALID_OPERATION
glGetError()=GL_INVALID_OPERATION
glCompressedTextureSubImage2DEXT(1,GL_TEXTURE_2D,6,0,0,32,32,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,512,0000000014A4A880) glGetError() = GL_INVALID_OPERATION
glGetError()=GL_INVALID_OPERATION
glCompressedTextureSubImage2DEXT(1,GL_TEXTURE_2D,7,0,0,16,16,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,128,0000000014A4AA80) glGetError() = GL_INVALID_OPERATION
glGetError()=GL_INVALID_OPERATION
glCompressedTextureSubImage2DEXT(1,GL_TEXTURE_2D,8,0,0,8,8,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,32,0000000014A4AB00) glGetError() = GL_INVALID_OPERATION
glGetError()=GL_INVALID_OPERATION
glCompressedTextureSubImage2DEXT(1,GL_TEXTURE_2D,9,0,0,4,4,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,8,0000000014A4AB20) glGetError() = GL_INVALID_OPERATION
glGetError()=GL_INVALID_OPERATION
glCompressedTextureSubImage2DEXT(1,GL_TEXTURE_2D,10,0,0,2,2,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,8,0000000014A4AB28) glGetError() = GL_INVALID_OPERATION
glGetError()=GL_INVALID_OPERATION
glCompressedTextureSubImage2DEXT(1,GL_TEXTURE_2D,11,0,0,1,1,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,8,0000000014A4AB30) glGetError() = GL_INVALID_OPERATION
glGetError()=GL_INVALID_OPERATION
glTextureParameteriEXT(1,GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,9729)
glTextureParameteriEXT(1,GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,9729)
最佳答案
当您调用 glTextureStorage2DEXT
时,您只是为单个 mipmap 分配了足够的内存。第三个参数是您要分配的 mipmap 级别数 - 在您的情况下,这应该是 11:
glTextureStorage2DEXT(1,GL_TEXTURE_2D,11,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,2048,2048)
对于给定的宽度和高度,您可以使用 floor(log2(max(width, height))) + 1
计算生成完整 mipmap 链所需的级别数。
对不起,我没有完全回答这个问题!您应该调用 setMipLevels
而不是调用 setMipLevelRange
.如 setMipLevels
的 Qt 文档中所述:
For texture targets that support mipmaps, this function sets the requested number of mipmap levels to allocate storage for. This function should be called before storage is allocated for the texture.
这应该有效:
mTexture.setMipLevels(floor(log2(max(width, height))) + 1);
或者使用您的parser.getMipmapCount()
方法:
mTexture.setMipLevels(parser.getMipmapCount());
关于c++ - 上传压缩纹理时出现 GL_INVALID_OPERATION,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26193815/