Текстуры, сжатые OpenGL DXT, становятся черными, когда ширина и высота различаются

Я реализовал загрузку сжатых текстур DXT в OpenGL, следуя этому руководству:

Учебное пособие по OpenGL DXT

Проблема в том, что он отлично работает, когда ширина и высота одинаковы (всегда степени двойки), но он просто отображается черным, когда они не равны (1024 * 512, 256 * 512 и т. д. не работают...). В чем может быть проблема?

Я использую OpenGL 3.3, а моя видеокарта — AMD Radeon HD 7610M (ноутбук, но довольно неплохая). Кроме того, glGetError() не показывает ошибок (тройная проверка).

Я публикую свою версию кода, чтобы быть уверенным (разница в том, что я читаю текстуры из упакованного формата файла, что не может быть проблемой, поскольку я загружаю все свои модели из них, и все в порядке):

void Texture::loadDDS(unsigned char* data)
{
    unsigned int height = *(unsigned int*)&(data[12]);
    unsigned int width = *(unsigned int*)&(data[16]);
    unsigned int mipMapCount = *(unsigned int*)&(data[28]);
    unsigned int fourCC = *(unsigned int*)&(data[84]);
    unsigned int format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;

    switch(fourCC)
    {
        case FOURCC_DXT1: format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
        case FOURCC_DXT3: format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
        case FOURCC_DXT5: format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
    }

    glGenTextures(1, &_id);
    glBindTexture(GL_TEXTURE_2D, _id);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    unsigned int blockSize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
    unsigned int offset = 124 + 4;

    for(unsigned int level = 0; level < mipMapCount && (width || height); ++level)
    {
        unsigned int size = ((width + 3) / 4) * ((height + 3) / 4) * blockSize;
        //if(size == 0) break; // neccessary?
        glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height, 0, size, &data[offset]);

        offset += size;
        width /= 2;
        height /= 2;
    }

    glBindTexture(GL_TEXTURE_2D, 0);
}

person Bodorkós Ádám    schedule 25.08.2013    source источник


Ответы (1)


Я полагаю, что ваша проблема связана со следующими строками:

width /= 2;
height /= 2;

Что приведет к неправильным значениям 0 (нуля).

Вы должны попробовать заменить их чем-то вроде:

width = MAX(1, width/2);
height = ...
person rotoglup    schedule 25.08.2013
comment
Вау, спасибо, я не могу поверить, что это была проблема! В этом случае даже оригинальный учебник и большая часть кода, который я нашел, были неправильными... Интересно. - person Bodorkós Ádám; 25.08.2013