OpenGL ES
Термин OpenGL ES часто попадается мне на глаза. О том, что это такое, можно почитать в Википедии и других местах. Для общего развития мне захотелось узнать, что это за зверь такой. Это статья неспециалиста по данной теме. Написал, чтобы оставить статью на память. Может потом буду возвращаться к статье и дополнять её.
Кстати, пример не заработал на эмуляторе, хотя вроде на форумах говорят, что последние сборки ADT для Eclipse поддерживают OpenGL ES на эмуляторе. Я проверял на своём устройстве. Примеры будут расчитаны только на OpenGL ES 2.0, который занимает 99.8% на устройствах. Говорят, что версия 2.0 сильно отличается от версии 1.1 и изучать платформу по старым примерам смысла нет.
Создаём стандартный проект. В коде главной активности пишем код:
Показать код (щелкните мышкой)
В коде идёт обращение к классу LessonOneRenderer. Создадим его:
Показать код (щелкните мышкой)
В манифесте сообщим системе, что собираемся использовать OpenGL ES версии 2.0:
Из того, что понял из статьи — В проектах используется компонент GLSurfaceView, на котором происходит рисование графики.
В методе onCreate() происходит проверка на поддержку второй версии OpenGL и подключается свой класс, в котором содержится логика отрисовки графики.
Также следует прописать одноимённые методы в методах активности onResume() и onPause().
В классе LessonOneRenderer идёт тарабарщина, которая мне пока не понятна. Я с трудом понимаю, как это можно запомнить и пользоваться. Поэтому я просто скопировал код, скомпилировал проект и запустил на телефоне. Получил работающую программу с цветными треугольниками и доволен как слон. А вы по-прежнему хотите изучать OpenGL ES?
Источник
Полный список
— создаем простейший пример с OpenGL
Продолжаем тему графики, и переходим на следующий уровень, который называется OpenGL ES. Расшифровывается это как OpenGL for Embedded Systems, т.е. OpenGL для встраиваемых систем (android-девайсы в нашем случае).
Пару лет назад я читал книгу по этой теме, делал из нее примеры и, в целом, без особых проблем понял, все что там было написано. Но та книжка была по OpenGL ES версии 1.0. Cейчас эта версия уже устарела и используются версии 2.0, 3.0 и 3.1. Эти версии по API существенно отличаются от 1.0 и несовместимы с ней. Поэтому мне самому придется изучать тему почти заново.
Первый урок будет похож на Урок 141. Мы выполним минимальный набор действий, чтобы заполнить экран каким-либо цветом, но в этот раз сделаем это с помощью OpenGL. Кстати, сразу хочу предупредить, что OpenGL это не обязательно 3D. Сначала мы немного порисуем 2D, а потом добавим объем.
Ну и как обычно, поначалу, скорее всего, мало что будет понятно, но по мере погружения в тему общая картина будет проясняться.
Приступим к созданию нашего первого минимального примера. Обсудим его ключевые элементы.
1) Изображение надо на чем-то показывать. Для этого мы будем использовать компонент GLSurfaceView (далее — surface).
2) Изображение кто-то должен создавать, т.е. принимать от нас инструкции, что и как рисовать. Этим будет заниматься Renderer (далее — рендер).
3) Ну и нужна будет проверка, что девайс поддерживает OpenGL 2.0, иначе ничего не будет работать.
Начнем с создания класса рендера. Объект этого рендер-класса мы потом будем передавать в surface, которое в процессе своей работы будет вызывать методы рендера.
Рендер имеет три метода:
onSurfaceCreated — вызывается при создании/пересоздании surface. Т.е. метод будет вызываться при запуске приложения или, например, в уже запущенном приложении при выходе девайса из сна. Здесь будет выполняться установка OpenGL параметров и инициализация графических объектов.
onSurfaceChanged — вызывается при изменении размера surface. Самый распространенный пример — смена ориентации экрана.
onDrawFrame — вызывается, когда surface готово отобразить очередной кадр. В этом методе мы и будем создавать изображение.
Создаем класс OpenGLRenderer, который реализует интерфейс Renderer:
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
import static android.opengl.GLES20.glClear;
import static android.opengl.GLES20.glClearColor;
import static android.opengl.GLES20.glViewport;
public class OpenGLRenderer implements Renderer <
@Override
public void onDrawFrame ( GL10 arg0 ) <
glClear ( GL_COLOR_BUFFER_BIT ) ;
@Override
public void onSurfaceChanged ( GL10 arg0, int width, int height ) <
glViewport ( 0 , 0 , width, height ) ;
@Override
public void onSurfaceCreated ( GL10 arg0, EGLConfig arg1 ) <
glClearColor ( 0f , 1f , 0f , 1f ) ;
>
В onSurfaceCreated мы вызываем метод glClearColor и передаем ему RGBA-компоненты в диапазоне от 0 до 1. Тем самым мы устанавливаем дефолтный цвет, который будет отображаться после полной очистки surface.
А в методе onDrawFrame мы как раз выполняем эту очистку. Метод glClear с параметром GL_COLOR_BUFFER_BIT очистит все цвета на экране, и установит цвет, заданный методом glClearColor.
В методе onSurfaceChanged мы методом glViewPort задаем область surface, которая будет доступна для вывода изображения. Мы указываем левую нижнюю точку — (0,0) и размеры области — (width, height), т.е. изображение будет выведено на все surface.
Рендер готов. Теперь надо в Activity повесить surface и настроить его.
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 MainActivity extends Activity <
private GLSurfaceView glSurfaceView;
@Override
protected void onCreate ( Bundle savedInstanceState ) <
super .onCreate ( savedInstanceState ) ;
if ( !supportES2 ()) <
Toast.makeText ( this, «OpenGl ES 2.0 is not supported» , Toast.LENGTH_LONG ) .show () ;
finish () ;
return ;
>
glSurfaceView = new GLSurfaceView ( this ) ;
glSurfaceView.setEGLContextClientVersion ( 2 ) ;
glSurfaceView.setRenderer ( new OpenGLRenderer ()) ;
setContentView ( glSurfaceView ) ;
>
@Override
protected void onPause () <
super .onPause () ;
glSurfaceView.onPause () ;
>
@Override
protected void onResume () <
super .onResume () ;
glSurfaceView.onResume () ;
>
private boolean supportES2 () <
ActivityManager activityManager =
( ActivityManager ) getSystemService ( Context.ACTIVITY_SERVICE ) ;
ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo () ;
return ( configurationInfo.reqGlEsVersion >= 0x20000 ) ;
>
В onCreate мы сначала нашим методом supportES2 определяем, что девайс поддерживает OpenGL ES 2.0 и выше. Если нет, то закрываемся.
Если же все ок, то
— создаем GLSurfaceView,
— методом setEGLContextClientVersion говорим ему, что будем использовать OpenGL ES версии 2
— методом setRenderer передаем экземпляр нашего класса OpenGLRenderer. Теперь этот рендер будет отвечать за то, что будет нарисовано на surface
— методом setContentView ставим surface как основное View для Activity
Кроме этого, необходимо привязать surface к lifecycle-методам Activity: onPause и onResume, вызвав в них одноименные surface-методы.
Все готово. Запускаем
Экран заполнен зеленым цветом. Первое простейшее OpenGL-приложение готово. Не Need For Speed конечно, но с чего то ж надо начинать )
Три момента, на которых я хотел бы еще остановиться
1) Почему-то не работает alpha-компонент в методе glClearColor. Т.е. передаете последним параметром хоть 0 хоть 1, прозрачность не добавляется. На этот вопрос у меня пока ответа нет.
2) Координаты viewport, которые мы задаем методом glViewport никак не влияют на результат, и даже если задать область viewport только в половину surface, все равно в зеленый цвет будет закрашена все surface. По этому поводу я вычитал, что это норма. Метод glClear работает на все surface, независимо от размера viewport.
3) По поводу запуска приложений. Обычно пишут, что OpenGL ES не пашет на эмуляторах. Я не проверял на стандартном эмуляторе, но на Genymotion запуcкается без проблем. На крайняк всегда есть реальный девайс, можно тестить на нем.
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник
OpenGL в смартфонах — что это и зачем нужно?
Принцип работы и применение технологии OpenGL ES 2.0.
Сейчас трехмерные изображения стали привычными. Чаще всего они встречаются в фильмах со специальными эффектами, компьютерных и мобильных играх. На заре становления компьютерной графики не существовало единого стандарта, и все программы создавались практически «с нуля», на основе своих методов отображения графической информации.
Позже, когда трехмерная графика стала доступной не только для суперокомпьютеров, но и для обычных ПК, появилась насущная потребность в едином стандарте в области графики. Одним из них и стал OpenGL (Open Graphics Library — «открытая графическая библиотека»). На сегодня это один из самых популярных графических стандартов в мире.
OpenGL основан на графической библиотеке IRIS GL, созданной компанией Silicon Graphics. Стандарт был разработан и утвержден в 1992 году целой группой крупнейших разработчиков, в число которых вошли Silicon Graphics, IBM Corporation, Microsoft, Hewlett-Packard Corporation, Sun Microsystems, Intel Corporation, Evans & Sutherland и другие.
Технология OpenGL в телефонах
OpenGL — спецификация, благодаря которой мобильные устройства получили возможность отображать графику уровня игровых приставок. Стандарт включает более 300 функций для отрисовки сложных трехмерных сцен. Он относится к открытым спецификациям, что позволяет написанные с его помощью программы портировать на любые платформы. При этом результат будет одинаковым, будь это мощный профессиональный компьютер или обычный смартфон.
OpenGL позволяет получить на смартфоне более быструю и плавную работу интерфейса, а также высокую производительностью в 3D-приложениях, в том числе и в играх. В современных смартфонах используется версия OpenGL ES 2.0.
Данную опцию можно включить на мобильном устройстве через режим разработчика. Для этого нужно войти в «Настройках» в раздел «О телефоне» и 7 раз подряд нажать по надписи с версией операционной системы или по версии сборки (в зависимости от производителя). Далее нужно найти в разделе «Для разработчиков» опцию 4X MSAA. Если ее включить, активируется четырехкратное сглаживание в технологии OpenGL ES 2.0. Это улучшит качество графики на смартфоне, но приведет к более быстрой разрядке аккумулятора.
Стандарт OpenGLв смартфонах позволяет значительно повышать качество графики в приложениях и играх. Минус этой спецификации — высокая нагрузка на системные ресурсы и батарею устройства.
Источник
Разработка OpenGL приложения под Android. Часть 1. Знакомство.
Доброго времени суток.
Это вторая часть цикла статей «Разработка OpenGL приложения под Android».
Начнем с того, что сегодня самый лучший день для того, чтобы написать свое первое приложение для android. Если у Вас что-то не получалось до этого момента — будьте уверены, сегодня все получится!
И так. Вы установили новейшую версию Android Studio и все необходимые компоненты для работы с Android 4.4 ? Немного пощупали, изучили основные принципы работы в данной IDE и готовы покорять мир 3D графики? Отлично! Тогда приступим к работе.
- В первую очередь создадим проект и назовем его OGLPart1 .
Вы можете назвать его как угодно, но мне так будет удобнее. Уроков будет много и что бы не запутаться в них я буду нумеровать проекты эквивалентно статьям. Здесь все просто. Все, что от Вас требуется это указать имя проекта, папку для его хранения и минимальную поддерживаемую версию android. Стандартная процедура.
- Теперь перед нами окно выбора шаблона приложения.
Я рекомендую Вам выбрать Blank Activity . В ином случае Вам может показаться, что в приложении много «лишнего» кода. Для начала этого вполне достаточно.
- Диалог настройки активити
Он предложит нам сменить имя активити, заголовок .xml файла, содержащего его описание и прочие параметры.
Оставим все как есть.
При желании все это можно сменить позже, так что не пугайтесь и не волнуйтесь если что-то сделали не так.
Жмем кнопку » Finish » и через некоторое время перед нами появляется activity_main.xml файл. Точнее его графическое представление.
Снизу, под списком элементов, расположены две закладки: Design и Text . Если Вы будете нажимать на них(поверьте, Вы будете), то увидите, что с их помощью можно переключаться между графическим редактором интерфейса программы и кодом.
Слева Вы видите структурное дерево проекта. Именно там нужно выбирать файл для работы с ним.
Сверху расположены различные элементы управления.
Интересными, в данный момент, для нас являются два:
Первый — зеленый треугольник. Эта кнопка служит для компиляции и запуска наших гениальных программ.
Второй — это менеджер виртуальных устройств. Эмуляторов, говоря другими словами. Нажмем на него.
Перед нами появилось окно виртуальных устройств. Скорее всего, если Вы еще не создали ничего без меня, то список устройств будет пуст.
Без паники! Это легко исправить. Кликаем по кнопке » Create Virtual Device. » и выставляем нужные нам настройки. Все просто!
/* Только не забываем, что минимальная версия Android на девайсе тоже должна быть 4.4 . */
Готово! Теперь при нажатии на кнопку запуска приложения оно будет запускаться через наш эмулятор.
Перед тем как окунуться с головой в программирование нам нужно закинуть на форму специальный элемент GLSurfaceView . Именно он предназначен для работы с OpenGL командами и вывода изображения на дисплей устройства. Поищите его в списке элементов.
Да, я тоже долго искал и думал, что просто не могу его заметить. Его там нет. Почему-то его не посчитали нужным вынести на панель, но мы это исправим.
Видите TextView с текстом » Hello, world! «? Мы превратим его в GLSurfaceView. Как Вам идея? Мне нравится, а у Вас все равно нет выбора, раз Вы до сих пор читаете.
/* Вообще, Вы можете сделать так с любым элементом или без элемента вообще, просто добавив нужный код в activity_main.xml */
Переходим в файл activity_main.xml и находим там описание TextView.
Оно будет выглядеть примерно следующим образом:
Круто! У нас теперь есть настоящий GLSurfaceView с id glSurfaceView , растянутый на все окно. Почти.
Остались зазоры по краям. Это происходит из-за того, что у RelativeLayout свойство padding по всем сторонам выставлено по умолчанию в 16dp. Что бы это исправить достаточно добавить в его описание такую строчку: android:padding=»0dp»
/* Больше я не буду подробно останавливаться на интерфейсе Android Studio и том, что касается визуальной настройки приложения. Наша статья не об этом. Мы знакомимся с OpenGL 1.0 . */
- Переходим к файлу MainActivity.java .
Студия создала для нас несколько функций в классе MainActivity для удобства, но нам нужна только одна:
/* Возможно, у Вас не будет необходимости в этом и Ваша Android Studio выдаст такой код сразу. */
Каракас нашей реализации класса Renderer готов.
Следующим нашим шагом будет его «установка» в glSurfaceView, так что возвращаемся в класс MainActivity и после описания glSurfaceView добавляем следующий код:
/* Я намеренно вернул вас в класс MainActivity для того, чтобы Вы сразу подключили Renderer к glSurfaceView и не забыли о нем.
А теперь я намеренно верну вас назад в класс OpenGLRenderer. */
Лучше некуда! Теперь это уже что-то похожее на реальное приложение, но оно совсем скучное и совсем ничего не делает. Мы с Вами совсем скоро это исправим, но, мне кажется, Вы хотите знать что значат все эти методы. И я Вам расскажу.
Этот метод вызывается для отрисовки текущего кадра. Для простоты можно сказать, что он постоянно работает и постоянно зациклен.
В качестве параметров несет в себе GL10 — интерфейс OpenGL1.0.
Мы проделали уже не мало работы, но наше приложение так ничего и не рисует. Это слегка огорчает, не так ли?
Обещаю, больше в этом уроке не будет ничего скучного. Мы начинаем КВН рисовать!
Весь код класса OpenGLRenderer:
- Теперь несколько слов по функции glLoadIdentity() :
Эта функция умножает текущую матрицу на единичную и, говоря другими словами, «обнуляет» ее.
Это нужно для того, что бы проделанные нами трансформации корректно отображались на экране.
Наша переменная angle содержит сначала 1, затем 2, затем 3 и так далее. И в каждый кадр у нас происходит поворот на этот угол.
Ели бы мы не сбрасывали матрицу, мы бы поворачивали объект ЕЩЕ НА 1 , ЕЩЕ НА 2 , ЕЩЕ НА 3 и т.д. градуса, а с применением glLoadIdentity() мы просто поворачиваем НА 1 , НА 2 , НА 3 и т.д. градуса.
Надеюсь, это понятно. Если нет — попробуйте запустить код без glLoadIdentity().
Источник