【问题标题】:GL_INVALID_OPERATION when uploading compressed textures上传压缩纹理时的 GL_INVALID_OPERATION
【发布时间】:2014-10-04 23:51:35
【问题描述】:

每次我尝试使用 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)

【问题讨论】:

  • 通过查看 Qt 文档,我认为您可能需要调用 setMipLevels() 而不是 setMipLevelRange()。前者指定要分配多少个级别,而后者指定采样的范围。

标签: c++ qt opengl texture2d


【解决方案1】:

当您调用 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 链所需的级别数。


对不起,我没有完全回答这个问题!而不是调用setMipLevelRange,您应该调用setMipLevels。正如setMipLevels 的 Qt 文档中所述:

对于支持 mipmap 的纹理目标,此函数设置请求的 mipmap 级别数以为其分配存储。应该在为纹理分配存储空间之前调用此函数。

这应该可行:

mTexture.setMipLevels(floor(log2(max(width, height))) + 1);

或者使用你的parser.getMipmapCount() 方法:

mTexture.setMipLevels(parser.getMipmapCount());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    • 1970-01-01
    相关资源
    最近更新 更多