Вивчаємо OpenGL ES2 для Android

Урок №1
Дана стаття написана для новачків, які (як і я) хочуть навчитися писати програми для Андроїд з використанням OpenGL. Основні думки та код взяті з чудової книги Кевіна Бразалера «OpenGL ES 2 for Android. A Quick-Start Guide by Kevin Brothaler» (1).
Навіщо ж переказувати, запитаєте ви? Справа в тому, що перед цією книгою я прочитав ще десяток статей на цю тему і код Кевіна у мене відразу не пішов (у книзі середовище розробки Eclipse, а у мене Android Studio). Тому, вирішив написати цю статтю так, щоб було зрозуміло, передусім, самому собі.
Для початку давайте з'ясуємо, що таке OpenGL. Якщо почитати Вікіпедію (2), то побачимо наступне:
«OpenGL (Open Graphics Library) — специфікація, що визначає незалежний від мови програмування платформонезависимый програмний інтерфейс для написання застосунків, що використовують двовимірну і тривимірну комп'ютерну графіку.
Включає більше 300 функцій для малювання складних тривимірних сцен з простих примітивів. Використовується при створенні комп'ютерних ігор, САПР, віртуальної реальності, візуалізації в наукових дослідженнях. На платформі Windows конкурує з Direct3D.»
Ми будемо вивчати укорочену версію OpenGL ES 2 (надалі OpenGL). Вкоротили її зі зрозумілих причин, у Андроїд мала операційна пам'ять у порівнянні з настільними ПК, наявність віртуальної машини Java також накладає певні обмеження. Напевно є ще багато причин, чому це зробили, але нас це не повинно хвилювати. Простий треба знати, що є прекрасний інструмент OpenGL і треба навчитися ним користуватися!

у вас на комп'ютері повинна бути встановлена середовище розробки Android Studio (3). Бажано до неї підключити реальний пристрій, так як досвід показав, що емулятори погано працюють з OpenGL. У моєму випадку це буде планшет Samsung GT-P3113 Android 4.2.2, API 17.
Наше завдання написати і запустити програму, яка буде циклічно очищати екран і заливати його червоним кольором з допомогою засобів OpenGL.

Крок перший. Створення проекту.
1.1 Відкрийте Android Studio і створіть новий проект.

1.2. Виберіть папку, де ви будете зберігати проект і введіть назву програми
First Open GL Project.

1.3. Виберіть найменшу версію пристрою, на якому може працювати ваше додаток. OpenGL ES2 підтримується починаючи з Android 2.3.3 (Gingerbread), таким чином, ми охоплюємо приблизно 100% пристроїв на Google Play.

1.4. Виберіть порожній бланк Актівіті. Назвіть головне Актівіті FirstOpenGlProjectActivity, Лэйаут можна не створювати, але якщо вирішили створити, то назвіть activity_first_open_glproject. Чекаємо деякий час, поки йде збірка проекту.

Крок другий. Запуск проекту
2.1 Запускаємо проект на реальному пристрої.

2.2 Оберіть для перегляду головне Актівіті і замість того, що там сгенерировалось автоматично, вставте наступний код. Надалі ми розберемо порядково, що він робить.

package com.adc2017gmail.firstopenglproject;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ConfigurationInfo;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.widget.Toast;

public class FirstOpenGLProjectActivity extends Activity {
private GLSurfaceView glSurfaceView;
private boolean rendererSet = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
glSurfaceView = new GLSurfaceView(this);

// Перевіряємо чи підтримується OpenGL ES 2.0.
final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
final boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;
if (supportsEs2) {
// Request an OpenGL ES 2.0 compatible context. glSurfaceView.setEGLContextClientVersion(2);
// Assign our renderer.
glSurfaceView.setRenderer(new FirstOpenGLProjectRenderer()); rendererSet = true;
} else {
Toast.makeText(this, "This device does not support OpenGL ES 2.0.", Toast.LENGTH_LONG).show(); return;
}

setContentView(glSurfaceView);

}

@Override
protected void onPause() { super.onPause();
if (rendererSet) {
glSurfaceView.onPause();
}
}
@Override
protected void onResume() { super.onResume();
if (rendererSet) {
glSurfaceView.onResume();
}
}

}


Android Studio повинна лаятися, так як в коді у нас є посилання на новий клас FirstOpenGLProjectRenderer. Студія запропонує вам створити цей клас. Натисніть на червону лампочку у коду правою кнопкою миші і виберіть створити клас. Назвіть його FirstOpenGLProjectRenderer.
В результаті у вас структура проекту буде такою.

Відкрийте документ FirstOpenGLProjectRenderer. Видаліть те, що в ньому сгенерировалось і вставте наступний код.

package com.adc2017gmail.firstopenglproject;

import android.opengl.GLSurfaceView.Renderer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import static android.opengl.GLES20.glClearColor;
import static android.opengl.GLES20.glClear;
import static android.opengl.GLES20.glViewport;
import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;

public class FirstOpenGLProjectRenderer implements Renderer {
@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {glClearColor(1.0 f, 0.0 f, 0.0 f, 0.0 f);
}

@Override
// Set the OpenGL viewport to fill the entire surface.
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
glViewport(0, 0, width, height);

}

@Override
// Clear the rendering surface.
public void onDrawFrame(GL10 glUnused) {
glClear(GL_COLOR_BUFFER_BIT);
}

}


Тепер помилок бути не повинно. Запускаємо проект на виконання.
На екрані має з'явитися іконка програми, а сам екран заллє червоним кольором.

Крок третій. Що сталося?
Розберемо код порядково. Почнемо з головного Актівіті.

Рядок (З) 1. Оголошується назва пакету. Складальник проекту Андроїд Студіо по ньому збирає наш проект.
З 3 – 9. Імпортуються потрібні бібліотеки для роботи нашої головної Актівіті і класу FirstOpenGLProjectActivity.
З 11. Оголошуємо про створення класу FirstOpenGLProjectActivity, який успадковується від класу Activity.
З 12. Створюємо об'єкт GLSurfaseView однойменного класу.
GLSurfaceView це спеціальний клас, який управляє поверхнею OpenGL і перетворює її в зрозумілу для Андроїда середу відображення. У класу є безліч функцій, які роблять OpenGL простіше у використанні. Ось деякі з функцій, найпоширеніші з них:
— GLSurfaceView забезпечує роботу в окремому потоці (thread) для візуалізації OpenGL, таким чином основний потік у нас не зайнятий.
— підтримує безперервний або на вимогу рендеринг (оновлення, оновлення вмісту на екрані).
— підтримує налаштування екрану для EGL, інтерфейсу між OpenGL і нашої віконною системою.
З 13. Створюємо булеву змінну rendererSet, яка за умовчанням приймає значення false. Вона буде керувати роботу класу GLSurfaceView в режимах паузи і очікування основного Актівіті.

З 15. Анотація, говорить, що перевизначений метод.
З 16. Оголошення методу onCreate (працює при запуску програми).
З 18. Створення нового об'єкта glSurfaseView.
З 20 – 30. Перевірка, чи підтримує наш пристрій OpenGL ES 2? Схоже, що ця перевірка застаріла і не потрібна. Вже всі Андроїд пристрої підтримують OpenGL ES 2, тим більше ми нічого не пропонуємо взамін, крім фрази «This device does not support...». Без неї все чудово працює, можна залишити тільки рядок 27.
Від ActivityManager отримуємо інформацію, яка дозволяє нам витягнути зі стану системи конфігурацію пристрою. А вже з неї ми отримуємо інформацію, яка допоможе нам зрозуміти підтримує наш пристрій OpenGL ES 2.
З 27. Задаємо поверхню і параметри промальовування з допомогою класу FirstOpenGLProjectRenderer ().
32. Виводимо на екран вміст.

З 36 – 47 Два методи, які призупиняють виведення на екран вмісту, якщо наше Актівіті не активно і знаходиться в режимі очікування або паузи.
GLSurfaceView вимагає, щоб ми викликали його методи onResume() і OnPause(), коли батьківське Актівіті викликає свої методи onResume() і onPaused(). Ми додаємо виклик цих методів, щоб правильно відновлювати і завершувати нашу діяльність.

Тепер розглянемо, що робить клас FirstOpenGLProjectRenderer.

С1. Оголошуємо ім'я пакета складання програми
С3-С9. Імпортуємо потрібні бібліотеки

С11. Оголошуємо клас
С13. Метод, який заливає поверхню червоним кольором. Перші три параметра в дужках методу glClearColor задають вагові коефіцієнти для червоного, зеленого і синього, а останній – задає прозорість шару. Якщо ми змінимо перший коефіцієнт на 0, а другий на 1, то отримаємо зелений екран. Упевнений, що ви і скажіть, які кольори екрана буде, якщо два перших коефіцієнта дорівнюють 1. Поиграйтесь. 
С18,19. Метод задає розміри шару. В даному випадку поверхня буде на всю довжину і ширину екрану пристрою.
С25. Метод очищає поверхню від вмісту. Його викликають, коли настав час, щоб зробити новий кадр. Ми повинні все одно щось намалювати, навіть якщо треба просто очистити екран. Буфер візуалізації буде замінений і вміст з'являється на екрані після того, як викликаний цей метод, так що якщо ми нічого не намалюємо, то скоріше за все отримаємо мерехтливий екран.
Чому ми робимо в цих методах посилання на GL10? Розробники запозичують методи розроблені під OpenGL ES 1.0 API. Вони добре працюють і в версії ES2.
Підіб'ємо підсумок.
Ми створили проект, ініціалізувати OpenGL ES2, запустили потік очищення і промальовування екрану. А головне – OpenGL не такий вже і страшний, порівняно з тим, що ми намалювали .

Посилання:
1. pragprog.com/book/kbogla/opengl-es-2-for-android
2. ru.wikipedia.org/wiki/OpenGL
3. developer.android.com/sdk/index.html

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.