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

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

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

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

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

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

<uses-feature android:glEsVersion="0x00020000" android:required="true" />

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

<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
<supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />

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

Создайте объект Activity для графики OpenGL ES.

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

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

Kotlin

class OpenGLES20Activity : Activity() {

    private lateinit var gLView: GLSurfaceView

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Create a GLSurfaceView instance and set it
        // as the ContentView for this Activity.
        gLView = MyGLSurfaceView(this)
        setContentView(gLView)
    }
}

Java

public class OpenGLES20Activity extends Activity {

    private GLSurfaceView gLView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Create a GLSurfaceView instance and set it
        // as the ContentView for this Activity.
        gLView = new MyGLSurfaceView(this);
        setContentView(gLView);
    }
}

Примечание. Для работы с OpenGL ES 2.0 требуется Android 2.2 (API уровня 8) или более поздней версии. Убедитесь, что в вашем проекте для Android указан этот или более высокий уровень API.

Создание объекта GLSurfaceView

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

Для GLSurfaceView требуется минимум кода, поэтому для быстрой реализации обычно создают внутренний класс в действии, которое его использует:

Kotlin

import android.content.Context
import android.opengl.GLSurfaceView

class MyGLSurfaceView(context: Context) : GLSurfaceView(context) {

    private val renderer: MyGLRenderer

    init {

        // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2)

        renderer = MyGLRenderer()

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(renderer)
    }
}

Java

import android.content.Context;
import android.opengl.GLSurfaceView;

class MyGLSurfaceView extends GLSurfaceView {

    private final MyGLRenderer renderer;

    public MyGLSurfaceView(Context context){
        super(context);

        // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2);

        renderer = new MyGLRenderer();

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(renderer);
    }
}

Ещё одно необязательное дополнение к реализации GLSurfaceView – настроить режим рендеринга так, чтобы представление отрисовывалось только при изменении данных рисования, с помощью настройки GLSurfaceView.RENDERMODE_WHEN_DIRTY:

Kotlin

// Render the view only when there is a change in the drawing data
renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY

Java

// Render the view only when there is a change in the drawing data
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

Этот параметр предотвращает перерисовку фрейма GLSurfaceView до вызова requestRender(), что более эффективно для этого примера приложения.

Создание класса отрисовщика

Реализация класса GLSurfaceView.Renderer, или средства визуализации, в приложении, использующем OpenGL ES, – это самое интересное. Этот класс управляет тем, что рисуется на связанном с ним объекте GLSurfaceView. В средстве визуализации есть три метода, которые вызываются системой Android, чтобы определить, что и как рисовать на GLSurfaceView:

  • onSurfaceCreated() – вызывается один раз для настройки среды OpenGL ES представления.
  • onDrawFrame() – вызывается при каждой перерисовке представления.
  • onSurfaceChanged() – вызывается при изменении геометрии представления, например при изменении ориентации экрана устройства.

Ниже приведен пример базовой реализации средства визуализации OpenGL ES, которое только рисует черный фон в GLSurfaceView:

Kotlin

import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

import android.opengl.GLES20
import android.opengl.GLSurfaceView

class MyGLRenderer : GLSurfaceView.Renderer {

    override fun onSurfaceCreated(unused: GL10, config: EGLConfig) {
        // Set the background frame color
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
    }

    override fun onDrawFrame(unused: GL10) {
        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
    }

    override fun onSurfaceChanged(unused: GL10, width: Int, height: Int) {
        GLES20.glViewport(0, 0, width, height)
    }
}

Java

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;

public class MyGLRenderer implements GLSurfaceView.Renderer {

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        // Set the background frame color
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    }

    public void onDrawFrame(GL10 unused) {
        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    }

    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
    }
}

Вот и всё! Приведенные выше примеры кода создают простое приложение для Android, которое отображает черный экран с помощью OpenGL. Хотя этот код не делает ничего интересного, создав эти классы, вы заложили основу, необходимую для начала рисования графических элементов с помощью OpenGL.

Примечание. Вы можете задаться вопросом, почему у этих методов есть параметр GL10, если вы используете API OpengGL ES 2.0. Эти сигнатуры методов просто повторно используются для API 2.0, чтобы упростить код фреймворка Android.

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