Android アプリケーションで OpenGL ES を使ってグラフィックスを描画するには、ビューコンテナを作成する必要があります。これを簡単に行う方法としては、GLSurfaceView
と GLSurfaceView.Renderer
の両方を実装することが挙げられます。GLSurfaceView
は OpenGL で描画されたグラフィックスのビューコンテナであり、GLSurfaceView.Renderer
はビュー内で描画される対象を制御します。こうしたクラスの詳細については、OpenGL ES デベロッパー ガイドをご覧ください。
GLSurfaceView
は、OpenGL ES グラフィックスをアプリケーションに組み込む方法の 1 つにすぎません。フルスクリーンまたはフルスクリーンに近いグラフィックス ビューの場合、これは適切な選択肢です。
OpenGL ES グラフィックスをレイアウトのごく一部に組み込む場合は、TextureView
をご覧ください。自作する場合は SurfaceView
を使用して OpenGL ES ビューを構築することも可能ですが、かなりの量の追加コードを書く必要があります。
このレッスンでは、シンプルなアプリケーション アクティビティで 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 デベロッパー ガイドをご覧ください。
OpenGL ES グラフィックスのアクティビティを作成する
OpenGL ES を使用する Android アプリケーションには、ユーザー インターフェースを備えた他のアプリケーションと同様のアクティビティがあります。他のアプリケーションとの主な違いは、アクティビティのレイアウトに追加するものです。多くのアプリケーションでは 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
実装に任意で追加するもう 1 つの例として、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);
この設定により、requestRender()
を呼び出すまで GLSurfaceView
フレームが再描画されなくなるため、このサンプルアプリの効率性が高くなります。
レンダラクラスを作成する
OpenGL ES を使用するアプリケーション内の GLSurfaceView.Renderer
クラスの実装、つまりレンダラでは、応用をきかせることができます。このクラスは、関連付けられている GLSurfaceView
で描画する対象を制御します。GLSurfaceView
で何をどのように描画するかを把握するために、Android システムによって呼び出されるレンダラには、3 つのメソッドがあります。
onSurfaceCreated()
- ビューの OpenGL ES 環境をセットアップするために 1 回呼び出されます。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); } }
内容はこれだけです。上記のコード例は、OpenGL を使用して黒い画面を表示する簡単な Android アプリケーションを作成します。このコードは特に目を引くものではありませんが、こうしたクラスの作成を通じて、OpenGL を使ってグラフィック要素を描画するうえで必要な基礎を築きました。
注: OpenGL ES 2.0 API を使用している場合、上記のメソッドに GL10
パラメータが使用されているのを疑問に思うかもしれません。このメソッド シグネチャは、Android フレームワークのコードをよりシンプル化するために 2.0 API で再利用されるだけです。
OpenGL ES API に詳しい場合、これで OpenGL ES 環境をアプリに設定してグラフィックスの描画を始めることができます。OpenGL を使用するにあたってもう少し説明が必要な場合は、次のレッスンに進み、さらなるヒントを確認してください。