Індексуватися ВЕРШИНИ: ВИКОРИСТОВУЄМО ПОВТОРНО – РОЗРОБКА ІГОР ДЛЯ ОС ANDROID

&nbsp

До цих пір ми завжди описували список трикутників, де кожен трикутник має власний набір вершин Насправді ми встигли намалювати тільки один трикутник, але додати ще дещо не складе особливих труднощів

Проте існують випадки, коли два або більше трикутників можуть ділити деякі вершини Розглянемо, як ми можемо візуалізувати прямокутник за допомогою вже вивчених прийомів Ми просто визначимо два трикутника, які матимуть дві вершини з однаковими координатами місця, квітами та текстурами

Однак ми можемо зробити ще краще На рис 714 показані старий і новий способи візуалізації прямокутника

Рис 714 Візуалізація прямокутника як двох трикутників з шістьма вершинами (ліворуч) та його візуалізація з чотирма вершинами (праворуч)

Замість дублювання вершин vl і v2 з вершинами v4 і v6 ми просто описуємо ці вершини один раз Ми як і раніше визуализируем два трикутника в даному випадку, однак явно повідомляємо OpenGL ES, які вершини використовувати для кожного трикутника (наприклад, vl, v2 і v3 для першого трикутника і v3, v4 і vl для другого) Те, які вершини застосовувати для кожного трикутника, визначається за індексами в масиві вершин Перша вершина в нашому масиві має індекс О, друга вершина має індекс 1 і т д Для попереднього прямокутника у нас буде наступний список індексів:

До речі, OpenGL ES воліє визначати індекси в форматі чисел short (правда, тут ми також можемо використовувати байти) Проте, як і з даними вершин, ми не можемо просто передати OpenGL ES масив short Йому потрібен прямий ShortBuf fer Ви вже знаєте, як це робити:

Short потрібно 2 байта памяті, так що виділяємо i ndi ces 1 ength х 2 байтів для нашого ShortBuffer Знову встановлюємо початковий порядок і отримуємо вид ShortBuffer, щоб нам було простіше обробити базовий ByteBuffer Все, що залишилося, – зібрати всі індекси в ShortBuffer і викликати f1iр, щоб всі позиції були встановлені правильно

Якби нам було потрібно намалювати Боба як прямокутник з двома індексованими, ми могли б описати вершини наступним чином:

Порядок вершин повністю збігається з правою частиною рис 714 Ми повідомляємо OpenGL ES, що у нас є координати положення, а також текстури для наших вершин Ще повідомляємо, де можна знайти ці властивості вершин за допомогою звичайного виклику gl Enabl eCli entState О і gl VertexPoi nter / glTexCoordPoi nter Єдина різниця полягає в методі, який ми викликаємо для малювання двох трикутників:

Все це дуже схоже на gl DrawArrays Перший параметр визначає тип елемента, який ми хочемо візуалізувати, – у нашому випадку це список трикутників Наступний параметр задає, скільки вершин ми хочемо використовувати (у нашому випадку – шість) Третій параметр вказує, який тип індексів ми задіємо (у нас це числа short без знака) Зверніть увагу, що в Java немає типів беззнакових типів Тим Проте, враховуючи кодування чисел зі знаками з порозрядним доповненням до одиниці, цілком доречно використовувати ShortBuffег, який працює з числами short зі знаками Останній параметр – наш ShortBuf fer, що містить шість індексів

Що ж робить OpenGL ES Системі відомо, що ми хочемо візуалізувати два трикутники, оскільки ми вказали, що збираємося візуалізувати шість вершин Але замість того, щоб перенести шість вершин по черзі з масиву вершин, він послідовно проходить через буфер індексів і використовує індексовані вершини

Всі разом

Коли ми всі обєднаємо, отримаємо код, як в лістингу 79

Лістинг 79 Уривок з IndexedTestjava малюємо два індексованих трикутника

Зверніть увагу, як зручно використовувати клас Texture, який значно скорочує кількість коду На рис 715 показаний результат

Тепер все дуже схоже на те, як ми працювали з Canvas У нас також набагато більше гнучкості зараз, оскільки ми більше не обмежені осями

Цей приклад описує все, що нам на даний момент треба знати про вершинах Ми побачили, що кожна вершина повинна мати як мінімум становище, але вона також може володіти додатковими властивостями, такими як колір, даний у чотирьох значеннях з плаваючою точкою (формат RGBA), і текстурні координати Ми також побачили, що можемо повторно використовувати вершини за допомогою індексації у разі, якщо хочемо уникнути дублювання Це дозволяє нам трохи прискорити роботу, оскільки OpenGL ES доведеться множити вершини на проекцію і матриці вигляду моделі не більше, ніж потрібно (давайте зупинимося на такій інтерпретації, хоча вона і не зовсім вірна)

Рис 715 Індексований Боб

Клас Vertices

Давайте спростимо код, створивши клас Vertices, який може містити максимальну кількість вершин і при необхідності індексів, використовуваних при візуалізації Він повинен також забезпечувати всі стани, потрібні для візуалізації, а також очищати стану після візуалізації, щоб інший код міг грунтуватися на чистому наборі станів OpenGL ES У лістингу 710 показаний клас Vertices

Лістинг 710 Verticesjava інкапсульовані (індексовані) вершини package combadlogiсandroidgamesframeworkgl

Клас Vertices містить посилання на екземпляр класу GLGraphics, тому ми можемо отримати екземпляр класу GL10, як тільки він знадобиться Ми також зберігаємо інформацію про те, чи мають вершини колір і текстурні координати Так досягається значна гнучкість, оскільки ми можемо вибрати мінімальний набір властивостей, які нам потрібні для візуалізації Ми також зберігаємо FloatBuffer, який містить наші вершини, і ShortBuffer, що включає в себе додаткові індекси

У конструкторі визначаємо, яку максимальну кількість вершин та індексів може містити екземпляр класу Verti ces, а також чи мають вершини колір і текстурні координати Усередині конструктора встановлюємо відповідні елементи і вказуємо значення буферам Зверніть увагу: якщо maxlndices дорівнює нулю, ShortBuffer отримає значення null У такому випадку візуалізація буде виконуватися без індексування

Переходимо до методів setVertices і setlndices Останній видаватиме виняток NullPointerException, якщо екземпляр класу Vertices не зберігаються індекси Все, що нам треба робити, – очищати буфери і копіювати вміст масивів

Останній метод класу Vertices – draw Він використовує тип елемента (наприклад, GL10 GLTRI ANGLES), зміщення в буфері вершин (або буфері індексів, якщо ми користуємося індексами) і кількість вершин, застосовуваних для візуалізації Залежно від того, чи мають вершини колір і текстурні координати, включаємо відповідні стану OpenGL ES і повідомляємо OpenGL ES, де знайти дані Природно, ми робимо те ж саме для положення вершин, оскільки ця інформація буде нам турбуватися постійно Залежно від того, чи використовуються індекси, викликаємо glDrawElements або glDrawArrays з відповідними параметрами Зверніть увагу, що параметр зміщення може також застосовуватися при індексованої візуалізації: ми просто встановлюємо положення буфера індексів таким чином, що OpenGL ES починає читати індекси з точки, де відбулося зміщення, а не з першого індексу буфера У методі draw Про залишилося тільки очистити стану OpenGL ES Викликаємо gl Disabled ientStateC) з GL10 GL C0L0R ARRAY або GL10, GL TEXTURE COORD ARRAY, якщо у вершин є ці атрибути Нам потрібно це зробити, оскільки інший примірник класу Vertices може не використовувати ці атрибути Якби ми візуалізували другий екземпляр класу Vertices, OpenGL ES і раніше шукав би координати кольору і текстур

Ми можемо замінити весь складний код конструктора з попереднього прикладу наступним фрагментом:

Ми також можемо замінити всі виклики, зайняті установкою наших масивів з атрибутами, а також зайняті відображенням, наступним викликом:

Разом з класом Texture у нас може вийти досить хороша основа для двомірної візуалізації в OpenGL ES Одна з деталей, яких нам досі не вистачає для повного відтворення можливостей нашого Canvas, – це змішування Давайте їм займемося

Джерело: Mario Zechner / Маріо Цехнер, «Програмування ігор під Android», пров Єгор Сидорович, Євген зазноби, Видавництво «Пітер»

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*