Я получаю GL_INVALID_OPERATION
каждый раз, когда я пытаюсь загрузить DXT1
текстура с несколькими уровнями mipmap с использованием Qt QOpenGLTexture
, Для уровня mipmap 0 все в порядке, но для любого другого я получаю GL_INVALID_OPERATION
в glCompressedTexSubImage2DEXT()
внутри библиотеки Qt. Где моя ошибка?
Код:
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)
Вы выделяете достаточно памяти только для одного mipmap при вызове glTextureStorage2DEXT
, Третий аргумент — это количество уровней mipmap, которое вы хотите выделить — в вашем случае это должно быть 11:
glTextureStorage2DEXT(1,GL_TEXTURE_2D,11,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,2048,2048)
Для заданной ширины и высоты вы можете рассчитать количество уровней, которое потребуется для создания полной цепочки mipmap с floor(log2(max(width, height))) + 1
,
Извините, я не совсем ответил на вопрос! Вместо звонка setMipLevelRange
, ты должен звонить setMipLevels
. Как указано в документации Qt для setMipLevels
:
Для текстурных целей, которые поддерживают mipmaps, эта функция устанавливает запрошенное количество уровней mipmap, для которых выделяется память. Эта функция должна быть вызвана до выделения памяти для текстуры.
Это должно работать:
mTexture.setMipLevels(floor(log2(max(width, height))) + 1);
Или используя ваш parser.getMipmapCount()
метод:
mTexture.setMipLevels(parser.getMipmapCount());