OpenGL в Delphi

Прямое обращение к пикселам экрана


Библиотека OpenGL располагает командами, позволяющими осуществить непосредственный доступ к пикселам экрана. Разберем проект из подкаталога Ex42 - простой пример на вывод блока пикселов на экран вызовом двух команд:

glRasterPos2f (-0. 25, -0. 25);
glDrawPixels(ImageWidth, ImageHeight, GL_RGB, GL_UNSIGNED_BYTE, @Image);

Первая команда задает базовую точку для выводимого блока, вторая ocyществляет собственно вывод массива пикселов. Высота при выводе может и отличаться от реального размера массива, т е быть меньше, ширину же для корректного вывода желательно не брать меньше действительного размера массива.
В этом простом примере выводимый массив заполняется значениями RGF так, что в результате получается шахматная доска с сине-красными клетками

const
ImageWidth = 64;
ImageHeight = 64;
...
Image : Array [0..ImageHeight-1, 0..ImageWidth - 1, 0..2] of GLUbyte;
...
{=================================================
Создание образа шахматной доски}
procedure TfrmGL.Makelmage;
var i, j : Integer;
begin For i := 0 to ImageHeight - 1 do
For j := 0 to ImageWidth - 1 do begin
If ((i and 8) = 0) xor ( (j and 8) = 0)
then begin
Image[ i ] [ j ][ 0 ] :=0; // красный
Image [ i ] [ j ][1] : = 0; // зеленый
Image[i][j][2] := 255; // синий
end
else begin
Image[ i ] [ j ][0] := 255; // красный
Image[ i ][ j ][1] := 0; // зеленый
Image[ i ] [ j ][2] := 0; // синий
end;
end;
end;

В развитие темы разберем более интересный пример (подкаталог Ех43), где выводимый массив заполняется следующим образом" создается объект класса TBitmap, в который загружается растр из bmp-файла, последовательно считываются пикселы объекта, и в соответствии со значениями цвета каждого пиксела заполняются элементы массива. Все просто, только надо обратить внимание, что ось Y битовой карты направлена вниз, поэтому элементы массива заполняются в обратном порядке:

procedure TfrmGL.Makelmage;
var
i, ] : Integer;
PixCol : TColor;
Bitmap : TBitmap;
begin
Bitmap := TBitmap.Create;
Bitmap.LoadFromFile ('Claudia.bmp');
For i := 0 to ImageHeight - 1 do For ] := 0 to ImageWidth - 1 do begin
PixCol := Bitmap.Canvas.Pixels [j, i];
// перевод цвета из TColor в цвет для команд OpenGL
Image[ImageHeight - i - 1][3][0] := PixCol and $FF;
Image[ImageHeight - i - 1] [3] [1] := (PixCol and $FFOO) shr 8;
Image[ImageHeight - i - 1][3][2] := (PixCol and $FFOOOO) shr 16;
end,
Bitmap.Free;
end;

Обратите внимание на строку, задающую выравнивание пикселов - без нее массив пикселов будет выводиться некорректно

glPixelStorel(GL_UNPACK_ALIGNMENT, 1);

Возможно, при знакомстве с файлом справки вы обратили внимание на команду giBitMap, специально предназначенную для вывода битовых массивов Растр в таком случае может быть монохромным, а не 24-битным Обычно эта команда используется для вывода текста, мы рассмотрим ее в главе 6. Выводимые массивы пикселов легко масштабируются вызовом команды giPixeizoom, аргументы которой - масштабные множители по осям X и Y. Для иллюстрации посмотрите проект из подкаталога Ех44, где нажатием клавиш 'X' и 'Y' можно управлять масштабом по соответствующим осям Обратите внимание, что при отрицательном значении множителей изображение переворачивается по соответствующей оси тот пример демонстрирует также еще одно возможное использование команды glPixelStorel, позволяющей, в частности, прокручивать изображение по вертикали или горизонтали, что в нашей программе осуществляется нажатием клавиш 'R'1 и 'P'1

Замечание
Учтите, что при прокрутке изображения на величину, превышающую половину растра, происходит аварийное завершение программы.

Команда glCopyPixeis позволяет копировать часть экрана в текущей позиции задаваемой giRasterpos объекте из диалога Ех45 я воспользовался этой командой следующим образом при нажатой кнопке мыши вслед за указателем мыши перемещается копия левого нижнего угла экрана. Изображение восстанавливается при каждой перерисовке экрана.
Здесь надо обратить внимание, что, в отличие от всех остальных примеров данной главы, флаги окна не включают двойную буферизацию и что контекст воспроизведения занимается приложением сразу по началу работы и не освобождается до завершения работы. Обработка движения мыши заканчивается не перерисовкой окна, а командой glFlush.
Команда glPixelTransfer позволяет задавать режимы вывода пикселов, в частности, задавать цветовые фильтры. В примере, располагающемся в подкаталоге Ex46, нажатием клавиш 'R', 'G', 'B' можно изменить составляющую долю соответствующего цвета.

Замечание
Надо отметить, что команды непосредственного доступа к пикселам экрана работают сравнительно медленно, поэтому используются только в исключительных случаях.

Команда glReadPixels позволяет считывать содержимое всего экрана или части его. Это одна из самых важных для нас команд, мы еще неоднократно будем к ней обращаться.
Для иллюстрации ее работы я подготовил проект (подкаталог Ex47), выводящий на экран простейшие стереокартинки. Одна из них показана на Рисунок 2. 14.



Содержание раздела