- •OpenGl es для новичков
- •2.5 OpenGl es 2.0. Урок 5 Шейдер преломления света……………………………………… 60
- •1.1 OpenGl es в Android, класс glSurfaceView
- •1.2 OpenGl es 1. Основы рисования для начинающих
- •Aтрибут координат вершины.
- •Цвет как атрибут вершины.
- •Координаты вектора нормали.
- •1.3 OpenGl es 1. Применение индексов при обходе вершин
- •1.4 OpenGl es 1. Освещение и материалы
- •1.5 OpenGl es 1. Двумерные текстуры
- •1.6 OpenGl es 1. Текстурирование на примере
- •1.7 OpenGl es 1. Как сделать текстуры прозрачными
- •1.8 OpenGl es 1. Как наложить несколько текстур на один полигон
- •1.9 OpenGl es 1. Текстуры в движении
- •1.10 OpenGl es 1. Зеркальное отражение при помощи кубических текстур
- •2.1 OpenGl es 2.0. Урок первый-Шейдеры Введение в шейдеры.
- •Получение матриц.
- •Создание шейдерного объекта в OpenGl es 2.0
- •Передача данных униформ в шейдеры.
- •Передача атрибутов вершин в вершинный шейдер.
- •Класс шейдерного объекта.
- •2.2 OpenGl es 2.0. Урок второй - Освещение в шейдере
- •Фоновое (ambient) освещение.
- •Диффузное (diffuse) или рассеянное освещение.
- •Зеркальное (specular) или бликовое освещение.
- •Коды шейдеров.
- •Практика. Освещение плоской поверхности.
- •2.3 OpenGl es 2.0. Урок третий - Двумерные текстуры Загрузка текстуры из файла.
- •Доступ к текстурам из шейдера.
- •Получение цвета пикселя из текстуры.
- •Практика. Текстурированный квадрат.
- •Включаем свет.
- •2.4 OpenGl es 2.0. Урок 4. Гладкие поверхности. Полигональная сетка.
- •Расчет нормалей.
- •Разбиваем сетку на треугольники и рисуем поверхность.
- •Полный код класса рендерера, рисующего поверхность.
- •2.5 OpenGl es 2.0. Урок 5. Шейдер преломления света
Доступ к текстурам из шейдера.
Теперь поговорим о том, как получить доступ к текстуре из шейдера. Для этого в GLSL существует специальный тип униформы и называется он sampler2D. Сэмплеры можно объявлять только во фрагментном шейдере, например так:
uniform sampler2D u_texture;
Здесь u_texture-это имя униформы.
Теперь нам нужно связать униформу текстуры u_texture с текстурным объектом mTexture. Последовательность действий при этом следующая. Сначала нужно выбрать текущую активную программу:
GLES20.glUseProgram(program_Handle);
Затем нужно получить ссылку на униформу u_texture:
int u_texture_Handle = GLES20.glGetUniformLocation(program_Handle, "u_texture");
В OpenGL ES 2.0 одновременно может быть загружено до 32 текстур в разные текстурные блоки. Каждый текстурный блок может содержать только одну текстуру. Текстурные блоки обозначают именами GL_TEXTURE0, GL_TEXTURE1, GL_TEXTURE2 и.т.д. Поэтому мы должны с начала выбрать текущий текстурный блок (например блок 0) :
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
Затем в этом блоке сделать активным наш текстурный объект mTexture:
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexture.getName());
Здесь первый аргумент это тип текстуры GL_TEXTURE_2D, который говорит о том, что текстура является двумерной. Второй аргумент - это имя текстуры.
Окончательно связь текстурного объекта mTexture и униформы u_texture выполняется командой:
GLES20.glUniform1i(u_texture_Handle, 0);
Здесь первый аргумент - это ссылка на униформу u_texture. Второй аргумент - номер текстурного блока (в нашем случае 0). Связь текстурного объекта с униформой установлена.
Нам может потребоваться загрузить несколько текстур для одновременного использования. В этом случае мы должны создать несколько текстурных объектов (mTexture0, mTexture1 и.т.д.) объявить во фрагментном шейдере несколько сэмплеров. Например, так:
uniform sampler2D u_texture0;
uniform sampler2D u_texture1;
и.т.д.
Далее нужно установить связь между объектом mTexture0 и униформой u_texture0, а также между объектом mTexture1 и униформой u_texture1 и.т.д.
Для примера рассмотрим случай двух текстур.
Дополним наш класс Shader, описанный в первом уроке, методом linkTexture, который выполняет связь двух текстур с соответствующими сэмплерами:
public void linkTexture(Texture texture0,Texture texture1){
// texture0, texture1 - текстурные объекты устанавливаем текущую активную программу GLES20.glUseProgram(program_Handle);
if (texture0 != null){
//получаем ссылку на униформу u_texture0
int u_texture0_Handle = GLES20.glGetUniformLocation(program_Handle, "u_texture0");
//выбираем текущий текстурный блок GL_TEXTURE0
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
//в текстурном блоке GL_TEXTURE0 делаем активной текстуру с именем texture0.getName()
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture0.getName());
//выполняем связь между объектом texture0 и униформой u_texture0 в нулевом текстурном блоке
GLES20.glUniform1i(u_texture0_Handle, 0);
}
if (texture1 != null){
//получаем ссылку на униформу u_texture1
int u_texture1_Handle = GLES20.glGetUniformLocation(program_Handle, "u_texture1");
//выбираем текущий текстурный блок GL_TEXTURE1
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
//в текстурном блоке GL_TEXTURE1 делаем активной текстуру с именем texture1.getName()
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture1.getName());
//выполняем связь между объектом texture1 и униформой u_texture1 в первом текстурном блоке
GLES20.glUniform1i(u_texture1_Handle, 1);
}
}//конец метода Создавать текстурные объекты и связывать их с сэмплерами нужно в методе onSurfaceCreated класса рендерера, потому что при создании экрана они разрушаются.
