glPixelStorei(GL_UNPACK_ALIGNMENT, 1) Недостатки?
Каковы недостатки всегда использовать Alginment 1?
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
glPixelStorei(GL_PACK_ALIGNMENT, 1)
Повлияет ли это на производительность современного gpus?
2 ответа
Как данные не могут быть выровнены по 1 байту?
Это настоятельно предполагает отсутствие понимания того, что означает выравнивание строк в операциях переноса пикселей.
Ожидается, что данные изображений, которые вы передаете в OpenGL, будут сгруппированы в строки. Каждая строка содержит width
количество пикселей, причем каждый пиксель имеет размер, определенный параметрами формата и типа. Так что формат GL_RGB
с типом GL_UNSIGNED_BYTE
приведет к пикселю размером 24 бита. В противном случае ожидается, что пиксели будут упакованы, поэтому строка из 16 этих пикселей займет 48 байтов.
Ожидается, что каждая строка будет выровнена по определенному значению, как определено GL_PACK/UNPACK_ALIGNMENT
, Это означает, что значение, которое вы добавляете к указателю для перехода к следующей строке: align(pixel_size * width, GL_*_ALIGNMENT)
, Если размер пикселя составляет 3 байта, ширина равна 2, а выравнивание равно 1, размер байта строки равен 6. Если выравнивание равно 4, размер байта строки равен восьми.
Видишь проблему?
Данные изображения, которые могут поступать из некоторого формата файла изображения, загруженного с помощью какого-либо загрузчика изображений, имеют выравнивание строк. Иногда это выравнивается по 1 байту, а иногда нет. Изображения DDS имеют выравнивание, указанное как часть формата. Во многих случаях изображения имеют 4-байтовые выравнивания строк; поэтому размеры пикселей менее 32 бит будут иметь отступы в конце строк определенной ширины. Если выравнивание, которое вы даете OpenGL, не соответствует этому, то вы получите искаженную текстуру.
Вы устанавливаете выравнивание, чтобы соответствовать выравниванию формата изображения. Если вы знаете или иным образом можете гарантировать, что выравнивание строк всегда равно 1 (и это маловероятно, если вы не написали свой собственный формат изображения или средство записи DDS), вам необходимо установить выравнивание строк точно в соответствии с форматом вашего изображения.
Повлияет ли это на производительность современного gpus?
Нет, потому что настройки хранилища пикселей подходят только для передачи данных из или в графический процессор, а именно для выравнивания ваших данных. Оказавшись в памяти графического процессора, он выровняется любым способом, который желает графический процессор и драйвер.
Там не будет никакого влияния на производительность. Установка более высокого выравнивания (в openGL) ничего не улучшает и не ускоряет.
Все, что нужно сделать - это сообщить openGL, где ожидать следующий ряд пикселей. Вы всегда должны использовать выравнивание 1, если пиксели вашего изображения плотно упакованы, т.е. если нет промежутков между тем, где заканчивается строка байтов и где начинается новая строка.
Выравнивание по умолчанию равно 4 (т.е. openGL ожидает, что следующая строка пикселей будет после скачка в памяти, который делится на 4), что может вызвать проблемы в случаях, когда вы загружаете текстуры R, RG или RGB, которые не являются 4-байтовыми плавающими или ширина не делится на 4. Если пиксели изображения плотно упакованы, вам нужно изменить выравнивание на 1, чтобы распаковка работала.
Вы могли бы (я лично не сталкивался с ними) иметь изображение, скажем, 3x3 RGB ubyte, строки которого выровнены 4-м с 3 дополнительными байтами, используемыми в качестве заполнения в конце. Какие строки могут выглядеть так:
R - G - B - R - G - B - R - G - B - X - X - X (всего 16 байтов)
Причина в том, что выровненные данные улучшают производительность процессора (не уверен, насколько это верно / оправдано на современных процессорах). Если у вас есть какой-либо контроль над тем, как составляется исходное изображение, то, возможно, выравнивание его тем или иным способом улучшит его обработку. Но это сделано до открытия GL. OpenGL не может ничего изменить по этому поводу, его интересует только то, где найти пиксели.
Итак, вернемся к строке изображения 3х3, приведенной выше - установка выравнивания на 4 была бы хорошей (и необходимой), чтобы перепрыгнуть через последний отступ. Если вы установите его на 1, тогда он испортит ваш результат, поэтому вам нужно сохранить / восстановить его до 4. (Обратите внимание, что вы также можете использовать ROW_LENGTH, чтобы перепрыгивать через него, так как этот параметр используется при работе с подмножествами image, и в этом случае вам иногда приходится перепрыгивать намного больше, чем на 3 или 7 байтов (это максимум, который может дать параметр выравнивания 8). В нашем примере, если вы укажете длину строки 4, а выравнивание 1 также будет Работа).
То же самое касается упаковки. Вы можете указать openGL выровнять строку пикселей по 1, 2, 4 и 8. Если вы сохраняете 3x3 RGB-байта, вы должны установить выравнивание на 1. Технически, если вы хотите, чтобы результирующие строки были плотно упакованы, вы должен всегда давать 1. Если вы хотите (по какой-либо причине) создать некоторые отступы, вы можете дать другое значение. Задание (в нашем примере) значения PACK_ALIGNMENT, равного 4, приведет к созданию строк, которые выглядят так же, как строка выше (с 3 дополнительными отступами в конце). Обратите внимание, что в этом случае ваш содержащий объект (openCV mat, bitmap и т. Д.) Должен иметь возможность получать этот дополнительный отступ.