Замечание
Для двумерной текстуры размеры массива образа должны быть степенью двойки, например, массив размером 256x512 подходит, а 255x255 - нет.
Помимо массива для основной текстуры вводится вспомогательный массив для подобраза, необходимый для работы команды glTexSubimage2D:
const
checklmageWidth = 64; // ширина текстуры шахматной доски
checklmageHeight = 64; // высота текстуры шахматной доски
sublmageWidth =16; // размеры вспомогательного массива
sublmageHeight = 16;
var
checklmage : Array [0..checklmageHeight - 1, 0..checklmageWidth - 1,
0..3] of GLubyte;
sublmage : Array [0..sublmageHeight - 1, 0..sublmageWidth - 1, 0..3] of GLubyte;
После того как массив заполнен, устанавливается двумерная текстура, параметры задаются только самые необходимые:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTex!mage2D(GL_TEXTURE_2D, 0, GL_RGBA, checklmageWidth,
checklmageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, @checklmage);
Последняя команда в этой последовательности имеет параметры со смыслами, аналогичными одномерной текстуре, и точно так же я рекомендую не менять их значения за исключением аргументов, связанных с массивом образа текстуры.
При воспроизведении кадра на время рисования площадки включается режим наложения двумерной текстуры:
glEnable(GL_TEXTURE_2D); // включить режим
//не учитывать цвет примитивов
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBegin(GL_QUADS); // два независимых четырехугольника
glTexCoord2f(0.0, 0.0);
glVertexSf(-2.О, -1.0, 0.0);
glTexCoord2f(0.0, 1.0);
glVertex3f(-2.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0);
glVertexSf(0.0, 1.0, 0.0);
glTexCoord2f(1.0, 0.0);
glVertexSf(0.0, -1.0, 0.0);
glTexCoord2f(0.0, 0.0);
glVertexSf(1.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0);
glVertexSf(1.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0);
glVertexSf(2.41421, 1.0, -1.41421);
glTexCoord2f(1.0, 0.0);
glVertexSf(2.41421, -1.0, -1.41421);
glEnd;
9lDisable(GL_TEXTURE_2D); // режим отключается, немного экономится время
Режим GL_DECAL включается для того, чтобы цвета текстуры и поверхности Не смешивались. Можете задать текущим произвольный цвет - примитивы. не окрасятся, а если отключить этот режим, то шашки станут окрашенными. Здесь этот режим включается для того, чтобы не появлялись искажения при наложении текстуры на правую площадку. Пример иллюстрирует также работу команды glTexSubimage2D, позволяющей подменять часть образа текстуры. В примере при нажатии клавиши 'S' на первоначальной текстуре появляется квадратик с мелкой красной шашечкой, а после нажатия на 'R' текстура восстанавливается:
if Key = Ord ('S') then Begin // "Подобраз"
glTexSubImage2D(GL_TEXTURE_2D, 0,
12, 44, // x, у в координатах текстуры
subImageWidth, subImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, @subImage);
InvalidateRect(Handle, nil, False);
end;
If Key = Ord ('R') then Begin // восстановление
// заново переустановить текстуру
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, @checkImage);
InvalidateRect(Handle, nil, False);
end;
Команда glTexSubimage2D не представлена ни в файле справки, ни в модуле opengl. pas, ее прототип я описал в программе.
Рисунок 4. 56 иллюстрирует работу следующего примера, располагающегося в подкаталоге Ex83 и подсказывающего, как можно наложить блики от источника света на поверхность, покрытую текстурой.