5 апреля 2012 г.

OpenGL ES 1. Текстуры в движении

До сих пор мы задавали для вершин полигонов фиксированные координаты текстур. В результате, текстура была как-бы "приклеена" к поверхности полигона. Однако, ничто нам не мешает изменять координаты текстуры вершин при смене кадров. Например, мы хотим чтобы текстура протекала по поверхности полигона. Как это можно реализовать ?
Двумерная текстура имеет две координаты S и T, аналогичные координатам X и Y на плоскости. S-это горизонтальная координата, T-вертикальная. Следует отметить, что разделение на вертикальную и горизонтальную координату условно и зависит какую из вершин полигона мы примем за начало текстурных координат. Кроме того, координаты текстур нормированы, т.е. находятся в диапазоне от 0 до 1. Достаточно с каждым новым кадром добавлять к координате S или T величину, намного меньше единицы, и увидим как текстура "поплывет". При этом рано или поздно текстурная координата выйдет за пределы единицы. Что при этом произойдет.
Ничего страшного. При создании текстуры мы использовали следующие команды:
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
Использование параметра состояния GL_REPEAT означает, что если координата текстуры станет больше единицы или меньше нуля, будет произведен ее повтор. Например, если координата S=1.4 то при текстурировании она автоматически отображается как 0.4. Таким образом, картинка будет повторяющейся.
Аналогично повтор координаты T задается командой: gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
-----------------------------------------------------------------------------------------------
Перейдем к практической реализации задуманной идеи.
Добавим в заголовок класса Triangle переменные для координат текстур:
private float s1,t1; // координаты текстуры первой вершины 
private float s2,t2; // координаты текстуры второй вершины
private float s3,t3; // координаты текстуры третьей вершины 
В конструкторе класса треугольника перед вызовом метода recount присвоим им начальные значения:
s1=0.5f;
t1=1;
s2=0;
t2=0;
s3=1;
t3=0;
Расчет и запись текстурных координат в буфер перенесем из конструктора в метод draw. В конце этого метода перед вызовом glDrawArrays добавим строки:
//увеличим текстурные координаты на величину 0.005
s1+=0.005f;
t1+= 0.005f;
s2+=0.005f;
t2+= 0.005f;
s3+= 0.005f;
t3+= 0.005f;
// запишем измененные текстурные координаты в буфер
// установим текущую позицию буфера на его начало
texcoordBuffer.position(0);
//Запись координат текстур
texcoordBuffer.put(s1); 
texcoordBuffer.put(t1); 
texcoordBuffer.put(s2);
texcoordBuffer.put(t2);
texcoordBuffer.put(s3);
texcoordBuffer.put(t3);
// установим текущую позицию буфера на его начало
texcoordBuffer.position(0);
Далее рисуем треугольник
gl.glDrawArrays(GL10.GL_TRIANGLES,0,3);
Для наглядности в классе рендерера сделаем материал непрозрачным
private float [] diffusematerialArray={0.8f, 0.8f, 0.8f, 1};
и закрасим все боковые грани передней пирамиды одной текстурой, например пятой.
p1.setTextureName(tex5.getName());

Получим такой интересный эффект:


Комментариев нет:

Отправить комментарий