2014-11-29 6 views
2

У меня есть this DDS файл. Я написал простой DDS-ридер, чтобы прочитать заголовок DDS и распечатать его данные на основе спецификации MSDN. В нем говорится, что это RDS DDS с 32 байтами на глубину пикселя и альфа игнорируется, то есть формат пикселей - X8R8G8B8 (или A8R8G8B8). Чтобы проверить это, я также открыл этот файл в шестнадцатеричном редакторе, который показывает первый (то есть из начала ввода данных) 4 байта, как BB GG RR 00 (замените их на правые шестнадцатеричные значения первого пикселя). I read, что функции копирования текстур OpenGL действуют на байты (по крайней мере концептуально), и, следовательно, с его точки зрения, эти данные являются B8G8R8A8. Пожалуйста, исправьте меня, если мое понимание здесь не так.Загрузка несжатого DDS в текстуру GL

Теперь glTexImage2Dвнутреннего формат проходит RGBA8 и внешнего формат и типа проходит BGRA и UNSIGNED_BYTE. Это приводит к синему оттенку в визуализированном выходе. В моем шейдере фрагмента, просто чтобы проверить, я сделал swizzle для обмена R и B, и он корректно отображает.

Я вернулся код шейдера, а затем заменил тип из UNSIGNED_BYTE с UNSIGNED_INT_8_8_8_8_REV (на основе this suggestion) и по-прежнему оказывает синий оттенок. Теперь изменив внешний формат на RGBA и с тип (UNSIGNED_BYTE или UNSIGNED_INT_8_8_8_8_REV) он делает штраф!

  • Поскольку OpenGL не поддерживает ARGB, предоставление BGRA понятно. Но почему RGBA работает правильно здесь? Это кажется неправильным.
  • Почему код не влияет на порядок расположения каналов?
  • Имеет ли отношение GL_UNPACK_ALIGNMENT к этому? Я оставил его по умолчанию (4). Если я прочитал руководство справа, это не должно повлиять на то, как считывается клиентская память.

Подробности

  • OpenGL версии 3.3
  • HD Graphics Intel, который поддерживает Шифрование до OpenGL 4.0
  • Используется GLI для загрузки файла DDS и получить указатель на данные
+0

Могу ли я взглянуть на читателя? – elect

+0

Назад, когда я спросил об этом, я написал что-то отброшенное. Спасибо вам за то, что спросили, я закончил писать что-то заново: [поделился здесь] (https://gist.github.com/legends2k/97584e4c576d7b5e0dcf)! Как говорится в ответе, вышеупомянутая проблема была вызвана ошибкой в ​​GLI, которая была исправлена ​​в последнее время. – legends2k

ответ

3

Я, наконец, нашел ответы сам! Отправьте его сюда, чтобы он мог помочь кому-то в будущем.

Поскольку OpenGL не поддерживает ARGB, предоставление BGRA понятно. Но почему RGBA работает правильно здесь? Это кажется неправильным.

Проверяя память, на которую указывает void* data, что GLI возвращается, когда указатель на двоичном данные изображения в просят, то можно увидеть, что GLI уже заказана байт при передаче данных из файла в памяти клиента. Окно memeory показывает от нижнего к более высокому адресу данные в форме RR GG BB AA. Это объясняет, почему работает GL_RGBA.Тем не менее, неправильный элемент GLI заключается в том, что при запросе внешнего формата возвращается GL_BGRA вместо GL_RGBA. A bug для решения этой проблемы.

Почему в типа оказывают никакого влияния на упорядочение каналов?

Нет, это имеет эффект. Машина, на которой я пытаюсь выполнить этот эксперимент, представляет собой небольшую конечную машину Intel x86_64. OpenGL Wiki четко заявляет, что данные пикселя клиента всегда находятся в порядке порядка байтов клиента. Теперь, когда передается GL_UNSIGNED_BYTE или GL_UNSIGNED_INT_8_8_8_8_REV, базовый тип (а не тип компонента) является unsigned int для обоих; таким образом, считывание int от data, на машине с маленькими концами будет означать, что переменная в регистре закончится с заменой байтов, то есть RR GG BB AA в ОЗУ достигнет VRAM как AA BB GG RR; при обращении к текстуре типа RGBA (RR GG BB AA), чтение AA фактически даст RR. Чтобы исправить это, реализация OpenGL меняет байты, чтобы нейтрализовать точность устройства, в случае GL_UNSIGNED_BYTEтип. В то время как для GL_UNSIGNED_INT_8_8_8_8_REV мы явно инструктируем OpenGL обменивать порядок байтов, и поэтому он корректно отображает. Однако, если тип передан как GL_UNSIGNED_INT_8_8_8_8, тогда рендеринг будет завинчен, так как мы поручаем OpenGL копировать байты, когда они были прочитаны на машине.

Есть ли у этого подшипника GL_UNPACK_ALIGNMENT? Я оставил его по умолчанию (4). Если я прочитал руководство справа, это не должно повлиять на то, как считывается клиентская память.

Он имеет отношение к распаковке данных текстур из клиентской памяти в память сервера. Тем не менее, это необходимо для учета байтов заполнения, присутствующих в строках изображения, для правильного вычисления шага (шага). Но в этом вопросе конкретно это не имеет никакого отношения, поскольку флаг шага равен 0, т. Е. В файле DDS нет соответствующих битов.

Похожие материалы: https://www.opengl.org/wiki/Pixel_Transfer#Pixel_type

+0

Этот ответ, надеюсь, правильный, но я не уверен на 100%, так как я сделал некоторые предположения в своем выводе. Если это неправильно, некоторые из мастеров [tag: opengl] могут порадовать меня из моего невежества. Благодаря! – legends2k

+1

Как вы знаете, формат DDS-файла может иметь дополнение для выравнивания. В мире D3D такие вещи называются «шаг». Вы можете прочитать в разделе «dwPitchOrLinearSize» [здесь] (http://msdn.microsoft.com/en-us/library/bb943991 (v = vs.85) .aspx). –

+0

Спасибо за подсказку! Я обновил ответ; Я читал документацию поспешно, мой плохой. Надеюсь, что все остальное верно. – legends2k

 Смежные вопросы

  • Нет связанных вопросов^_^