Главная » Программирование игр под Android » Куб: Hello World в 3D – РАЗРАБОТКА ИГР ДЛЯ ОС ANDROID

0

В нескольких последних главах мы уже использовали концепцию пространства моделей: это пространство, в котором определены наши модели, оно никак не связано с пространством создаваемого мира. Мы применяем соглашение о создании всех объектов вокруг начала координат пространства моделей, поэтому центр объекта совпадает в началом координат. Такая модель может быть повторно использована для отрисовки нескольких объектов в различных позициях мира. Эта особенность была применена в масштабном примере BobTest.

Первое, что необходимо определить для куба, – угловые точки. На рис. 10.10 показан куб со стороной, равной одной единице измерения (например, 1 м). Я также немного разобрал этот куб для того, чтобы вы могли видеть отдельные грани, каждая из которых создана из двух треугольников. В реальности все грани сойдутся на границах куба, определяемых его угловыми точками.

Рис. 10.10. Куб и его угловые точки

Куб имеет шесть граней, каждая из которых состоит из двух треугольников. Два треугольника каждой грани имеют по две общие вершины. Например, для передней грани куба общими являются вершины с координатами (-0,5; 0,5; 0,5) и (0,5; -0,5; 0,5). Для каждой грани необходимо определить четыре вершины, для всего куба получается 6-4 = 24 вершины. Однако нам нужно определить 36 индексов, а не 24. Это необходимо потому, что всего имеется 6 х 2 треугольника, каждый из которых использует 3 из 24 вершин. Мы можем создать сеть для этого куба, используя индексацию вершин, как показано в этом сниппете:

В этом фрагменте кода определяем лишь позиции вершин. Начинаем с передней грани, ее нижняя левая вершина находится в точке с координатами (-0,5; -0,5; 0,5). Далее определяем следующие три вершины этой грани, двигаясь против часовой стрелки. Следующей будет правая грань куба, за ней задняя, левая, верхняя и нижняя. Все они определяются по заданному шаблону. Сравните определения вершин с рис. 10.10.

Далее определяем индексы. Всего имеется 36 индексов – каждая строка приведенного кода определяет два треугольника, каждый из которых состоит из трех вершин. Индексы (0,1,3,1,2,3) задают переднюю грань куба, следующие три – левую грань и т. д. Сравните эти индексы с вершинами, показанными в коде, а также с рис. 10.10.

После определения всех вершин и индексов мы можем сохранить их в экземпляре класса Verti ces3 для дальнейшей отрисовки, что мы и делаем в последних нескольких строках этого сниппета.

Что насчет координат текстур? Просто добавьте их к определению координат. Предположим, что у нас есть текстура размером 128 х 128, содержащая изображение одной грани ящика. Мы хотим использовать эту текстуру для каждой грани куба. На рис. 10.11 показано, как мы можем сделать это.

Рис. 10.11. Координаты текстур для каждой из вершин передней, левой и верхней граней (это же верно и для других граней)

Добавление текстурных координат для передней грани куба в коде будет выглядеть так:

Конечно, необходимо указать экземпляру класса Vertices3, что он содержит и координаты текстур:

Остается загрузить текстуру, разрешить наложение текстур с помощью метода gl Enable, а также привязать текстуру с помощью метода Texture.bind. Напишем пример.

Пример

Мы хотим создать сеть для куба, показанную в предыдущих примерах кода, и применить текстуру ящика. Поскольку куб моделируется в пространстве моделей, расположенном вокруг начала его координат, нам придется использовать метод gl Transl atef  для того, чтобы переместить его в пространство создаваемого мира так же, как мы поступили с моделью Боба в примере BobTest. Кроме того, мы хотим, чтобы наш куб вращался вокруг оси у. Этого мы можем достичь с помощью метода gl Rotatef , что мы также делали в примере BobTest. В листинге 10.6 приведен полный код класса CubeScreen, содержащегося в классе CubeTest.

Листинг 10.6. Фрагменты класса CubeTest.java: отрисовка текстур куба

У нас есть поле для хранения сети куба, экземпляр класса Texture, а также переменная, имеющая тип числа с плавающей точкой, для хранения текущего угла поворота. В конструкторе мы создаем сеть куба и загружаем текстуру из файла актива, который называется crate. png, текстуру, имеющую размеры 128 х 128 пикселов, представляющую собой изображение одной грани ящика.

Код, создающий куб, находится в методе createCube. В нем просто устанавливаются вершины и индексы, а затем из них создается экземпляр класса Verti ces3. Каждая вершина имеет позицию в трехмерном пространстве и координаты текстуры.

Метод resume просто сообщает текстуре, что ей необходимо перезагрузиться. Помните, текстуры необходимо перезагружать всякий раз, когда теряется контекст OpenGL ES.

Метод update О увеличивает угол поворота, на который куб будет повернут по оси у.

Метод present  сначала устанавливает окно отображения, а также очищает буферы цвета и глубины. Далее устанавливается перспективная проекция и в видовую матрицу OpenGL ES загружается единичная матрица. Мы разрешаем проверку глубины и текстурирование, привязываем текстуру, а также сеть куба. Далее используется метод gl Translatef  для того, чтобы передвинуть куб в точку с координатами (0; 0; -3) пространства мира. С помощью метода gl Rotatef (Поворачиваем куб в пространстве моделей вокруг оси у. Помните, что порядок, в котором преобразования применяются к сети, является обратным. Куб сначала будет повернут (в пространстве моделей), а затем его повернутая версия будет размещена в пространстве мира. Наконец, мы рисуем куб, убираем привязку mesh и отключаем проверку глубины и текстурирование. Нет необходимости отключать эти состояния. Я выполнил это только для того, чтобы в дальнейшем мы смогли отрисовать двухмерные элементы на верху трехмерной сцены. На рис. 10.12 показан результат работы нашей первой настоящей 3D -программы.

Рис. 10.12. Вращающаяся текстура куба в 3D

Источник: Mario Zechner / Марио Цехнер, «Программирование игр под Android», пер. Егор Сидорович, Евгений Зазноба, Издательство «Питер»

По теме:

  • Комментарии