Android OpenGL HandsOn
-
Upload
ikuo-tansho -
Category
Self Improvement
-
view
2.141 -
download
2
description
Transcript of Android OpenGL HandsOn
![Page 1: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/1.jpg)
AndroidOpenGL/ES ハンズオン
Smart.LABO丹所 育男(tan1234jp)
1
![Page 2: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/2.jpg)
自己紹介• 丹所 育男(たんしょ いくお)• 春日井市出身・自宅は名古屋市・実家は可児市• 講師→制御系→ネットワーク系→業務系→制御系→システム保守→制御系→業務系→携帯アプリ
• 2011年6月に「SMART.LABO」として独立• Androidアプリの開発がメイン(iPhone,Coronaも)
• Twitter : @tan1234jp
2
![Page 3: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/3.jpg)
OpenGL/ESとは?• OpenGL Embedded Subsetの略• 3Dコンピュータグラフィックス用APIのサブセットで、3D空間に浮かんだ頂点を結んだ図形を描画することに特化している。
• 主に携帯電話などの組み込みシステムや、ゲーム専用機で使われている。→iOS, Android, Symbian OS,→PlayStation3、Nintendo 3DS
3
![Page 4: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/4.jpg)
描画APIのサポート• 点• 直線• 三角形• 四角形• 五角形以上の多角形• 円• 文字
• 点• 直線• 三角形
Canvas OpenGL/ES
4
![Page 5: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/5.jpg)
AndroidのView• Androidには、3種類のViewがある。→View,SurfaceView,GLSurfaceView
• OpenGLでは、GLSurfaceViewを継承したものを使う。
5
![Page 6: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/6.jpg)
GLSurfaceView• OpenGLの描画に特化したView• 描画タイミングは端末依存(プログラマが決めることもできる)
• 別スレッドで動作するため、直接UIに対して変更をかけることは不可
6
![Page 7: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/7.jpg)
OpenGL/ESの初期化• プロジェクトの作成
• バージョンの決定(Ver1.5以降であればOK)
OpenGL_Sample
7
![Page 8: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/8.jpg)
OpenGL/ESの初期化• パッケージ名の設定
com.example.opengl_sample
8
![Page 9: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/9.jpg)
OpenGL/ESの初期化package com.example.opengl_sample;
import android.app.Activity;import android.opengl.GLSurfaceView;import android.os.Bundle;
public class OpenGL_SampleActivity extends Activity { private GLSurfaceView glSurfaceView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); glSurfaceView = new GLSurfaceView(this); glSurfaceView.setRenderer(new GLRenderSample()); setContentView(glSurfaceView); }
エラーとなるが無視
9
![Page 10: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/10.jpg)
OpenGL/ESの初期化 @Override protected void onPause() { super.onPause(); glSurfaceView.onPause(); }
@Override protected void onResume() { super.onResume(); glSurfaceView.onResume(); }
//ここに後でコードを追加します!}
10
![Page 11: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/11.jpg)
OpenGL/ESの初期化GLRenderSampleの作成onResume()の後に以下のコードを追加。
class GLRenderSample implements GLSurfaceView.Renderer {
public void onDrawFrame(GL10 gl) { gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); gl.glClear(GL10.GL_COLOR_BUFFER_BIT); }
public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); }
public void onSurfaceCreated(GL10 gl, EGLConfig config) { }
11
![Page 12: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/12.jpg)
OpenGL/ESの初期化• 実行!真っ白な画面になりましたか?
12
![Page 13: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/13.jpg)
コード解説• GLRenderSampleの各メソッド
メソッド名 呼ばれるタイミングonSurfaceCreated(GL10 gl, EGLConfig eglconfig) GLSurfaceView用のメモリ確保が終了
onSurfaceChanged(GL10 gl, int width, int height) 画面サイズが変更された時
onDrawFrame(GL10 gl) 再描画が必要な時
13
![Page 14: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/14.jpg)
コード解説• 各メソッドの呼び出され方
onSurfaceCreated
onSurfaceChanged
onDrawFrame呼び出されるタイミングは
端末依存14
![Page 15: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/15.jpg)
コード解説• 描画範囲の設定
メソッド名 役割
glViewport(int x, int y, int width, int height);OpenGL/ESの描画範囲を指定する。「どの座標(x, y)から、幅width、高さheightまで」を描画範囲とする。
15
![Page 16: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/16.jpg)
コード解説• 描画クリア
• glClearColorの引数の値を適当に変更して、いろいろな色で塗りつぶされることを確認してみてください。
メソッド名 役割
glClearColor(float r, float g, float b, float a);画面全体を塗りつぶす色を決定する。RGBA(Aはアルファ値)を指定する。指定できる範囲は0~1の実数値。
glClear(int mask); 塗りつぶしを実行する。引数にGL_COLOR_BUFFER_BITを指定する。
16
![Page 17: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/17.jpg)
OpenGL/ESの座標系• 座標系の違い
ViewSurfaceView OpenGL
原点(0,0)
原点(0,0)
(480,0)
(0,854)
(1,0)(-1,0)
(0,1)
(0,-1)
(Xperiaの場合)
17
![Page 18: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/18.jpg)
三角形を描画する• 例えば、(0,0),(1,0),(1,1)の3点を結ぶ三角形を描画する場合・・・
HT-03A Xperia
480px
320px
854px
480px
18
![Page 19: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/19.jpg)
三角形を描画する• onDrawFrameを修正 public void onDrawFrame(GL10 gl) { gl.glClearColor(0.0f, 1.0f, 1.0f, 1.0f); //第1引数に変更あり! gl.glClear(GL10.GL_COLOR_BUFFER_BIT); float positions[] = { 1.0f, 0.0f, 0.0f,//右(1,0) 0.0f, 0.0f, 0.0f,//原点(0,0) 1.0f, 1.0f, 0.0f,//右上(1,1) }; ByteBuffer bb = ByteBuffer.allocateDirect(positions.length * 4); bb.order(ByteOrder.nativeOrder()); FloatBuffer fb = bb.asFloatBuffer(); fb.put(positions);
19
![Page 20: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/20.jpg)
三角形を描画する• onDrawFrameを修正(続き)
fb.position(0); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fb); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); }
20
![Page 21: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/21.jpg)
三角形を描画する• 実行!→水色の背景に白い三角形が表示されましたか?→解像度の違う端末でも同じ画面が表示されましたか?
21
![Page 22: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/22.jpg)
コード解説• 座標の設定float positions[] = { 1.0f, 0.0f, 0.0f,//右(1,0) 0.0f, 0.0f, 0.0f,//原点(0,0) 1.0f, 1.0f, 0.0f,//右上(1,1) };
• 浮動小数の1次元配列で表す• 配列に格納する順番は「頂点1(x,y,z)」「頂点2(x,y,z)」「頂点3(x,y,z)」・・・とする。
22
![Page 23: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/23.jpg)
コード解説• 座標配列をOpenGL/ESに転送
ByteBuffer bb = ByteBuffer.allocateDirect(positions.length * 4);bb.order(ByteOrder.nativeOrder());FloatBuffer fb = bb.asFloatBuffer();fb.put(positions);fb.position(0);
• 座標配列をOpenGL/ESで扱えるメモリ形式に変換
• AndroidでOpenGL/ESを扱う際の「おまじない」。
23
![Page 24: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/24.jpg)
コード解説• OpenGL/ESは、Android RuntimeではなくLibraries群(CPU依存)
• Javaの配列などのデータを、そのままOpenGL/ESへ転送することはできない
• java.nio.* パッケージを使用して、OpenGL/ESから直接参照できるようなデータに変換する必要がある。
24
![Page 25: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/25.jpg)
Androidアーキテクチャ
25
![Page 26: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/26.jpg)
コード解説• GLSurfaceViewに描画するメソッド名 役割
glEnableClientState(int array);
glVertexPointer()で転送するメモリ情報の種類を設定する。引数はいろいろあるが、座標情報を転送する場合は「GL_VERTEX_ARRAY」を指定する。
glVertexPointer(int size, int type, int stride, Buffer pointer);
位置情報を設定する。size : 位置情報の要素数。3次元の場合は3。type : 位置情報の変数の型。stride : 常時0。pointer : OpenGL/ESに転送可能な位置情報
glDrawArrays(int mode, int first, int count);
GLSurfaceViewに描画する。mode : 描画方法を指定する(後ほど説明)first : 描画する位置情報の開始位置。count : 位置情報を使用する数。
26
![Page 27: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/27.jpg)
(発展)四角形を描画する• onDrawFrameを修正 public void onDrawFrame(GL10 gl) { : : float positions[] = { 1.0f, 0.0f, 0.0f,//右(1,0) 0.0f, 0.0f, 0.0f,//原点(0,0) 1.0f, 1.0f, 0.0f,//右上(1,1) 0.0f, 0.0f, 0.0f,//原点(0,0) 0.0f, 1.0f, 0.0f,//上(0,1) 1.0f, 1.0f, 0.0f,//右上(1,1) };
27
![Page 28: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/28.jpg)
(発展)四角形を描画する• onDrawFrameを修正(続き) : : gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fb); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3 * 2); }
28
![Page 29: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/29.jpg)
(発展)四角形を描画する• 実行!→水色の背景の右上に、白い四角形が表示されましたか?→解像度の違う端末でも同じ画面が表示されましたか?
29
![Page 30: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/30.jpg)
(発展)四角形を描画する• 三角形を組み合わせれば、どんな多角形でも作成可能
+ =
30
![Page 31: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/31.jpg)
(発展)四角形を描画する• 重複している座標がある! public void onDrawFrame(GL10 gl) { : : float positions[] = { 1.0f, 0.0f, 0.0f,//右(1,0) 0.0f, 0.0f, 0.0f,//原点(0,0) 1.0f, 1.0f, 0.0f,//右上(1,1) 0.0f, 0.0f, 0.0f,//原点(0,0) 0.0f, 1.0f, 0.0f,//上(0,1) 1.0f, 1.0f, 0.0f,//右上(1,1) };
• 座標を使いまわししたい!
31
![Page 32: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/32.jpg)
(発展)四角形を描画する• onDrawFrameを修正 public void onDrawFrame(GL10 gl) { : : float positions[] = { 1.0f, 0.0f, 0.0f,//右(1,0) 0.0f, 0.0f, 0.0f,//原点(0,0) 1.0f, 1.0f, 0.0f,//右上(1,1) // 0.0f, 0.0f, 0.0f,//原点(0,0) 0.0f, 1.0f, 0.0f,//上(0,1) // 1.0f, 1.0f, 0.0f,//右上(1,1) };
32
![Page 33: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/33.jpg)
(発展)四角形を描画する• onDrawFrameを修正(続き)
: :
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fb);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); //第1・3引数変更 }
33
![Page 34: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/34.jpg)
(発展)四角形を描画する• 実行!→先ほどと同じ画面になりましたか?
34
![Page 35: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/35.jpg)
glDrawArraysの引数• glDrawArrays()の第1引数で指定する値(定数)により、描画方法を変更することができる。引数 説明GL10.GL_POINTS 点
GL10.GL_LINES 直線
GL10.GL_LINE_STRIP 折れ線GL10.GL_TRIANGLES 三角形GL10.GL_TRIANGLE_STRIP 1辺を共有しながら帯状に三角形を描画するGL10.GL_TRIANGLE_FAN 1点を共有しながら扇状に三角形を描画する
35
![Page 36: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/36.jpg)
glDrawArraysの引数• 描画方法の違い public void onDrawFrame(GL10 gl) { : : float positions[] = { 1.0f, 0.0f, 0.0f,//右(1,0) 0.0f, 0.0f, 0.0f,//原点(0,0) 1.0f, 1.0f, 0.0f,//右上(1,1) 0.0f, 1.0f, 0.0f,//上(0,1) }; : : gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); //第1・3引数変更 }
①②③④
36
![Page 37: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/37.jpg)
GL_POINTS• 点(1px)を描画する
④ ③
①②
37
![Page 38: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/38.jpg)
GL_LINES• 直線を描画する時に使う• 座標の描画順は、①②→③④→⑤⑥→
①②
③④
38
![Page 39: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/39.jpg)
GL_LINE_STRIP• 直線を描画する時に使う• 座標の描画順は、①②→②③→③④→④⑤→
②
④ ③
①
39
![Page 40: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/40.jpg)
GL_TRIANGLE_STRIP• 隣接した三角形を描画する時に使う• 座標の描画順は、①②③→②③④→③④⑤→
④ ③
② ① ② ①
③④
40
![Page 41: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/41.jpg)
GL_TRIANGLE_FAN• 扇形を描画する時に使う• 座標の描画順は、①②③→①③④→①④⑤→
①
③
②
④
①
③④
②
41
![Page 42: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/42.jpg)
GL_TRIANGLE_FAN• 引数を変更して実行すると、右の図形が描画されます。
42
![Page 43: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/43.jpg)
色をつける• onDrawFrameを修正 public void onDrawFrame(GL10 gl) { : : gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fb); gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f); //追加 gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); }
43
![Page 44: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/44.jpg)
色をつける• 実行!→水色の背景の右上に、赤い四角形が表示されましたか?
44
![Page 45: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/45.jpg)
コード解説• 描画色を指定する
• glColor4fの引数の値を適当に変更して、いろいろな色で塗りつぶされることを確認してみてください。
メソッド名 役割
glColor4f(float r, float g, float b, float a);描画色を決定する。RGBA(Aはアルファ値)を指定する。指定できる範囲は0~1の実数値。
45
![Page 46: Android OpenGL HandsOn](https://reader034.fdocuments.net/reader034/viewer/2022052307/559129a01a28ab04198b4743/html5/thumbnails/46.jpg)
• 本日のハンズオンはここまでです。お疲れ様でした。
• 今回は、単純に三角形を描画するのみでしたが、任意の場所への描画や回転、拡大・縮小、任意画像の描画などもできます。
• ・・・が、数学(行列)の知識が必要となりますので、次回(?)のハンズオンにできればと思っております。
46