Для выполнения домашнего задания мне нужно реализовать алгоритм заливки. Мой код уже структурирован, но я не могу понять, почему мой раздел glReadPixels не работает. Я надеялся, что кто-нибудь может взглянуть на то, что я делаю, и сообщить мне, если я ошибаюсь в его использовании.
// I fetch pixels like so:
glReadPixels(100, 250, 150, 150, GL_RGB, GL_UNSIGNED_BYTE, clip_pixels);
// I index the result using:
in_rect_pos = (in_rect_y * in_rect_w) + in_rect_x;
// in_rect_* is a point w/ its origin at (100, 250)
GLubyte *pixel_at_pos = clip_pixels + (in_rect_pos * GL_PACK_ALIGNMENT);
Но я не получаю правильные значения, и я действительно даже не знаю, как отладить это.
Я могу заметить одну очень существенную ошибку в вашем коде:
GLubyte *pixel_at_pos = clip_pixels + (in_rect_pos * GL_PACK_ALIGNMENT);
С помощью GL_PACK_ALIGNMENT
здесь это неправильно двумя разными способами:
В корне, GL_PACK_ALIGNMENT
является перечисление значение в OpenGL. Случается, что он определен как 0x0D05 (3333 в десятичном виде), и это не значение из GL_PACK_ALIGNMENT
Состояние GL, которое вы можете установить через glPixelStore
и запросить обратно через glGet
. В обоих случаях, GL_PACK_ALIGNMENT
просто используется для ссылки на переменную состояния GL, к которой необходимо получить доступ.
Вы не используете выравнивание правильно. Даже если вы использовали значение, запрошенное glGetIntegerv(GL_PACK_ALIGNMENT, &alignment)
Ваша формула все равно будет неправильной. GL_PIXEL_PACK
выравнивание ссылки на адреса каждого строка данных пикселей. По умолчанию это значение равно 4, поэтому, если ваша строка не будет начинаться с адреса, кратного 4, вы должны добавить от 1 до 3 байтов заполнения, чтобы делить ее на 4.
const int X = 0;
const int Y = 0;
const int Width = 100;
const int Height = 100;
unsigned char Buffer[Width * Height * 3];
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(X, Y, Width, Height, GL_RGB, GL_UNSIGNED_BYTE, &Buffer[0]);
for (int i = 0; i < height; ++i)
{
for (int j = 0; j < width; ++j)
{
unsigned char R = Buffer[(i * j + width) + 0];
unsigned char G = Buffer[(i * j + width) + 1];
unsigned char B = Buffer[(i * j + width) + 2];
}
}
Если он выровнен по некоторой границе (а вы этого не делаете: glPixelStorei(GL_PACK_ALIGNMENT, 1)
), вам нужно будет учитывать отступы ..
Пример:
unsigned char* ptr = &Buffer[0];
for (int i = 0; i < Height; ++i)
{
for (int j = 0; j < Width; ++j)
{
int R = *(ptr++);
int G = *(ptr++);
int B = *(ptr++);
}
ptr += (4 - ((width * 3) % 4)) % 4; //DWORD boundary alignment.
}