Согласно этому документу OpenGL на glDrawPixels (выделение добавлено):
ширина x высота пикселей считываются из памяти, начиная с данных о местоположении. По умолчанию эти пиксели взяты из смежных областей памяти, за исключением того, что после считывания всех пикселей ширины, указатель чтения продвигается к следующей четырехбайтовой границе . Четырехбайтовое выравнивание строк определяется glPixelStore с аргументом GL_UNPACK_ALIGNMENT, и оно может быть установлено в один, два, четыре или восемь байтов.
Обратите внимание, что ваши цвета определены как значения 3 GLuint
- всего 3 байта! Каждая строка пикселей содержит 3 * 897 = 2691
байтов. Следующее значение, кратное 4 после 2691
, равно 2692
, и, таким образом, определяется glDrawPixels
, GL пропускает один байт после каждой строки. Вот почему изображение обрезается и почему оно выглядит серым (если вы увеличите масштаб, вы увидите, что оно не серое, а каждая третья строка имеет правильные цвета, а промежуточные оттенки смещены на 120 градусов).
Способ исправить это - сделать glPixelStore
вызов перед вызовом glDrawPixels
. Достаточно изменить
glDrawPixels(_w, _h, GL_RGB,
GL_UNSIGNED_BYTE, _data);
до
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glDrawPixels(_w, _h, GL_RGB,
GL_UNSIGNED_BYTE, _data);
Кроме того, код внутри вашего цикла for
неверен. _h-y
должно быть _h-y-1
, чтобы при y=0
вы не записывали вне границ массива и аналогично, когда y=_h-1
, вы записываете в 0
-й индекс массива.
Кроме того, обратите внимание на динамическое выделение памяти вместо выделения массива статического размера. Это сделает ваш код менее подверженным нарушениям доступа, т.е. чтению / записи памяти, которая на самом деле вам не принадлежит, что приводит к сбоям и другим проблемам.