- •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. Шейдер преломления света
1.7 OpenGl es 1. Как сделать текстуры прозрачными
В этой статье, основанной на предыдущем примере показано как сделать грани пирамиды полупрозрачными, рассмотрен вопрос о сортировке полигонов для правильного отображения эффекта прозрачности. Для этих целей будем использовать режим смешивания цветов при помощи альфа-компоненты цвета материла. Всего у цвета есть четыре компонента: красный, зеленый, синий и альфа. Яркость каждой компоненты изменяется в диапазоне от 0 до 1. Альфа компонент-это четвертый компонент цвета. Он определяет степень непрозрачности объекта.
Альфа=0 - полностью прозрачный объект. Альфа=1 - полностью непрозрачный объект.
В заголовке класса MyClassRenderer изменим строку:
private float [] diffusematerialArray={0.8f, 0.8f, 0.8f, 1};
на float [] diffusematerialArray={0.8f, 0.8f, 0.8f, 0.5f};
т.е. установим альфа-компоненту рассеянного цвета материала равной 0.5.
Кроме того нужно в метод onSurfaceCreated класса MyClassRenderer добавить следующие настройки:
// включаем модель освещения внешних и внутренних сторон gl.glLightModelx(GL10.GL_LIGHT_MODEL_TWO_SIDE, GL10.GL_TRUE); // отключаем отсечение невидимых граней gl.glDisable(GL10.GL_CULL_FACE); // включаем альфа-компонент цвета gl.glEnable(GL10.GL_ALPHA); // включаем смешивание цветов gl.glEnable(GL10.GL_BLEND); // устанавливаем режим смешивания цветов gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); ------------------------------------------------------------------------------------------------------------
Запустив программу на исполнение, убедимся что эффект прозрачности появляется и исчезает при вращении пирамиды. Это происходит потому, что мы рисуем полигоны, из которых состоит пирамида, в определенном порядке без учета их удаленности от глаза наблюдателя.
Поэтому нам нужно рисовать полигоны от дальнего к ближнему, чтобы эффект прозрачности не пропадал при повороте пирамиды. Займемся сортировкой полигонов в пирамиде. Поскольку полигоны представляют объекты разных классов Triangle и Quadr нам нужен метод, который сортирует объекты разных типов по определенному индексу. В Java таким методом является метод compareTo интерфейса Comparable. Создадим абстрактный класс Polygon, реализующий интерфейс Comparable.
------------------------------------------------------------------------------------------------------------
package com.blogspot.andmonahov.pyramid;
import javax.microedition.khronos.opengles.GL10;
public abstract class Polygon implements Comparable<Object> {
// поле полигона, по которому производится сортировка
public float indexsort;
// абстрактный метод рисования у каждого полигона он свой
public abstract void draw(GL10 gl);
// метод-сортировщик по полю indexsort // сортировка выполняется по убыванию значения indexsort
public int compareTo(Object obj) {
Polygon tmp = (Polygon)obj;
if(this.indexsort < tmp.indexsort){
return 1;
}
else if(this.indexsort > tmp.indexsort){
return -1;
}
return 0;
}
}
------------------------------------------------------------------------------------------------------------
Наследуем классы Triangle и Quadr от общего предка Polygon следующим образом:
public class Triangle extends Polygon {............
public class Quadr extends Polygon{............
При этом полигоны наследуют поле indexsort, по которому будет производиться сортировка в методе compareTo. Теперь нужно определить значение indexsort для полигонов внутри пирамиды. Таким полем будет расстояние от камеры до центра полигона. Поскольку поля для координат камеры xposition, yposition, position объявлены в классе MyClassRenderer как public static мы можем получить доступ к ним из любого класса, в т.ч. из класса пирамиды. Перепишем метод draw класса Pyramid:
------------------------------------------------------------------------------------------------------------
public void draw (GL10 gl){
//
координаты вектора от камеры до центра
полигона
float dx;
float dy;
float dz;
//задаем сортировку по расстоянию от камеры до центра полигона
for (int i=0; i<4; i++){
dx=MyClassRenderer.xposition-triangle[i].getxcenter();
dy=MyClassRenderer.yposition-triangle[i].getycenter();
dz=MyClassRenderer.zposition-triangle[i].getzcenter();
triangle[i].indexsort=dx*dx+dy*dy+dz*dz;
}
dx=MyClassRenderer.xposition-quadr.getxcenter();
dy=MyClassRenderer.yposition-quadr.getycenter();
dz=MyClassRenderer.zposition-quadr.getzcenter();
quadr.indexsort=dx*dx+dy*dy+dz*dz;
//создаем массив полигонов
Polygon [] polygon =new Polygon[5];
for (int i=0; i<4; i++){
polygon[i]=triangle[i]; //записываем в массив полигонов треугольники
}
polygon[4]=quadr; // последний элемент массива-квадрат дна
// сортируем массив полигонов по полю indexsort
Arrays.sort(polygon);
// рисуем массив полигонов
for (int i=0; i<5; i++){
polygon[i].draw(gl);
}
}
------------------------------------------------------------------------------------------------------------
Теперь эффект полупрозрачности не зависит от вращения пирамиды. Получаем такую картинку:
