Чтобы рисовать графику с помощью 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, перейдите к следующим урокам.