Android — Android + OpenGL


Содержание

OpenGL для Android на Java и C++

АЛЕКСЕЙ ВЕРИЖНИКОВ, филиал ЗАО «Корпорация ГРИНН» туристический многофункциональный комплекс «ГРИНН», системный архитектор, mail_aw@mail.ru

OpenGL для Android на Java и C++

В данной статье поговорим о программировании компьютерной графики на основе OpenGL на примере операционной системы Android

Что такое мобильные технологии и Android?

В последнее время большую популярность приобрели мобильные устройства, и сегодня мы имеем три основных ОС для работы с мобильными устройствами: Android, Apple iOS и Microsoft Windows Phone. При этом подавляющее большинство устройств работает под управлением Android.

В качестве основной среды разработки под Android применяют технологии Java и виртуальную машину, которая занимается запуском и выполнением всех приложений. Стандартные приложения, несильно зависящие от мощности аппаратных средств устройства, в данном случае процессоры и видеокарты, используют для работы виртуальную машину Java как среду выполнения.

Сейчас мощность мобильных устройств возросла настолько, что на них возможно уже играть в те же игры, в которые играли на стационарных компьютерах восемь лет назад. Тенденция развития такая, что мощность мобильных процессорных платформ будет только увеличиваться, причем нарастающими темпами. Из этого следует, что качество и сложность мобильных приложений тоже будет возрастать.

Исходя из выше описанной ситуации применение технологии Java оправдано, так как она позволяет унифицировать разработку программных продуктов. Но в ситуации с графическими приложениями, где необходима не только унификация, но и скорость работы, причем скорость выходит на первый план, иначе использование этой технологии будет неэффективным. Всевозможные оптимизации Java-технологий привели к значительному ускорению выполнения приложений, но этого не достаточно для 3D-графики с большим количеством используемых аппаратных ресурсов, где идет оптимизация наоснове аппаратной реализации. Мое мнение, что нужно использовать технологии, имеющие доступ к аппаратным ресурсам устройства без лишних прослоек.

В данной статье я рассмотрю два подхода к программированию 3D-графики на OpenGL.

    Разработка с использованием только средства Java-технологий для OpenGL и Andro > Программирование компьютерной графики на основе OpenGL с использованием Java-технологий для OpenGL и Android

Для начала рассмотрим основы программирования под Android.

Для создания приложений используется много IDE и визуальных средств. Основным я считаю ADT (Android Developer Tools) на основе Eclipse. Это среда разработки для Java, C++ и для множества других языков. Скачать и установить это среду разработки можно с сайта [1].

Есть другие средства разработки, такие как Android Studio, основанный на NetBeans. Они могут считаться альтернативой, но пока только ADT Eclipse поддерживает разработку с помощью C\C++. Дляэтого необходимо поставить NDK (Native Development Kit) и подключить его к ADT Eclipse. Так же на сайте расположено много полезных статей для программирования на Android.

После установки данной среды разработки необходимо еще доставить SDK (Software Development Kit) для работы с указанным приложением. Для создания первого приложения уже установленных изADT средств достаточно, но рекомендую сразу установить все необходимое, используя SDK Manager (см. рис.1).

Рисунок 1. SDK Manager

Далее хочу рассказать о системе обновления Eclipse из Интернета. Она располагается в меню Help → Install New Software… Там есть возможность загрузки и установки недостающих компонент.

Теперь о структуре самого приложения (см. рис. 2). В папке src находятся исходники, в папке bin – пакет для выполнения на Android. В папке Res находятся XML-файлы. Это файлы, которые содержат многие статически хранящиеся ресурсы, например, текст, изображения, цвета и т.д. В папке res/layout находятся шаблоны окон на Android, активностей или слоев. ADT Eclipse позволяет визуально редактировать форму активности с возможностью добавления кнопок, текстовых полей и т.д.

Рисунок 2. Структура исходных кодов приложения

Структура OpenGL приложения под Android – это обычное приложение, но в качестве инструмента рендеринга используются уже созданные классы и интерфейсы.

Теперь, как в приложениях для стационарных систем, нам необходимо получить контекст рендеринга, то есть где все будет рисоваться, и сопоставить его с контекстом отображения, то есть где мы увидим, что там нарисовалось. Для этого создадим активность средствами Eclipse.

public class OpenGLES20Activity extends Activity <

private GLSurfaceView mGLView;

public void onCreate(Bundle savedInstanceState) <

// Создаем экземпляр GLSurfaceView и устанавливаем его

// как контекст отображения для нашей активности или окна

mGLView = new MyGLSurfaceView(this);

protected void onPause() <

protected void onResume() <

Методы onPause() и onResume() соответственно отрабатывают, когда приложение для Android активно или свернуто или неактивно.

Далее расскажу о самой процедуре создания контекста рендеринга, то есть где все будет рисоваться. Будет показано, как прикрепить к нему класс рендеринга, где будем рисовать нашу графику средствами OpenGL.

public class MyGLSurfaceView extends GLSurfaceView <

private final MyGLRenderer mRenderer;

public MyGLSurfaceView(Context context) <

// Создаем OpenGL контекст, который будет

// отображаться в активности

// Создаем экземпляр класса рендеринга

mRenderer = new MyGLRenderer();

// Режим рендеринга, где отображение новой картинки

// происходит при ее изменении

// Метод onTouchEvent вызывается при прикосновении

// к экрану устройства

public boolean onTouchEvent(MotionEvent e)

Класс MyGLRenderer как раз и занимается созданием нашего изображения, отображаемого на экране устройства. В нем переопределяются три основных метода:

  • onSurfaceCreated – вызывается при создании и инициализации контекста OpenGL;
  • onSurfaceChanged – вызывается при изменении размеров экрана;
  • onDrawFrame – метод генерирует кадр графики для отображения.

public class MyGLRenderer implements GLSurfaceView.Renderer <

private static final String TAG = «MyGLRenderer»;

private final float[] mMVPMatrix = new float[16];

private final float[] mProjectionMatrix = new float[16];

private final float[] mViewMatrix = new float[16];

private final float[] mRotationMatrix = new float[16];

public void onSurfaceCreated(GL10 unused, EGLConfig config) <

// Инициализация данных при создании контекста OpenGL

GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

public void onDrawFrame(GL10 unused) <

// Генерируем матрицу камеры

Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

// Перемножаем видовую матрицу и матрицу камеры

// для получения необходимой матрицы отображения

Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

// Отображаем нашу сцену

// Создаем матрицу поворота

Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, 1.0f);


Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);

public void onSurfaceChanged(GL10 unused, int width, int height) <

GLES20.glViewport(0, 0, width, height);

float ratio = (float) width / height;

// Меняем видовую матрицу в соответствии с новыми

Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

// Полезная функция отображения и проверки ошибок

public static void checkGlError(String glOperation) <

while ((error = GLES20.glGetError()) != ↵

Log.e(TAG, glOperation + «: glError » + error);

throw new RuntimeException(glOperation + «: glError » + error);

Теперь о некоторых особенностях создания и работы со сценой. В Android Java – некоторая оптимизация работы с матрицами. Поскольку метод отображения не является конечным автоматом, поэтому вся работа формируется с матрицей. Координаты вершины умножаются на необходимую матрицу, и мы видим изменение при отображении на экране. Соответственно для каждого объекта отображения создается класс, и ему передается сформированная матрица для конкретного объекта, например, шарик, кубик, человек – сама большая сцена.

В общем схематическом виде можно представить создание программы для Android c использованием OpenGL (см. рис. 3).

Рисунок 3. Схема формирования отображения кадра

Как видите, достаточно проста и понятна работа с OpenGL-графикой с помощью Java применительно к Android. Но, как всегда бывает, за удобства нужно платить производительностью. Так как все этиклассы – это код, созданный на Java и обрабатывающийся виртуальной машиной Java, некоторые задержки и дополнительные вычисления будут присутствовать.

Программирование компьютерной графики на основе OpenGL с использованием NDK С\С++ для Android

Теперь рассмотрим, как реализовать эти задачи с помощью NDK и С\С++.

Начнем с того, что Android по своей структуре – это один из клонов операционной системы Linux. Соответственно ему присущи все особенности работы и программирования под подобные операционные системы. Как и в Linux, под Android можно использовать SDL. Пока же ограничимся только приложением, использующим напрямую NDK и ресурсы Android. Итак, для начала надо подготовить среду ADT Eclipse для работы с NDK. Для этого надо обновить и поставить недостающие компоненты. Выполнить это можно, открыв меню Help → Install New Software… и в окне в редакторе текста Work with указать https://dl.google.com/android/eclipse (см. рис. 4).

Рисунок 4. Установка компонент NDK для Eclipse

В дальнейшем открыть меню Window → Preferences. В полученном окне открыть в дереве Android\NDK и указать путь папке, где распакован NDK, например, C:\Android\android-ndk-r9d.

Для подключения к проекту возможностей NDK надо выбрать Android Tools → Add Native Support… нажав правой кнопкой мыши на необходимый проект. Там будет предоставлен выбор имени статической библиотеки на C\С++ в формате для Linux «lib .so». Будет создана папка jni с необходимыми файлами С++ и Android.mk, скриптом для компиляции библиотеки.

Теперь расскажу о структуре вызова процедур из библиотеки C++. Так как среда разработки и само приложение Android реализованы с помощью Java-технологий, то придется использовать окружение Java для работы. Для начала надо экспортировать процедуры или функции из C++ библиотеки в класс Java.

В коде С++ необходимые процедуры и функции экспортируются, как указано ниже.

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height);

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj);

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height)

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj)

Здесь длинное имя экспортируемой функции Java_com_android_gl2jni_GL2JNILib_ должно соответствовать src.com.android.gl2jni.GL2JNILib.java, то есть знак «_» в Java меняется на «.».

В Java импорт выглядит вот так:

public class GL2JNILib

public static native void init(int width, int height);

public static native void step();

Здесь с помощью вызова системного метода System.loadLibrary(«gl2jni») указывается, откуда производить импорт. С помощью директивы public static native указывается имя вызываемой функции изсозданного нами класса C++ (см. рис. 5).

Рисунок 5. Экспорт функций C++ в Java

Для линковки библиотеки необходимо подключить необходимые библиотеки для работы с OpenGL -lGLESv2 и вывода отладочных сообщений в лог Android «-llog» в файле Android.mk.

LOCAL_PATH:= $(call my-dir)

LOCAL_LDLIBS := -llog -lGLESv2

За выполнение действий за отрисовку буферов отвечает класс GLSurfaceView.

private void init(boolean translucent, int depth, int stencil)

В нем инициализируются два следующих класса-потомка GLSurfaceView.EGLContextFactory и GLSurfaceView.Renderer.

В классе GLSurfaceView.Renderer переопределяются методы onDrawFrame(GL10 gl) и onSurfaceChanged(GL10 gl, int width, int height)

public void onDrawFrame(GL10 gl) <

public void onSurfaceChanged(GL10 gl, int width, int height) <

public void onSurfaceCreated(GL10 gl, EGLConfig config) <

Вся остальная работа будет производиться средствами Android в созданном экземпляре класса Activity. Метод setContentView(mView) сопоставляет активность и наш класс для работы с OpenGL – GLSurfaceView.

protected void onCreate(Bundle icicle) <

mView = new GL2JNIView(getApplication());

Другие действия в Java части нашего приложения производить нет смысла, так как основную логику работы будут содержать функции и процедуры в С++ библиотеке.

Так как Android является по сути своей Linux, то есть большая вероятность, что, если код работает под Linux, он будет работать и под Android. Единственное различие – в аппаратных ресурсах. Все-таки мобильные приложения пока еще не могут поддерживать и выполнять все аппаратные функции стационарных компьютеров. Поэтому приложение надо тестировать на Android.

Там будут использоваться стандартные процедуры из OpenGL-библиотек. Так как библиотеки изменены и урезаны, то стандартных glBegin(), glVertex3f() и т.п. в этих библиотеках нет. Есть стандартные вызовы методов glDrawArray() и других.

Используя данный функционал, можно без существенных затрат перенести приложения со стационарных рабочих станций на мобильные устройства. OpenGL придерживается своего стандарта. Если егопридерживаться при программировании, сложностей при портировании будет гораздо меньше.

Сравнение двух подходов

Как и везде при формировании программы с использование OpenGL с помощью Java и нативных средств операционной системы NDK, есть достоинства и недостатки.

Начну с достоинств подхода использования только Java для формирования графики:

  • Возможность использования полученного кода на множестве устройств.
  • Удобство и заранее решенные вопросы с работой с устройством, то есть не нужно перехватывать события изменения на устройстве и нажатия.
  • Удобство отладки.

Данный подход эффективен при создании приложений с не очень сложной графикой, например, отображение карт или простых каких-либо графических эффектов, связанных с текстурами.

Если есть достоинства, то должны быть и недостатки . Самый главный и, по моему мнению, критический недостаток – это объектно-ориентированный подход к формированию приложения. Достаточно большие затраты ресурсов и производительности будут тратиться на внутреннюю работу с экземплярами классов.

Все методы в классах отображения OpenGL являются статическими. Они, конечно же, используют нативные средства расчетов. То есть время отображения какого-либо объекта ничем не будет отличаться от средств С++. Но вот другие действия, которые связаны с формированием изменения кадра или какой-либо динамики, будут заметно замедлять работу.

Теперь по поводу достоинств и недостатков нативного подхода с использованием NDK.

Достоинства:

  • Скорость формирования и обработки кадра.
  • Доступ к ресурсам устройства на более низком уровне.
  • Возможность портирования приложений со стационарных компьютеров.

Скорость отображения кадра при использовании NDK визуально выше, чем с помощью Java. Есть возможность работы с памятью и с внутренними, более обширными ресурсами устройства.

Недостатками можно считать следствия достоинств:


    Проблемный перенос программы на другие мобильные устройства. Не всегда NDK-приложение на текущем устройстве будет работать на других. Каждый бренд изменяет Andro >Разработчики Android рекомендуют для совместимости использовать только Java-ресурсы. NDK был создан для совместимости Android c другими приложениями, на других платформах.

Если учесть, что современные графические фреймворки уже создаются с учетом использования их на мобильных устройствах, NDK будет только развиваться.

Создание среды OpenGL ES

Для того, чтобы рисовать графику с помощью OpenGL в Android приложениях, необходимо создать для этого контейнер просмотра. Один из прямолинейных способов, это использовать объекты GLSurfaceView и GLSurfaceView.Renderer. GLSurfaceView это контейнер для просмотра графики, нарисованной с помощью OpenGL, а GLSurfaceView.Renderer управляет тем, что будет нарисовано в этом контейнере. Подробная информация о данных классах содержится в разделе OpenGL ES.

Использование GLSurfaceView это всего лишь один из способов включить OpenGL ES в ваше приложение. Для полноэкранного просмотра графики это разумный выбор. Разработчикам, которые хотят включить графику OpenGL ES в небольшую часть разметки, следует обратить внимание на класс TextureView. В действительности, разработчики-самоучки, можно выводить OpenGL графику с помощью компонента SurfaceView, однако это требует довольно много дополнительного кода.

В уроке поясняется как создать минимальную реализацию GLSurfaceView и GLSurfaceView.Renderer в простом явлении.

Объявляем использование OpenGL ES в манифесте

Для использования OpenGL ES 2.0 в приложении, вы должны добавить следующие строки в файл манифеста:

Если в вашем приложении используется компрессия текстур, вы должны также объявить форматы компрессии, которые оно поддерживает. Тогда приложение сможет быть установлено только на совместимые устройства:

Подробную информацию о форматах компрессии текстур смотрите в разделе OpenGL.

Создаем явление для графики OpenGL ES

Приложения, использующие OpenGL ES содержат явления, подобно любым другим приложениям с пользовательским интерфейсом. Главное отличие от других приложений в том, какие компоненты будут находиться в разметке явления. В то время как в обычных приложениях используются кнопки, поля ввода и списки, в приложениях с OpenGL ES вы можете добавить также компонент GLSurfaceView.

В следующем примере показана минимальная реализация явления, которое использует GLSurfaceView :

How to Use OpenGL ES in Android Apps

Almost every Android phone available in the market today has a graphics processing unit, or GPU for short. As its name suggests, this is a hardware unit dedicated to handling calculations that are usually related to 3D graphics. As an app developer, you can make use of the GPU to create complex graphics and animations that run at very high frame rates.

There are currently two different APIs you can use to interact with an Android device’s GPU: Vulkan and OpenGL ES. While Vulkan is available only on devices running Android 7.0 or higher, OpenGL ES is supported by all Android versions.

In this tutorial, I’ll help you get started with using OpenGL ES 2.0 in Android apps.

Prerequisites

To be able to follow this tutorial, you’ll need:

OpenGL, which is short for Open Graphics Library, is a platform-independent API that allows you to create hardware-accelerated 3D graphics. OpenGL ES, short for OpenGL for Embedded Systems, is a subset of the API.

OpenGL ES is a very low-level API. In other words, it doesn’t offer any methods that allow you to quickly create or manipulate 3D objects. Instead, while working with it, you are expected to manually manage tasks such as creating the individual vertices and faces of 3D objects, calculating various 3D transformations, and creating different types of shaders.

It is also worth mentioning that the Android SDK and NDK together allow you to write OpenGL ES-related code in both Java and C.

2. Project Setup

Because the OpenGL ES APIs are a part of the Andro >compile dependency in your app module’s build.gradle file:

Additionally, in order to stop Google Play users who do not have devices that support the OpenGL ES version you need from installing your app, add the following tag to your project’s manifest file:

3. Create a Canvas

The Andro >GLSurfaceView and TextureView . Most developers prefer using GLSurfaceView , and choose TextureView only when they intend to overlay their 3D graphics on another View w >GLSurfaceView will suffice.

Adding a GLSurfaceView widget to your layout file is no different from adding any other widget.

Note that we’ve made the width of our widget equal to its height. Doing so is important because the OpenGL ES coordinate system is a square. If you must use a rectangular canvas, do remember to include its aspect ratio while calculating your projection matrix. You’ll learn what a projection matrix is in a later step.

Initializing a GLSurfaceView w >Activity >findViewById() method and passing its id to it.

Additionally, we must call the setEGLContextClientVersion() method to explicitly specify the version of OpenGL ES we’ll be using to draw inside the widget.

4. Create a 3D Object

Although it is possible to create 3D objects in Java by hand-coding the X, Y, and Z coordinates of all their vertices, doing so is very cumbersome. Using 3D modeling tools instead is far easier. Blender is one such tool. It is open source, powerful, and very easy to learn.

Fire up Blender and press X to delete the default cube. Next, press Shift-A and select Mesh > Torus. We now have a fairly complex 3D object consisting of 576 vertices.

To be able to use the torus in our Android app, we must export it as a Wavefront OBJ file. Therefore, go to File > Export > Wavefront (.obj). In the next screen, give a name to the OBJ file, make sure that the Triangulate Faces and Keep Vertex Order options are selected, and press the Export OBJ button.

You can now close Blender and move the OBJ file to your Android Studio project’s assets folder.

5. Parse the OBJ File

If you haven’t noticed already, the OBJ file we created in the previous step is a text file, which can be opened using any text editor.

In the file, each line that starts with a «v» represents a single vertex. Similarly, each line starting with an «f» represents a single triangular face. While each vertex line contains the X, Y, and Z coordinates of a vertex, each face line contains the indices of three vertices, which together form a face. That’s all you need to know to parse an OBJ file.

Before you begin, create a new Java >List objects, one for the vertices and one for the faces, as its member variables.

The easiest way to read all the indiv >Scanner >nextLine() method. While looping through the lines and populating the two lists, you can use the String >startsWith() method to check if the current line starts with a «v» or an «f».

6. Create Buffer Objects

You can’t pass the lists of vertices and faces to the methods available in the OpenGL ES API directly. You must first convert them into buffer objects. To store the vertex coordinate data, we’ll need a FloatBuffer object. For the face data, which simply consists of vertex indices, a ShortBuffer object will suffice.

Accordingly, add the following member variables to the Torus class:

To initialize the buffers, we must first create a ByteBuffer object using the allocateDirect() method. For the vertices buffer, allocate four bytes for each coordinate, what with the coordinates being floating-point numbers. Once the ByteBuffer object has been created, you can convert it into a FloatBuffer by calling its asFloatBuffer() method.

Similarly, create another ByteBuffer object for the faces buffer. This time, allocate two bytes for each vertex index because the indices are unsigned short literals. Also, make sure that you use the asShortBuffer() method to convert the ByteBuffer object to a ShortBuffer .

Populating the vertices buffer involves looping through the contents of verticesList , extracting the X, Y, and Z coordinates from each item, and calling the put() method to put data ins >verticesList contains only strings, we must use the parseFloat() to convert the coordinates from strings to float values.

Note that in the above code we’ve used the position() method to reset the position of the buffer.

Populating the faces buffer is slightly different. You must use the parseShort() method to convert each vertex index to a short value. Additionally, because the indices start from one instead of zero, you must remember to subtract one from them before putting them inside the buffer.

7. Create Shaders

To be able to render our 3D object, we must create a vertex shader and a fragment shader for it. For now, you can think of a shader as a very simple program written in a C-like language called OpenGL Shading Language, or GLSL for short.

A vertex shader, as you might have guessed, is responsible for handling a 3D object’s vertices. A fragment shader, also called a pixel shader, is responsible for coloring the 3D object’s pixels.

Step 1: Create a Vertex Shader

Create a new file called vertex_shader.txt inside your project’s res/raw folder.

A vertex shader must have an attribute global variable ins >uniform global variable to receive a view-projection matrix from the Java code.

Ins >main() function of the vertex shader, you must set the value of gl_position , a GLSL built-in variable that dec >uniform and attribute global variables.

Accordingly, add the following code to the file:

Step 2: Create a Fragment Shader

Create a new file called fragment_shader.txt inside your project’s res/raw folder.

To keep this tutorial short, we’ll now be creating a very minimalist fragment shader that simply assigns the color orange to all pixels. To assign a color to a pixel, ins >main() function of a fragment shader, you can use the gl_FragColor built-in variable.

In the above code, the first line specifying the precision of floating-point numbers is important because a fragment shader doesn’t have any default precision for them.

Step 3: Compile the Shaders

Back in the Torus >IOUtils >toString() method for doing just that. The following code shows you how to use it:

The shaders’ code must be added to OpenGL ES shader objects. To create a new shader object, use the glCreateShader() method of the GLES20 >GL_VERTEX_SHADER or GL_FRAGMENT_SHADER to it. The method returns an integer that serves as a reference to the shader object. A newly-created shader object doesn’t contain any code. To add the shader code to the shader object, you must use the glShaderSource() method.


The following code creates shader objects for both the vertex shader and the fragment shader:

We can now pass the shader objects to the glCompileShader() method to compile the code they contain.

8. Create a Program

While rendering a 3D object, you don’t use the shaders directly. Instead, you attach them to a program and use the program. Therefore, add a member variable to the Torus class to store a reference to an OpenGL ES program.

To create a new program, use the glCreateProgram() method. To attach the vertex and fragment shader objects to it, use the glAttachShader() method.

At this point, you can link the program and start using it. To do so, use the glLinkProgram() and glUseProgram() methods.

9. Draw the 3D Object

With the shaders and buffers ready, we have everything we need to draw our torus. Add a new method to the Torus class called draw:

In an earlier step, ins >position variable to receive vertex position data from Java code. It is now time to send the vertex position data to it. To do so, we must first get a handle to the position variable in our Java code using the glGetAttribLocation() method. Additionally, the handle must be enabled using the glEnableVertexAttribArray() method.

Accordingly, add the following code ins >draw() method:

To point the position handle to our vertices buffer, we must use the glVertexAttribPointer() method. In addition to the vertices buffer itself, the method expects the number of coordinates per vertex, the type of the coordinates, and the byte offset for each vertex. Because we have three coordinates per vertex and each coordinate is a float , the byte offset must be 3 * 4 .

Our vertex shader also expects a view-projection matrix. Although such a matrix is not always necessary, using one allows you to have better control over how your 3D object is rendered.

A view-projection matrix is simply the product of the view and projection matrices. A view matrix allows you to specify the locations of your camera and the point it is looking at. A projection matrix, on the other hand, allows you to not only map the square coordinate system of OpenGL ES to the rectangular screen of an Android device, but also specify the near and far planes of the viewing frustum.

To create the matrices, you can simply create three float arrays of size 16 :

To initialize the projection matrix, you can use the frustumM() method of the Matrix >-1 and 1 for the left and right, and the bottom and top clip planes. For the near and far clip planes, feel free to experiment with different values.

To initialize the view matrix, use the setLookAtM() method. It expects the positions of the camera and the point it is looking at. You are again free to experiment with different values.

Finally, to calculate the product matrix, use the multiplyMM() method.

To pass the product matrix to the vertex shader, you must get a handle to its matrix variable using the glGetUniformLocation() method. Once you have the handle, you can point it to the product matrix using the glUniformMatrix() method.

You must have noticed that we still haven’t used the faces buffer. That means that we still haven’t told OpenGL ES how to connect the vertices to form triangles, which will serve as the faces of our 3D object.

The glDrawElements() method allows you to use the faces buffer to create triangles. As its arguments, it expects the total number of vertex indices, the type of each index, and the faces buffer.

Lastly, do remember to disable the attribute handler you enabled earlier to pass the vertex data to the vertex shader.

10. Create a Renderer

Our GLSurfaceView w >GLSurfaceView.Renderer object to be able to render 3D graphics. You can use the setRenderer() to associate a renderer with it.

Ins >onSurfaceCreated() method of the renderer, you must specify how often the 3D graphic must be rendered. For now, let’s render only when the 3D graphic changes. To do so, pass the RENDERMODE_WHEN_DIRTY constant to the setRenderMode() method. Additionally, initialize a new instance of the Torus object.

Ins >onSurfaceChanged() method of the renderer, you can define the w >glViewport() method.

Ins >onDrawFrame() method of the renderer, add a call to the draw() method of the Torus class to actually draw the torus.

At this point, you can run your app to see the orange torus.

Conclusion

You now know how to use OpenGL ES in Android apps. In this tutorial, you also learned how to parse a Wavefront OBJ file and extract vertex and face data from it. I suggest you generate a few more 3D objects using Blender and try rendering them in the app.

Although we focused only on OpenGL ES 2.0, do understand that OpenGL ES 3.x is backwards-compatible with OpenGL ES 2.0. That means that if you prefer using OpenGL ES 3.x in your app, you can simply replace the GLES20 >GLES30 or GLES31 classes.

To learn more about OpenGL ES, you can refer to its reference pages. And to learn more about Android app development, be sure to check out some of our other tutorials here at Envato Tuts+!

How to Get Started With Android’s Native Development Kit

Android — Android + OpenGL

I have started a new updated serie of tutorials on OpenGL ES 2.0 for android. Check them out at: OpenGL ES 2.0

I’m going to write a couple of tutorials on using OpenGL ES on Android phones. The theory of OpenGL ES is the same on different devices so it should be quite easy to convert them to another platform.

I can’t always remember where I found particular info so I might not always be able to give you the right reference. If you feel that I have borrowed stuff from you but have forgotten to add you as a reference, please e-mail me.

In the code examples I will have two different links for each function. The actual function will be linked to the android documentation and after that I will also link the OpenGL documentations. Like this:

In this tutorial I will show you how to set up your OpenGL ES view that’s always a good place to start.

Setting up an OpenGL ES View

Setting up a OpenGL view has never been hard and on Android it is still easy. There really are only two things you need to get started.

GLSurfaceView

GLSurfaceView is a API class in Android 1.5 that helps you write OpenGL ES applications.

  • Providing the glue code to connect OpenGL ES to the View system.
  • Providing the glue code to make OpenGL ES work with the Activity life-cycle.
  • Making it easy to choose an appropriate frame buffer pixel format.
  • Creating and managing a separate rendering thread to enable smooth animation.
  • Providing easy-to-use debugging tools for tracing OpenGL ES API calls and checking for errors.

If you want to get going fast with your OpenGL ES application this is where you should start.

The only function you need to call on is:

GLSurfaceView.Renderer

GLSurfaceView.Renderer is a generic render interface. In your implementation of this renderer you should put all your calls to render a frame.
There are three functions to implement:

onSurfaceCreated

Here it’s a good thing to setup things that you don’t change so often in the rendering cycle. Stuff like what color to clear the screen with, enabling z-buffer and so on.

onDrawFrame

Here is where the actual drawing take place.

onSurfaceChanged

If your device supports flipping between landscape and portrait you will get a call to this function when it happens. What you do here is setting upp the new ratio.
Read more at: GLSurfaceView.Renderer

Putting it together

First we create our activity, we keep it clean and simple.

Our renderer takes little bit more work to setup, look at it and I will explain the code a bit more.

Fullscreen

Just add this lines in the OpenGLDemo class and you will get fullscreen.

This is pretty much all you need to get your view up and running. If you compile and run it you will see a nice black screen.

References

You can download the source for this tutorial here: Tutorial_Part_I.zip
You can also checkout the code from: code.google.com

This Post Has 90 Comments

Samuh Varta

thanks for starting this tutorial series on OpenGL for Android!


odd256

Thanks, this is extremely helpful.

I believe there’s a typo on line 220:
s/OpenGLDemo/TutorialPartI

chhsf

Hi Per-Erik
Thank you for your tutorial.But My application is not work for a error.It is GLLogger, it show couldn’t load library(Cannot find library).
I don’t know what’s wrong.

Gary Wang

Dear Sir, really good articles to Android OpenGL ES!
Thanks for ur sharing!

Sr > 24 Feb 2010 Reply

Thank you for the tutorial, alas some inspiration to start of OpenGL ES :)

any way to use a GLSurfaceView as a background? the idea is to have a normal surfaceview on top of the GLSurfaceView, render the background with opengl, then throw some sprites onto the other view. so as the opengl is just handling the background. I currently have this working fine, except i cannot get the GLSurfaceView to stay in the background.. no amount of view manipulation ie. what order they are in etc, seems to help.

murali

Your article is very helpful. Thanks

My doubt is opengl return a .exe file as output in android, similarly in what format the o/p file will be in Android ? May be my question is very silly.

Thanks in advance.

shubham

Thanx Bro..it’s realy good try.

shubham

hi friend’s ,I want to draw an 2d image ..how can i do here.
I got pixel position of image ..

Thank in Advance..

Chinson

It’s very helpful. Thanks!

Daniel Rodríguez

Awesome tutorial. Thank you very much.

Tom Anderson

By the way thought it could be helpful for anyone since black is the same as the default color. Try this instead:

// Set the background color to RED( rgba ).
gl.glClearColor(255.0f, 0.0f, 0.0f, 0.5f);

Amandeep

Too Good Blog.
Very Clear and Informative.
Thanks for availing this information

czhedu

Great tutorial…….
Clear and easy to understand……….

ashik

really nice tutorial and Im gonna add ur blog in my blogroll!!

srikanth

thanks
its really nice to start opengl in eclipse
if possible please provide the code for drawing arc in opengl using java

Really appreciate your tutorials, thanks!

gabriel

excellent to get started nice and easy :)

just a note, you also need to include two classes for enable full screen:
import android.view.Window;
import android.view.WindowManager;

great work on the writing, links and selecting the examples. jumping on part II now.

PS: this should be linked from the android manual, where they say it’s not the scope of the glsurfaceview to explain how to do openGL helloworld! think that if you used more androidesque syntax they would consider it :) …just sugar, like @Override, etc

gabriel

*to enable full screen

subho

i am facing some error:
[2010-11-20 15:31:55 – Emulator] invalid command-line parameter: partition-size.
[2010-11-20 15:31:55 – Emulator] Hint: use ‘@foo’ to launch a virtual device named ‘foo’.
[2010-11-20 15:31:55 – Emulator] please use -help for more information

c programming

Good Work. Keep it up.

Sureshkumar

dear sir, I do have a question regarding this codes here
// Sets the current view port to the new size.
gl.glViewport(0, 0, width, height);// OpenGL docs.
// Select the projection matrix
gl.glMatrixMode(GL10.GL_PROJECTION);// OpenGL docs.
// Reset the projection matrix
gl.glLoadIdentity();// OpenGL docs.
// Calculate the aspect ratio of the window
GLU.gluPerspective(gl, 45.0f,
(float) width / (float) height,
0.1f, 100.0f);
// Select the modelview matrix
gl.glMatrixMode(GL10.GL_MODELVIEW);// OpenGL docs.
// Reset the modelview matrix
gl.glLoadIdentity();// OpenGL docs.

why do we have to change the glMatrixMode to GL10.GL_MODELVIEW? and reload the glLoadIdentity?

I hope I would here from your guidance since I’m new to OPENGL and android…

Hi,
I have followed this tutorial and hve also got a square to appear on screen. I am able to move the square by using up down left and right keys. My question is how can I get a cameraq to “follow” this square when it moves? ie I want the camera to be focused on the square.

Per-Erik Bergman

Nate: You can use en GLSurfaceView as any view so with a frame layout I guess you can add it as a background.

mural: On android we get an .apk file.

shubham: Rendering 2D with OpenGL is a big tutorial itself, it is in the pipeline.

Pach: GL_PROJECTION and GL_MODELVIEW is two different matrix and since we need to “reset” them both we need to do glLoadIdentity on both.

John: The easiest way is to create a camera object that you can steer. When rendering do the camera translation first before you render the square.

Robin Degen

As an openGL programmer on the PC, this was all i needed to get me started on android. However, i’d prefer using C++ over java, so that will be a next thing to figure out on android. But atleast i got started now. Thanks for the info

sameh ammar

Thanx you are very nice :)

Nayanesh Gupte

How do I bind different textures to to different faces of cube?

I’m trying something like this

gl.glActiveTexture(GL10.GL_TEXTURE0);
gl.glClientActiveTexture(GL10.GL_TEXTURE0);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
….
gl.glActiveTexture(GL10.GL_TEXTURE5);
gl.glClientActiveTexture(GL10.GL_TEXTURE5);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[5]);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);


gl.glTexEnvx(GL10.GL_TEXTURE_ENV , GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);

gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);

lattimore

Excellent!
Great tutorial!

Adrian

Hi,
Is it possible to modify the draw method of an object in such a way that it only needs to be drawn once and not every time in the onDraw method? I am having performance issues while drawing lots of pixels for a background image and wondered if the draw method could be changed?

Edward

Sorry..i’m new in OpenGL ES..i just wondering, why do we need to include GL10?

And, I found that its quite difficult to look for OpenGL ES in Android in the internet but tons in iPhone…

haryo

thanxs Per-Erik Bergman…
its work..

but i still really confuse to make graphics for AR using this ..any tutorial for make it ? please ??

minimal

Thanks this is really great.
But I would also like to see a similar example set for NDK.
I was at google I/0 and some of the stuff that they showed on NDK was awesome.

harinath

This was the excellent tutorial.i am having few doubts regarding the fallowing.
How do I bind different textures to to different faces of cube?
coud u please clarify it.

Guillermo

Hey, really really really great tutorial!! it`s very simple, i`m starting with opengl and android and its helps me a lot to dont missup with other stuffs. The links on the documentation also helps a lot on the learning process. I`ll continue with the other tutorials you`ve already posted. Thanks a lot!

Helen

Another much easier way to set your application to fullscreen ist by adding 1 line to the Andro >

OpenGL

In this document

Key classes

See also

Android includes support for high performance 2D and 3D graphics with the Open Graphics Library (OpenGL), specifically, the OpenGL ES API. OpenGL is a cross-platform graphics API that specifies a standard software interface for 3D graphics processing hardware. OpenGL ES is a flavor of the OpenGL specification intended for embedded devices. The OpenGL ES 1.0 and 1.1 API specifications have been supported since Android 1.0. Beginning with Android 2.2 (API Level 8), the framework supports the OpenGL ES 2.0 API specification.

Note: The specific API provided by the Android framework is similar to the J2ME JSR239 OpenGL ES API, but is not identical. If you are familiar with J2ME JSR239 specification, be alert for variations.

The Basics

Android supports OpenGL both through its framework API and the Native Development Kit (NDK). This topic focuses on the Android framework interfaces. For more information about the NDK, see the Android NDK.

There are two foundational classes in the Android framework that let you create and manipulate graphics with the OpenGL ES API: GLSurfaceView and GLSurfaceView.Renderer . If your goal is to use OpenGL in your Android application, understanding how to implement these classes in an activity should be your first objective.

GLSurfaceView This class is a View where you can draw and manipulate objects using OpenGL API calls and is similar in function to a SurfaceView . You can use this class by creating an instance of GLSurfaceView and adding your Renderer to it. However, if you want to capture touch screen events, you should extend the GLSurfaceView class to implement the touch listeners, as shown in OpenGL training lesson, Responding to Touch Events. GLSurfaceView.Renderer This interface defines the methods required for drawing graphics in an OpenGL GLSurfaceView . You must provide an implementation of this interface as a separate class and attach it to your GLSurfaceView instance using GLSurfaceView.setRenderer() .

The GLSurfaceView.Renderer interface requires that you implement the following methods:

  • onSurfaceCreated() : The system calls this method once, when creating the GLSurfaceView . Use this method to perform actions that need to happen only once, such as setting OpenGL environment parameters or initializing OpenGL graphic objects.
  • onDrawFrame() : The system calls this method on each redraw of the GLSurfaceView . Use this method as the primary execution point for drawing (and re-drawing) graphic objects.
  • onSurfaceChanged() : The system calls this method when the GLSurfaceView geometry changes, including changes in size of the GLSurfaceView or orientation of the device screen. For example, the system calls this method when the device changes from portrait to landscape orientation. Use this method to respond to changes in the GLSurfaceView container.

OpenGL packages

Once you have established a container view for OpenGL using GLSurfaceView and GLSurfaceView.Renderer , you can begin calling OpenGL APIs using the following classes:

  • OpenGL ES 1.0/1.1 API Packages
    • android.opengl — This package provides a static interface to the OpenGL ES 1.0/1.1 classes and better performance than the javax.microedition.khronos package interfaces.
      • GLES10
      • GLES10Ext
      • GLES11
      • GLES10Ext
    • javax.microedition.khronos.opengles — This package provides the standard implementation of OpenGL ES 1.0/1.1.
      • GL10
      • GL10Ext
      • GL11
      • GL11Ext
      • GL11ExtensionPack
  • OpenGL ES 2.0 API Class
    • android.opengl.GLES20 — This package provides the interface to OpenGL ES 2.0 and is available starting with Android 2.2 (API Level 8).

If you’d like to start building an app with OpenGL right away, follow the Displaying Graphics with OpenGL ES class.

Declaring OpenGL Requirements

If your application uses OpenGL features that are not available on all devices, you must include these requirements in your AndroidManifest.xml file. Here are the most common OpenGL manifest declarations:

    OpenGL ES version requirements — If your application only supports OpenGL ES 2.0, you must declare that requirement by adding the following settings to your manifest as shown below.

Adding this declaration causes Google Play to restrict your application from being installed on devices that do not support OpenGL ES 2.0.

Texture compression requirements — If your application uses texture compression formats, you must declare the formats your application supports in your manifest file using . For more information about available texture compression formats, see Texture compression support.

Declaring texture compression requirements in your manifest hides your application from users with devices that do not support at least one of your declared compression types. For more information on how Google Play filtering works for texture compressions, see the Google Play and texture compression filtering section of the documentation.

Mapping Coordinates for Drawn Objects

One of the basic problems in displaying graphics on Android devices is that their screens can vary in size and shape. OpenGL assumes a square, uniform coordinate system and, by default, happily draws those coordinates onto your typically non-square screen as if it is perfectly square.

Figure 1. Default OpenGL coordinate system (left) mapped to a typical Android device screen (right).

The illustration above shows the uniform coordinate system assumed for an OpenGL frame on the left, and how these coordinates actually map to a typical device screen in landscape orientation on the right. To solve this problem, you can apply OpenGL projection modes and camera views to transform coordinates so your graphic objects have the correct proportions on any display.

In order to apply projection and camera views, you create a projection matrix and a camera view matrix and apply them to the OpenGL rendering pipeline. The projection matrix recalculates the coordinates of your graphics so that they map correctly to Android device screens. The camera view matrix creates a transformation that renders objects from a specific eye position.

Projection and camera view in OpenGL ES 1.0

In the ES 1.0 API, you apply projection and camera view by creating each matrix and then adding them to the OpenGL environment.

  1. Projection matrix — Create a projection matrix using the geometry of the device screen in order to recalculate object coordinates so they are drawn with correct proportions. The following example code demonstrates how to modify the onSurfaceChanged() method of a GLSurfaceView.Renderer implementation to create a projection matrix based on the screen’s aspect ratio and apply it to the OpenGL rendering environment.
  2. Camera transformation matrix — Once you have adjusted the coordinate system using a projection matrix, you must also apply a camera view. The following example code shows how to modify the onDrawFrame() method of a GLSurfaceView.Renderer implementation to apply a model view and use the GLU.gluLookAt() utility to create a viewing tranformation which simulates a camera position.

Projection and camera view in OpenGL ES 2.0


In the ES 2.0 API, you apply projection and camera view by first adding a matrix member to the vertex shaders of your graphics objects. With this matrix member added, you can then generate and apply projection and camera viewing matrices to your objects.

    Add matrix to vertex shaders — Create a variable for the view projection matrix and include it as a multiplier of the shader’s position. In the following example vertex shader code, the included uMVPMatrix member allows you to apply projection and camera viewing matrices to the coordinates of objects that use this shader.

Note: The example above defines a single transformation matrix member in the vertex shader into which you apply a combined projection matrix and camera view matrix. Depending on your application requirements, you may want to define separate projection matrix and camera viewing matrix members in your vertex shaders so you can change them independently.

  • Access the shader matrix — After creating a hook in your vertex shaders to apply projection and camera view, you can then access that variable to apply projection and camera viewing matrices. The following code shows how to modify the onSurfaceCreated() method of a GLSurfaceView.Renderer implementation to access the matrix variable defined in the vertex shader above.
  • Create projection and camera viewing matrices — Generate the projection and viewing matrices to be applied the graphic objects. The following example code shows how to modify the onSurfaceCreated() and onSurfaceChanged() methods of a GLSurfaceView.Renderer implementation to create camera view matrix and a projection matrix based on the screen aspect ratio of the device.
  • Apply projection and camera viewing matrices — To apply the projection and camera view transformations, multiply the matrices together and then set them into the vertex shader. The following example code shows how modify the onDrawFrame() method of a GLSurfaceView.Renderer implementation to combine the projection matrix and camera view created in the code above and then apply it to the graphic objects to be rendered by OpenGL.
  • For a complete example of how to apply projection and camera view with OpenGL ES 2.0, see the Displaying Graphics with OpenGL ES class.

    Shape Faces and Winding

    In OpenGL, the face of a shape is a surface defined by three or more points in three-dimensional space. A set of three or more three-dimensional points (called vertices in OpenGL) have a front face and a back face. How do you know which face is front and which is the back? Good question. The answer has to do with winding, or, the direction in which you define the points of a shape.

    Figure 1. Illustration of a coordinate list which translates into a counterclockwise drawing order.

    In this example, the points of the triangle are defined in an order such that they are drawn in a counterclockwise direction. The order in which these coordinates are drawn defines the winding direction for the shape. By default, in OpenGL, the face which is drawn counterclockwise is the front face. The triangle shown in Figure 1 is defined so that you are looking at the front face of the shape (as interpreted by OpenGL) and the other side is the back face.

    Why is it important to know which face of a shape is the front face? The answer has to do with a commonly used feature of OpenGL, called face culling. Face culling is an option for the OpenGL environment which allows the rendering pipeline to ignore (not calculate or draw) the back face of a shape, saving time, memory and processing cycles:

    If you try to use the face culling feature without knowing which sides of your shapes are the front and back, your OpenGL graphics are going to look a bit thin, or possibly not show up at all. So, always define the coordinates of your OpenGL shapes in a counterclockwise drawing order.

    Note: It is possible to set an OpenGL environment to treat the clockwise face as the front face, but doing so requires more code and is likely to confuse experienced OpenGL developers when you ask them for help. So don’t do that.

    OpenGL Versions and Device Compatibility

    The OpenGL ES 1.0 and 1.1 API specifications have been supported since Android 1.0. Beginning with Android 2.2 (API Level 8), the framework supports the OpenGL ES 2.0 API specification. OpenGL ES 2.0 is supported by most Android devices and is recommended for new applications being developed with OpenGL. For information about the relative number of Android-powered devices that support a given version of OpenGL ES, see the OpenGL ES Versions Dashboard.

    Texture compression support

    Texture compression can significantly increase the performance of your OpenGL application by reducing memory requirements and making more efficient use of memory bandwidth. The Android framework provides support for the ETC1 compression format as a standard feature, including a ETC1Util utility class and the etc1tool compression tool (located in the Android SDK at /tools/ ). For an example of an Android application that uses texture compression, see the CompressedTextureActivity code sample.

    The ETC format is supported by most Android devices, but it not guarranteed to be available. To check if the ETC1 format is supported on a device, call the ETC1Util.isETC1Supported() method.

    Note: The ETC1 texture compression format does not support textures with an alpha channel. If your application requires textures with an alpha channel, you should investigate other texture compression formats available on your target devices.

    Beyond the ETC1 format, Android devices have varied support for texture compression based on their GPU chipsets and OpenGL implementations. You should investigate texture compression support on the the devices you are are targeting to determine what compression types your application should support. In order to determine what texture formats are supported on a given device, you must query the device and review the OpenGL extension names, which identify what texture compression formats (and other OpenGL features) are supported by the device. Some commonly supported texture compression formats are as follows:

    • ATITC (ATC) — ATI texture compression (ATITC or ATC) is available on a wide variety of devices and supports fixed rate compression for RGB textures with and without an alpha channel. This format may be represented by several OpenGL extension names, for example:
      • GL_AMD_compressed_ATC_texture
      • GL_ATI_texture_compression_atitc
    • PVRTC — PowerVR texture compression (PVRTC) is available on a wide variety of devices and supports 2-bit and 4-bit per pixel textures with or without an alpha channel. This format is represented by the following OpenGL extension name:
      • GL_IMG_texture_compression_pvrtc
    • S3TC (DXTn/DXTC) — S3 texture compression (S3TC) has several format variations (DXT1 to DXT5) and is less widely available. The format supports RGB textures with 4-bit alpha or 8-bit alpha channels. This format may be represented by several OpenGL extension names, for example:
      • GL_OES_texture_compression_S3TC
      • GL_EXT_texture_compression_s3tc
      • GL_EXT_texture_compression_dxt1
      • GL_EXT_texture_compression_dxt3
      • GL_EXT_texture_compression_dxt5
    • 3DC — 3DC texture compression (3DC) is a less widely available format that supports RGB textures with an an alpha channel. This format is represented by the following OpenGL extension name:
      • GL_AMD_compressed_3DC_texture

    Warning: These texture compression formats are not supported on all devices. Support for these formats can vary by manufacturer and device. For information on how to determine what texture compression formats are on a particular device, see the next section.

    Note: Once you decide which texture compression formats your application will support, make sure you declare them in your manifest using . Using this declaration enables filtering by external services such as Google Play, so that your app is installed only on devices that support the formats your app requires. For details, see OpenGL manifest declarations.

    Determining OpenGL extensions

    Implementations of OpenGL vary by Android device in terms of the extensions to the OpenGL ES API that are supported. These extensions include texture compressions, but typically also include other extensions to the OpenGL feature set.

    To determine what texture compression formats, and other OpenGL extensions, are supported on a particular device:

      Run the following code on your target devices to determine what texture compression formats are supported:

    Warning: The results of this call vary by device! You must run this call on several target devices to determine what compression types are commonly supported.

  • Review the output of this method to determine what OpenGL extensions are supported on the device.
  • Choosing an OpenGL API Version

    OpenGL ES API version 1.0 (and the 1.1 extensions) and version 2.0 both provide high performance graphics interfaces for creating 3D games, visualizations and user interfaces. Graphics programming for the OpenGL ES 1.0/1.1 API versus ES 2.0 differs significantly, and so developers should carefully consider the following factors before starting development with either API:

    • Performance — In general, OpenGL ES 2.0 provides faster graphics performance than the ES 1.0/1.1 APIs. However, the performance difference can vary depending on the Android device your OpenGL application is running on, due to differences in the implementation of the OpenGL graphics pipeline.
    • Device Compatibility — Developers should consider the types of devices, Android versions and the OpenGL ES versions available to their customers. For more information on OpenGL compatibility across devices, see the OpenGL Versions and Device Compatibility section.
    • Coding Convenience — The OpenGL ES 1.0/1.1 API provides a fixed function pipeline and convenience functions which are not available in the ES 2.0 API. Developers who are new to OpenGL may find coding for OpenGL ES 1.0/1.1 faster and more convenient.
    • Graphics Control — The OpenGL ES 2.0 API provides a higher degree of control by providing a fully programmable pipeline through the use of shaders. With more direct control of the graphics processing pipeline, developers can create effects that would be very difficult to generate using the 1.0/1.1 API.

    While performance, compatibility, convenience, control and other factors may influence your decision, you should pick an OpenGL API version based on what you think provides the best experience for your users.

    Начало работы с OpenGL … на Andro >

    Я опытный разработчик Android (если такая вещь существует), которая раньше никогда не работала с OpenGL.

    Существуют различные преимущества платформы Android (open-source, open distribution, portable и т. Д.), Которые заставляют меня думать, что это может быть отличная среда, чтобы наконец попасть в OpenGL.

    Но я также обеспокоен тем, что сложность работы в среде с ограниченными ресурсами может быть слишком большой для тех, кто раньше никогда не работал с 3D-графикой. Кроме того, похоже, что Android использует только подмножество OpenGL, и я не знаю, как это повлияет на мой опыт обучения.

    Как вы думаете? Является ли Android OpenGL разработкой новичком или для опытных разработчиков OpenGL?

    На самом деле нет «Android OpenGL», это просто OpenGL ES 1.1 или OpenGL ES 2.0, который является подмножеством OpenGL, но ориентирован на мобильные и встроенные устройства.

    Я не думаю, что какая-либо платформа «приветствуется новичком», просто вам нужно получить необходимые знания, чтобы использовать ее. Для OpenGL / OpenGL ES вам необходимо иметь определенные знания компьютерной графики, прежде чем пытаться их использовать. GL ES и GL очень похожи, а знание GL ES также работает в GL (не наоборот, поскольку это подмножество), поэтому просто входите в него.

    Я рекомендую книгу OpenGL ES 2.0 Programming Guide (для GL ES 2.0) и книгу OpenGL ES Game Developmen t для OpenGL ES 1.1. Эти книги находятся на C, вам нужно «переносить» их на Java, поскольку Android использует это, но основы одинаковы.

    Записки разработчика

    Посвящаю разработке ПО и всего с ним связанного

    Заметки об OpenGL ES в Andro >Март 26th, 2012 § 0 comments

    Сегодня я хотел бы рассказать о некоторых моментах в работе с OpenGL ES в Android информации по этому поводу не так уж много и большая её часть англоязычная. Первое что хотел бы сразу отметить, старайтесь тестировать на устройстве т.к. очень часто бывает, что отображается на эмуляторе, то может не отображаться на устройстве и наоборот. Первое что мы должны сделать, это имплементировать класс GLSurfaceView и интерфейс GLSurfaceView.Renderer. Базовый код будет выглядеть примерно так.

    Класс Run унаследованный от Activity

    Класс SurfaceView, унаследованный от GLSurfaceView

    Класс GlRenderer, имплементирующий интерфейс GLSurafaceView.Renderer


    Вот ваш каркас для ваших приложений Android с использование OpenGL ES, если все правильно сделано, то вы получите экран, закрашенный серым цветом. Основная работа происходит в GlRenderer, как видите. Сначала вызывается функция onSurfaceCreated (это происходит каждый раз, когда поверхность экрана создается или пересоздается) в ней мы вызываем функцию gl.glClearColor, это функция устанавливает цвет очистки экрана в формате RGBA. Далее вызывается функция onSurfaceChanged (это происходит каждый раз когда, размер экрана меняется, к примеру, вы перевернули устройство, и оно перешло из портретного в лендскейп). Первая проверка на то что бы не произошло деление на ноль, здесь оно не используется, может потребоваться позже. Далее мы выбираем, с какой матрицей работать, активная матрица над которой и будут совершаться преобразования в данном случае GL10.GL_PROJECTION отвечает за всю сцену. glViewport устанавливает наш вьюпорт, задаем его во весь экран.

    Одна из особенностей OpenGL, которую стоит запомнить точка (0;0) во вьюпорте это нижний левый угол (а не верхний как мы привыкли при рисовании на Canvas). Функция glLoadIdentity устанавливает единичную матрицу для текущей активной матрицы преобразований. Последняя функция, что вызывается это glOrthof в ней собственно и задается тот способ, как мы будем смотреть на нашу сцену. glOrtho используется для отображения двухмерной графики это все еще 3D, но только глубина (координата z) равно по умолчанию 0.0. Здесь задается формат нашей координатной сетки, он может быть любой от -1.0 до 1.0 по x и столько же по y или же, как в примере от (0;width) по x и (0;height) по y, так же задан наш план видимости по z вы спросите, почему его не установить в (0;0) этого делать не рекомендуют. В функции onDrawFrame вызывается glClear, эти два параметра указывают очистить буфер экрана и буфер глубины. Вот это базовое приложения я постарался разобрать основные моменты код примеров для Eclipse вы можете скачать с bitbucket.org ссылку приложу в конце.

    Следующим шагом будет вывод треугольника на экран. Для этого создадим новый класс Triangle

    Тут появляется много новых основополагающих вещей, разберем их подробнее. Я не буду приводить код всего проекта, т.к. основным отличием будет всего лишь то, что я задам координаты ортогональной проекции статически, а именно от (0;320) по x (0;480) по y OpenGL автоматически переведет их в физические координаты, об этом нам беспокоится не надо. Последним отличием будет то, что в onDrawFrame будет вызываться код triangle.draw(gl);

    Вернемся к нашему классу Triangle, в нем используется java.nio это позволяет нам выделять память не в куче виртуальной машины, а в куче физического устройства. Переменная vertexBuffer собственно и будет хранить точки для рисования. Переменная vertices хранит эти точки для того что бы преобразовать их в нужный нам формат. Как видите, каждая точка задается тремя переменными типа float (x,y,z) В конструкторе, что происходит мы, создаем ByteBuffer вызываем allocateDirect (выделяет целый блок памяти заданного размера) для каждого значения vertices требуется 4 байта. Выставляем порядок ByteOrder.nativeOrder() (в зависимости от типа платформы будет BIG_ENDIAN или LITTLE_ENDIAN это способ хранения чисел в памяти). Далее присваиваем нашему vertexBuffer’у значения и кладем в него массив после этого устанавливаем позицию в буфере в начало. В функции draw мы вызываем gl.glEnableClientState(GL10.GL_VERTEX_ARRAY) эта команда говорит OpenGL ES, что мы будем рисовать то что имеет координаты (немного бессмысленно т.к. нельзя нарисовать то что координат не имеет). Следующая команда gl.glColor4f устанавливает цвет рисования в формате RGBA. glVertexPointer мы говорим, где находятся наши координаты, первый аргументы функции указывает, сколько чисел представляют вершину в данном случае ставим 3 (x;y;z) если бы наш массив состоял из координат (x;y) то мы бы поставили 2. Следующим параметром идет тип переменной, который мы используем для хранения координат, в данном случае это float. Следующий параметр говорит как удаленны векторы в памяти друг от друга, в данном случае они располагаются последовательно, так что ставим 0 и последний параметр это и будет наш буфер. Наконец мы вызываем gl.glDrawArrays первый параметр указывает, какой примитив мы собираемся нарисовать, вторым параметром задается смещение (он нужен когда мы хотим нарисовать не все примитивы, а только подмножество) и третьим параметром задается количество вершин, которые мы хотим нарисовать. Последняя функция возвращает режим рисования в прежнее состояние.

    Тут показано два примитивных примера для работы с OpenGL ES в Android, не рассмотренными остались еще масса моментов, таких как наложение текстур, анимация, освещение и прочее, но это в следующих заметках. Привожу ссылку на bitbucket где выложены рабочие примеры для Eclipse тут

    Если вы найдете не точности или откровенные глупости напишите, и я исправлю, т.к. сам только начинаю работать с OpenGL ES.

    Создание среды OpenGL ES

    Для того, чтобы рисовать графику с помощью OpenGL в Android приложениях, необходимо создать для этого контейнер просмотра. Один из прямолинейных способов, это использовать объекты GLSurfaceView и GLSurfaceView.Renderer. GLSurfaceView это контейнер для просмотра графики, нарисованной с помощью OpenGL, а GLSurfaceView.Renderer управляет тем, что будет нарисовано в этом контейнере. Подробная информация о данных классах содержится в разделе OpenGL ES.

    Использование GLSurfaceView это всего лишь один из способов включить OpenGL ES в ваше приложение. Для полноэкранного просмотра графики это разумный выбор. Разработчикам, которые хотят включить графику OpenGL ES в небольшую часть разметки, следует обратить внимание на класс TextureView. В действительности, разработчики-самоучки, можно выводить OpenGL графику с помощью компонента SurfaceView, однако это требует довольно много дополнительного кода.

    В уроке поясняется как создать минимальную реализацию GLSurfaceView и GLSurfaceView.Renderer в простом явлении.

    Объявляем использование OpenGL ES в манифесте

    Для использования OpenGL ES 2.0 в приложении, вы должны добавить следующие строки в файл манифеста:

    Если в вашем приложении используется компрессия текстур, вы должны также объявить форматы компрессии, которые оно поддерживает. Тогда приложение сможет быть установлено только на совместимые устройства:

    Подробную информацию о форматах компрессии текстур смотрите в разделе OpenGL.

    Создаем явление для графики OpenGL ES

    Приложения, использующие OpenGL ES содержат явления, подобно любым другим приложениям с пользовательским интерфейсом. Главное отличие от других приложений в том, какие компоненты будут находиться в разметке явления. В то время как в обычных приложениях используются кнопки, поля ввода и списки, в приложениях с OpenGL ES вы можете добавить также компонент GLSurfaceView.

    В следующем примере показана минимальная реализация явления, которое использует GLSurfaceView :

    OpenGL, a noob’s guide for Android developers

    So, you dec >it’s normal !

    What’s OpenGL ?

    ES what now ? …

    You had figured it out, it was too nice to be true, there is a catch. Andro > ES . OpenGL ES is a variant of OpenGL’s specifications for embedded system.
    OK, ok ! That’s not that bad, there are differences but nothing major. That means some code working on your computer may not be working as is on your phone but almost.
    Ouf !

    The graphic driver ?

    “I thought Android was made in Java and I didn’t have to care about the hardware unless I would use native code (C or C++)”

    You are almost right. When you use OpenGL, you speak directly to the graphic driver and so it is possible the same Java code doesn’t work the same way on all phones. But there will be still time to care about this if and when such problems arise !

    Let’s dive in !

    I am only going to talk about OpenGL ES 2.0 because it is the one supported on most Android phones (Android 2.2+). Nevertheless, that should be enough to start and launch you for OpenGL ES 3.0 or 3.1 should you need it.

    In the next sections, I will introduce some important points and “ gotchas” without getting into implementation details. To know how everything goes together, go check the example project which goes along this article : https://bitbucket.org/Xzan/opengl-example .
    Please note everything has been put into one file on purpose to try to ease the reading.

    GLSurfaceView and the Renderer

    We need to start somewhere and, generally, it’s best to start at the beginning. To avoid confusing you from the start, we are going to start with what you need to know for Android in Java.

    In our case, we start by adding a view in which we are going to display the result of our OpenGL commands. This view is called GLSurfaceView and takes care of the thread’s creation for your OpenGL commands.
    Then enters its interface : GLSurfaceView.Renderer which will be called at 3 key moments of GLSurfaceView’s OpenGL’s thread:

    • on SurfaceCreated(GL10 gl, EGLConfig config)
    • on SurfaceChanged(GL10 gl, int w >DrawFrame(GL10 gl)

    Even though they are pretty explicites, it’s important to know what you are going to do in each of them.

    * In on SurfaceCreated, you initialize your program and your initial configurations. You can see this method as the View’s constructor . This method is called once for each Surface’s view’s cycle. But the Surface can be destroyed and this method will be called when the next one is created.

    * on SurfaceChanged is a good place to create your textures (we’ll get back on that) and (re)create what depends on your view’s size. You can see this method as View.onSizeChanged(int w, int h, int oldw, int oldh). This method is also not called often.

    * Finally, on DrawFrame is called everytime your views is going to be rendered on screen, in other words very often. You can see that as the method View.onDraw(Canvas canvas) and therefore, best practices about performances apply there as well (E.g.: do not instantiate objects in this method, etc.).

    Bonus : You can ask your view not to be redrawn every time but only when it’s “dirty”. To achieve this, call GLSurfaceView.setRenderMode(int) with the parameter RENDERMODE_WHEN_DIRTY. Then, call GLSurfaceView.requestRender() to specify your view is dirty.

    Note, SurfaceView isn’t a view like the others, it is rendered under your activity in which there is a hole to let you see your Surface through it. If you which to obtain something “more classic”, you can use a TextureView. There is no GLTextureView but you can find an implementation from Roman Nurik in Muzei : https://github.com/romannurik/muzei/blob/master/main/src/main/java/com/google/android/apps/muzei/render/GLTextureView.java .
    In itself, it’s not impossible to do OpenGL without GLSurfaceView or GLTextureView but it’s far simpler to use them than to take care of all this by yourself, specially at the beginning.

    How OpenGL works

    Now, it’s time to talk about OpenGL but before we go further, to understand it fully, we need a full overview of OpenGL’s pipeline. In other words, the steps by which OpenGL go through to build the picture to render on screen based on the values we feed it.

    In this section, I may use some words that are unknown to you or not completely understood as shader, fragment or texture. These concepts are important and are explained later. Do not hesitate to read this section again once you have finished reading the whole article to fully understand what is explained here.

    GLSL programs (or shaders)

    GLSL is short for Open GL Shader Language and is the name of the language in which we program OpenGL. The keyword is “ Shader”. This weird word you may have heard before, without understanding it, is actually simple. It’s a part of the OpenGL program which will be executed on the GPU.

    Moreover, it exists several types of shaders. Out of those, there are two which are of interest to us :

    • The vertex shader : in charge of computing the rendered position. We feed it a set of attributes associated to a point in a 3D space and it will compute the position on screen. This set of attributes is more often composed of coordinates and a color (or texture coordinates). The vertex shader is called once per vertex.
    • The fragment shader : in charge of computing the color for each pixel. It receives the output of the vertex shader as input. This code is executed for each pixel of your image. To be clearer, the GPU optimizes most of its calls to be as performant as possible for rendering and is capable of computing the value of several pixels in parallel. We often represent this as if the GPU computes each pixels simultaneously but what is important to get out of this is that we don’t start with the top left corner to finish to the bottom right. If you dec >A very simple example of those two shaders can be found in the example project :

    In the vertex shader, we receive 3 parameters :

    • uMVPMatrix : a matrix which allows us to change the point of view, rotation and scale.
    • vPosition : the coordinates which will form our “strip”.
    • vTextureCoordinate : the coordinates of each of our vertex.

    In the fragment shader, we receive 2 parameters :

    • uTexture : texture containing the picture to be shown.
    • position : parameter received from the vertex shader which contains the position of the pixel to display.

    As I am sure you know, there are some shaders a lot more complex than those.

    Enter the matrice (Coordinates systems)

    OpenGL’s coordinates system doesn’t care about the screen size as shown in the picture below :

    This is why it’s important to pass the ratio and other kind of information to the vertex shader. That’s the usefulness of this line in the example project.

    In the example project, and in a lot of other cases, the coordinates are passed as “ strip”. That means we pass the coordinates of adjacent triangles’ vertices creating the image we wish to show:

    Still in the example project, the array passed is composed of 4 vertices starting in the bottom left corner, going to the bottom right corner, to the top left corner and finishing in the top right corner.

    The coordinate of the texture are slightly different to respect the orientation in which the picture is loaded.

    Also, if you look a bit closer, you’ll notice the passed coordinates for the position go from -1 to 1 on the other hand those for the textures goes from 0 to 1. Also, the position coordinates contains depth as the Z coordinate but it’s not mandatory if you only do 2D.

    In the vertex shader given as example, there is a multiplication between uMVPMatrix and vPosition. vPosition is a matrix containing the coordinates mentioned ealier. uMVPMatrix is a matrix formed thanks to utility methods provided by the Matrix class from the Android framework. GLSL is capable of matrix multiplications and processing those simply and effectively.
    Another nuance, I used “vTextureCoordinate .xy”. This creates a size 2 vector containing the first and second value of the size 4 vector which is vTextureCoordinate. I could have done : “vTextureCoordinate .xx” to create a size 2 vector with the first value of vTextureCoordinate for both value.

    Note, a little subtlety you might encounter while reading shaders: to be more correct and respect naming conventions, I should have used “vTextureCoordinate. st”. STPQ replace XYZW when talking about texture coordinates and RGBA when talking about colors. In any case, using one or the other won’t change the execution, only its readability.

    Textures


    Textures are memory spaces in which the graphic processor (GPU) is stocking images. Either to render them or to write new values.

    Code to create new texture in memory can be found here.

    Buffers (FBO)

    A Frame Buffer Object (or FBO) comes on top of a texture and writes in it. Without FBO, all OpenGL commands you would execute would go on screen. This would be pretty annoying if you would make some effect by combining some other effects.

    Code to create FBOs can be found here.

    Advices

    In the sample project, I voluntarily put everything into one file. It has been done to ease the reading because, when I was learning, I noticed that trying to look for the piece of code I was trying to understand would stop me in my reflection and would not help me understand.
    Nevertheless, once you got the bases, I can only advise you to abstract as much as possible your code behind some Java >FBO’s creation for you, put your setup in a class that will extend GLSurfaceView and extract the shaders’ logic into their own classes (as GPUImage does it so well), etc. This will make the code cleaner and easier to read.

    Crash often but crash well. Debugging OpenGL code is particularly hard. Check for errors and check your states (E.g.: the state of your FBOs or your shaders’ compilation’s error) and throw a RuntimeException to help you see what and where it’s wrong. This will help you during development but also when testing on different devices.

    Finally, test manually on several devices and several Andro >flagships like the Galaxy S series or Galaxy Note series from Samsung but also on more modest devices. Don’t forget some famous Chinese brands like Wiko or Xiaomi.
    If you don’t own a lot of devices and/or want to play safe, publish your app on the Play Store’s alpha & beta channels to get feedback from your users before this goes to the wider audience.

    Conclusion

    Well you got it, developing for OpenGL, it’s a lot of boilerplate, mathematics and hair pulling. Nevertheless, rest assured, a lot of people went through this before you and they faced the same problem you will be facing so there will be help along the way.
    I hope I was able through this article to highlight some of the key concepts which will help you understand StackOverflow posts when you will search for answers to your questions.

    As mentioned earlier, the tutorial provided by the Android developer’s website is really good, even if missing a few points which, I hope, have been explained here. It also come with a great sample project which can be a huge source of inspiration and provides some utils methods which will help you a lot.

    Android — Android + OpenGL

    I have started a new updated serie of tutorials on OpenGL ES 2.0 for android. Check them out at: OpenGL ES 2.0

    I’m going to write a couple of tutorials on using OpenGL ES on Android phones. The theory of OpenGL ES is the same on different devices so it should be quite easy to convert them to another platform.

    I can’t always remember where I found particular info so I might not always be able to give you the right reference. If you feel that I have borrowed stuff from you but have forgotten to add you as a reference, please e-mail me.

    In the code examples I will have two different links for each function. The actual function will be linked to the android documentation and after that I will also link the OpenGL documentations. Like this:

    In this tutorial I will show you how to set up your OpenGL ES view that’s always a good place to start.

    Setting up an OpenGL ES View

    Setting up a OpenGL view has never been hard and on Android it is still easy. There really are only two things you need to get started.

    GLSurfaceView

    GLSurfaceView is a API class in Android 1.5 that helps you write OpenGL ES applications.

    • Providing the glue code to connect OpenGL ES to the View system.
    • Providing the glue code to make OpenGL ES work with the Activity life-cycle.
    • Making it easy to choose an appropriate frame buffer pixel format.
    • Creating and managing a separate rendering thread to enable smooth animation.
    • Providing easy-to-use debugging tools for tracing OpenGL ES API calls and checking for errors.

    If you want to get going fast with your OpenGL ES application this is where you should start.

    The only function you need to call on is:

    GLSurfaceView.Renderer

    GLSurfaceView.Renderer is a generic render interface. In your implementation of this renderer you should put all your calls to render a frame.
    There are three functions to implement:

    onSurfaceCreated

    Here it’s a good thing to setup things that you don’t change so often in the rendering cycle. Stuff like what color to clear the screen with, enabling z-buffer and so on.

    onDrawFrame

    Here is where the actual drawing take place.

    onSurfaceChanged

    If your device supports flipping between landscape and portrait you will get a call to this function when it happens. What you do here is setting upp the new ratio.
    Read more at: GLSurfaceView.Renderer

    Putting it together

    First we create our activity, we keep it clean and simple.

    Our renderer takes little bit more work to setup, look at it and I will explain the code a bit more.

    Fullscreen

    Just add this lines in the OpenGLDemo class and you will get fullscreen.

    This is pretty much all you need to get your view up and running. If you compile and run it you will see a nice black screen.

    References

    You can download the source for this tutorial here: Tutorial_Part_I.zip
    You can also checkout the code from: code.google.com

    This Post Has 90 Comments

    Samuh Varta

    thanks for starting this tutorial series on OpenGL for Android!

    odd256

    Thanks, this is extremely helpful.

    I believe there’s a typo on line 220:
    s/OpenGLDemo/TutorialPartI

    chhsf

    Hi Per-Erik
    Thank you for your tutorial.But My application is not work for a error.It is GLLogger, it show couldn’t load library(Cannot find library).
    I don’t know what’s wrong.

    Gary Wang

    Dear Sir, really good articles to Android OpenGL ES!
    Thanks for ur sharing!

    Sr > 24 Feb 2010 Reply

    Thank you for the tutorial, alas some inspiration to start of OpenGL ES :)

    any way to use a GLSurfaceView as a background? the idea is to have a normal surfaceview on top of the GLSurfaceView, render the background with opengl, then throw some sprites onto the other view. so as the opengl is just handling the background. I currently have this working fine, except i cannot get the GLSurfaceView to stay in the background.. no amount of view manipulation ie. what order they are in etc, seems to help.

    murali

    Your article is very helpful. Thanks

    My doubt is opengl return a .exe file as output in android, similarly in what format the o/p file will be in Android ? May be my question is very silly.

    Thanks in advance.

    shubham

    Thanx Bro..it’s realy good try.

    shubham

    hi friend’s ,I want to draw an 2d image ..how can i do here.
    I got pixel position of image ..

    Thank in Advance..

    Chinson


    It’s very helpful. Thanks!

    Daniel Rodríguez

    Awesome tutorial. Thank you very much.

    Tom Anderson

    By the way thought it could be helpful for anyone since black is the same as the default color. Try this instead:

    // Set the background color to RED( rgba ).
    gl.glClearColor(255.0f, 0.0f, 0.0f, 0.5f);

    Amandeep

    Too Good Blog.
    Very Clear and Informative.
    Thanks for availing this information

    czhedu

    Great tutorial…….
    Clear and easy to understand……….

    ashik

    really nice tutorial and Im gonna add ur blog in my blogroll!!

    srikanth

    thanks
    its really nice to start opengl in eclipse
    if possible please provide the code for drawing arc in opengl using java

    Really appreciate your tutorials, thanks!

    gabriel

    excellent to get started nice and easy :)

    just a note, you also need to include two classes for enable full screen:
    import android.view.Window;
    import android.view.WindowManager;

    great work on the writing, links and selecting the examples. jumping on part II now.

    PS: this should be linked from the android manual, where they say it’s not the scope of the glsurfaceview to explain how to do openGL helloworld! think that if you used more androidesque syntax they would consider it :) …just sugar, like @Override, etc

    gabriel

    *to enable full screen

    subho

    i am facing some error:
    [2010-11-20 15:31:55 – Emulator] invalid command-line parameter: partition-size.
    [2010-11-20 15:31:55 – Emulator] Hint: use ‘@foo’ to launch a virtual device named ‘foo’.
    [2010-11-20 15:31:55 – Emulator] please use -help for more information

    c programming

    Good Work. Keep it up.

    Sureshkumar

    dear sir, I do have a question regarding this codes here
    // Sets the current view port to the new size.
    gl.glViewport(0, 0, width, height);// OpenGL docs.
    // Select the projection matrix
    gl.glMatrixMode(GL10.GL_PROJECTION);// OpenGL docs.
    // Reset the projection matrix
    gl.glLoadIdentity();// OpenGL docs.
    // Calculate the aspect ratio of the window
    GLU.gluPerspective(gl, 45.0f,
    (float) width / (float) height,
    0.1f, 100.0f);
    // Select the modelview matrix
    gl.glMatrixMode(GL10.GL_MODELVIEW);// OpenGL docs.
    // Reset the modelview matrix
    gl.glLoadIdentity();// OpenGL docs.

    why do we have to change the glMatrixMode to GL10.GL_MODELVIEW? and reload the glLoadIdentity?

    I hope I would here from your guidance since I’m new to OPENGL and android…

    Hi,
    I have followed this tutorial and hve also got a square to appear on screen. I am able to move the square by using up down left and right keys. My question is how can I get a cameraq to “follow” this square when it moves? ie I want the camera to be focused on the square.

    Per-Erik Bergman

    Nate: You can use en GLSurfaceView as any view so with a frame layout I guess you can add it as a background.

    mural: On android we get an .apk file.

    shubham: Rendering 2D with OpenGL is a big tutorial itself, it is in the pipeline.

    Pach: GL_PROJECTION and GL_MODELVIEW is two different matrix and since we need to “reset” them both we need to do glLoadIdentity on both.

    John: The easiest way is to create a camera object that you can steer. When rendering do the camera translation first before you render the square.

    Robin Degen

    As an openGL programmer on the PC, this was all i needed to get me started on android. However, i’d prefer using C++ over java, so that will be a next thing to figure out on android. But atleast i got started now. Thanks for the info

    sameh ammar

    Thanx you are very nice :)

    Nayanesh Gupte

    How do I bind different textures to to different faces of cube?

    I’m trying something like this

    gl.glActiveTexture(GL10.GL_TEXTURE0);
    gl.glClientActiveTexture(GL10.GL_TEXTURE0);
    gl.glEnable(GL10.GL_TEXTURE_2D);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glFrontFace(GL10.GL_CCW);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
    ….
    gl.glActiveTexture(GL10.GL_TEXTURE5);
    gl.glClientActiveTexture(GL10.GL_TEXTURE5);
    gl.glEnable(GL10.GL_TEXTURE_2D);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[5]);
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glFrontFace(GL10.GL_CCW);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

    gl.glTexEnvx(GL10.GL_TEXTURE_ENV , GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);

    gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);

    lattimore

    Excellent!
    Great tutorial!

    Adrian

    Hi,
    Is it possible to modify the draw method of an object in such a way that it only needs to be drawn once and not every time in the onDraw method? I am having performance issues while drawing lots of pixels for a background image and wondered if the draw method could be changed?

    Edward

    Sorry..i’m new in OpenGL ES..i just wondering, why do we need to include GL10?

    And, I found that its quite difficult to look for OpenGL ES in Android in the internet but tons in iPhone…

    haryo

    thanxs Per-Erik Bergman…
    its work..

    but i still really confuse to make graphics for AR using this ..any tutorial for make it ? please ??

    minimal

    Thanks this is really great.
    But I would also like to see a similar example set for NDK.
    I was at google I/0 and some of the stuff that they showed on NDK was awesome.

    harinath

    This was the excellent tutorial.i am having few doubts regarding the fallowing.
    How do I bind different textures to to different faces of cube?
    coud u please clarify it.

    Guillermo

    Hey, really really really great tutorial!! it`s very simple, i`m starting with opengl and android and its helps me a lot to dont missup with other stuffs. The links on the documentation also helps a lot on the learning process. I`ll continue with the other tutorials you`ve already posted. Thanks a lot!

    Helen

    Another much easier way to set your application to fullscreen ist by adding 1 line to the Andro >

    Цукерберг рекомендует:  Вакансии Мобильное приложение Стоматология Улыбка
    Понравилась статья? Поделиться с друзьями:
    Все языки программирования для начинающих
    Рубрика: Разработка / Графика