Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OpenGL ES 1и2.docx
Скачиваний:
8
Добавлен:
01.07.2025
Размер:
4.8 Mб
Скачать

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);

            }

}

------------------------------------------------------------------------------------------------------------ 

Теперь эффект полупрозрачности не зависит от вращения пирамиды. Получаем такую картинку:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]