Фільтрація текстур – РОЗРОБКА ІГОР ДЛЯ ОС ANDROID

Є ще одна деталь, яку нам необхідно визначити перед тим, як ми зможемо використовувати обєкт текстури Вона повязана з тим, що наш трикутник може займати більше або менше пікселів на екрані в порівнянні з тим, скільки пікселів є у позначеній зоні текстури Наприклад, зображення Боба на рис 710 має розмір 128 х 128 пікселів Наш трикутник займає половину цього зображення, так що він використовує 128 х 128/2 пікселя з текстури (текстурні пікселі також називаються текселов) Коли ми намалюємо на екрані трикутник з координатами, які описали в попередньому фрагменті коду, він займатиме 320 х 480/2 пікселів На екрані ми використовуємо набагато більше пікселів в порівнянні з тим, що перенесли із зони текстури Природно, все може бути і навпаки: ми використовуємо менше пікселів на екрані, ніж на виділеній зоні текстури Перший випадок називається магніфікаціей, а другий – мініфікаціей У кожному з них нам необхідно повідомити OpenGL ES, як потрібно збільшувати або зменшувати текстуру У термінології OpenGL ES відповідні механізми називаються фільтрами мініфікаціі і магніфі-кации Ці фільтри є властивостями обєкта текстури, як і самі дані зображення Щоб їх встановити, необхідно спочатку перевірити, привязаний чи обєкт текстури за допомогою glBindTexture Якщо це так, встановлюємо їх таким чином:

В обох випадках використовуємо метод GL10 GlTexParameterf, який встановлює властивості текстури У першому випадку ми визначаємо фільтр мініфікаціі, а в іншому – фільтр магніфікаціі Перший параметр в цьому методі – тип текстури, який в нашому випадку за замовчуванням дорівнює GL10 GL TEXTURE 2D Другий параметр повідомляє методу, яке властивість ми хочемо встановити У нашому випадку це GL10GL TEXTURE MIN FILTER і GL10GL TEXTURE MAG FILTER Останній параметр вказує тип фільтра, який повинен бути використаний Тут у нас є два варіанти: GL10 GLJEAREST і GL10 GL LINEAR

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

На рис 712 показана різниця між цими двома типами фільтрів

Тепер наш обєкт текстури повністю визначений: ми створили ID, встановили графічні дані і визначили фільтри, які повинні бути використані, якщо наше зображення неідеально Як правило, ми одвязуємо текстуру після того, як закінчимо її описувати

Рис 712 Фільтр GL1OGL NEAREST робить зображення мозаїчним (ліворуч), фільтр GL10GL LINEAR трохи згладжує зображення (праворуч)

Нам також необхідно переробити растровий малюнок Bitmap, який ми завантажили, оскільки він нам більше не потрібен Навіщо витрачати память даремно Отвязиваніе можна зробити за допомогою наступного фрагмента коду:

О – це спеціальний ID, який повідомляє OpenGL ES, що слід відвязати поточний привязаний обєкт Якщо ми хочемо використовувати текстуру для малювання трикутників, нам, природно, потрібно заново її привязати

Видалення текстур

Корисно також знати, як видалити обєкт текстури з відеопамяті, якщо він нам більше не потрібен (так само, як ми використовуємо Bitmap Гесусе, щоб звільнити память малюнка) Це можна зробити за допомогою наступного фрагмента:

Зверніть увагу: спочатку нам потрібно впевнитися, що обєкт текстури, який ми хочемо видалити, не привязаний Залишилося частина коду нагадує етап з використанням glGenTextures для створення обєкта текстури

Корисний фрагмент коду

Ось (для довідки) повний приклад коду, призначений для обєкта текстури, завантаження графічних даних і установки фільтрів на Android:

Зовсім непогано Найважливіше тут – заново використовувати малюнок Bitmap, коли ми закінчимо Інакше ми будемо даремно витрачати память Дані нашого зображення надійно зберігаються у відеопамяті в обєкті текстури (До тих пір поки контекст вона буде загублений і нам не знадобиться заново все завантажити)

Активація текстурирования

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

Це має бути вам вже знайомо Коли ми включали / вимикали властивості вершини раніше, ми використовували метод gl Enabl е1ientState/gl Di sabl eCl i entState Як я говорив раніше, це всі особливості OpenGL Насправді є причини, чому вони не включені в glEnable/glDisab1e, але не будемо в це заглиблюватися Просто запамятайте, що треба використовувати gl Enabl eCl i entState / gl Di sabl eCl i entState, щоб включити / виключити властивості вершини, a glEnableC / glDisable для всіх інших станів OpenGL, наприклад текстурирования

Всі разом

Тепер ми нарешті можемо написати невеликий приклад, який зєднає всі разом У лістингу 77 показаний уривок з файлу з вихідним кодом TexturedTriangleTest java Тут наведена тільки потрібна нам частина з класом TexturedTriangleScreen

Лістинг 77 Уривок з TexturedTriangleTestjava: текстурирование трикутника

Я вирішив помістити завантаження текстури в метод loadTexture, який просто використовує імя завантажуваного зображення Метод повертає ID-обєкт текстури, згенерований OpenGL ES, який ми будемо прменять в методі present для привязки текстури

Опис нашого трикутника навряд чи вас здивує, ми просто додали координати текстур до кожної вершини

Метод present робить те ж, що й завжди: очищає екран і встановлює матрицю проекції Потім активуємо асоціювання текстур за допомогою виклику glEnableO і привязуємо наш обєкт текстури Залишилася частина така ж, як завжди: включення властивостей вершини, які ми хочемо використовувати, повідомлення OpenGL ES, де їх можна знайти і які кроки при цьому використовувати, і, нарешті, малювання трикутника з викликом gl DrawArrays На рис 713 показані результати виконання попереднього коду

Рис 713 Асоціювання текстури Боба з трикутником

Залишилася ще одна дуже важлива річ, яку ми не обговорили Всі растрові зображення, які ми завантажуємо, повинні мати ширину і висоту в ступені 2 Це аксіома, і якщо їй не слідувати, виникнуть проблеми

Що це означає Зображення Боба, яке ми використовували в нашому прикладі, має розмір 128 х 128 пікселів 128 – це 2 в сьомий ступеня (2 х 2 х 2 х 2 х 2 х 2 х 2) Інші розміри зображення можуть бути 2 х 8,32 х 16,128 х 256 і т д Існує також межа того, наскільки великі можуть бути зображення На жаль, він варіюється в залежності від можливостей апаратури, на якій запущено зображення Наскільки мені відомо, стандарт OpenGL ES 1x не описує мінімальний підтримуваний розмір текстури Проте, виходячи з мого досвіду, текстура 512×512 пікселів працює на всіх сучасних пристроях Android (і, швидше за все, буде працювати на всіх майбутніх) Я навіть дозволю собі припустити, що розмір 1024 х 1024 також підійде

Ще один момент, який ми досі ігнорували, – це глибина кольору текстур На щастя, метод GLUti 1 s texImage2D, який ми використовували для завантаження даних нашого зображення в центральний процесор, досить успішно справляється з цим OpenGL ES може працювати з такою глибиною кольору, як RGBA8888, RGB565 і т д Ми завжди повинні намагатися використовувати найменшу можливу глибину кольору, щоб зменшити необхідну пропускну спроможність Для цього ми можемо використовувати клас Bi tmapFactory Opti ons, як у попередніх розділах, щоб, наприклад, завантажити зображення RGB888 або зображення RGB565 Коли ми завантажили екземпляр класу Bitmap з тією глибиною кольору, яка нам потрібна, ми використовуємо GLUti 1 s texImage2D, який перевіряє, чи отримав OpenGL ES дані зображення у вірному форматі Звичайно, ви завжди повинні перевіряти, чи позначається зменшення глибини кольору негативно на зовнішньому вигляді гри

Клас Texture

Щоб зменшити кількість коду, необхідного для наступних прикладів, я написав невеликий допоміжний клас Texture Він завантажить зображення з ресурсу і створить з нього обєкт текстури У нього також є кілька зручних методів, щоб привязати текстуру і щоб позбавитися від неї Код приведений в лістингу 78

Лістинг 78 Texturejava, невеликий клас Texture для OpenGL ES package combadlogicandroidgamesframeworkgl

Єдиний цікавий компонент цього класу – метод reload, який ми можемо використовувати, коли контекст OpenGL ES загублений Зверніть також увагу, що метод setFiltersO буде працювати тільки в тому випадку, якщо Texture привязаний В іншому випадку він встановить фільтри поточної привязаною текстури

Ми могли б також написати невеликий допоміжний метод для обробки буфера наших вершин Але перед цим потрібно обговорити ще одну деталь: індексовані вершини

Джерело: 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>

*

*