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 добавить следующие настройки: // включаем модель освещения внешних и внутренних сторон Запустив программу на исполнение, убедимся что эффект прозрачности появляется и исчезает при вращении пирамиды. Это происходит потому, что мы рисуем полигоны, из которых состоит пирамида, в определенном порядке без учета их удаленности от глаза наблюдателя. Поэтому нам нужно рисовать полигоны от дальнего к ближнему, чтобы эффект прозрачности не пропадал при повороте пирамиды. Займемся сортировкой полигонов в пирамиде. Поскольку полигоны представляют объекты разных классов 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 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); } } ------------------------------------------------------------------------------------------------------------ Теперь эффект полупрозрачности не зависит от вращения пирамиды. Получаем такую картинку:
|