Для задания домашней работы мне нужно реализовать алгоритм флуда. Мой код уже структурирован, но я не могу понять, почему мой раздел 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.
}