Más contenido relacionado
La actualidad más candente (19)
Similar a Android OpenGL HandsOn (20)
Android OpenGL HandsOn
- 3. OpenGL/ESとは?
• OpenGL Embedded Subsetの略
• 3Dコンピュータグラフィックス用APIのサブ
セットで、3D空間に浮かんだ頂点を結んだ図
形を描画することに特化している。
• 主に携帯電話などの組み込みシステムや、
ゲーム専用機で使われている。
→iOS, Android, Symbian OS,
→PlayStation3、Nintendo 3DS
3
- 4. 描画APIのサポート
Canvas OpenGL/ES
• 点 • 点
• 直線 • 直線
• 三角形 • 三角形
• 四角形
• 五角形以上の多角形
• 円
• 文字
4
- 9. 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
- 10. OpenGL/ESの初期化
@Override
protected void onPause() {
super.onPause();
glSurfaceView.onPause();
}
@Override
protected void onResume() {
super.onResume();
glSurfaceView.onResume();
}
//ここに後でコードを追加します!
}
10
- 11. 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
- 13. コード解説
• GLRenderSampleの各メソッド
メソッド名 呼ばれるタイミング
onSurfaceCreated(GL10 gl, EGLConfig eglconfig) GLSurfaceView用のメモリ確保が終了
onSurfaceChanged(GL10 gl, int width, int height) 画面サイズが変更された時
onDrawFrame(GL10 gl) 再描画が必要な時
13
- 15. コード解説
• 描画範囲の設定
メソッド名 役割
OpenGL/ESの描画範囲を指定する。
glViewport(int x, int y, int width, int height); 「どの座標(x, y)から、幅width、高さheightま
で」を描画範囲とする。
15
- 16. コード解説
• 描画クリア
メソッド名 役割
画面全体を塗りつぶす色を決定する。RGBA(A
glClearColor(float r, float g, float b, float a); はアルファ値)を指定する。
指定できる範囲は0∼1の実数値。
塗りつぶしを実行する。引数に
glClear(int mask);
GL_COLOR_BUFFER_BITを指定する。
• glClearColorの引数の値を適当に変更して、
いろいろな色で塗りつぶされることを確認し
てみてください。
16
- 17. OpenGL/ESの座標系
• 座標系の違い
(480,0)
原点(0,0) (0,1)
(Xperiaの場合) (-1,0) (1,0)
原点(0,0)
View
SurfaceView OpenGL
(0,854) (0,-1)
17
- 19. 三角形を描画する
• 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
- 20. 三角形を描画する
• 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
- 22. コード解説
• 座標の設定
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
- 23. コード解説
• 座標配列を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
- 26. コード解説
• GLSurfaceViewに描画する
メソッド名 役割
glVertexPointer()で転送するメモリ情報の種類
を設定する。引数はいろいろあるが、座標情報
glEnableClientState(int array);
を転送する場合は「GL_VERTEX_ARRAY」を
指定する。
位置情報を設定する。
size : 位置情報の要素数。3次元の場合は3。
glVertexPointer(int size, int type, int stride,
type : 位置情報の変数の型。
Buffer pointer);
stride : 常時0。
pointer : OpenGL/ESに転送可能な位置情報
GLSurfaceViewに描画する。
mode : 描画方法を指定する(後ほど説明)
glDrawArrays(int mode, int first, int count);
first : 描画する位置情報の開始位置。
count : 位置情報を使用する数。
26
- 27. (発展)四角形を描画する
• 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
- 28. (発展)四角形を描画する
• onDrawFrameを修正(続き)
:
:
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fb);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3 * 2);
}
28
- 31. (発展)四角形を描画する
• 重複している座標がある!
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
- 32. (発展)四角形を描画する
• 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
- 33. (発展)四角形を描画する
• 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
- 35. 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
- 36. 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
- 43. 色をつける
• 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
- 45. コード解説
• 描画色を指定する
メソッド名 役割
描画色を決定する。RGBA(Aはアルファ値)を指
glColor4f(float r, float g, float b, float a); 定する。
指定できる範囲は0∼1の実数値。
• glColor4fの引数の値を適当に変更して、いろ
いろな色で塗りつぶされることを確認してみ
てください。
45
- 46. • 本日のハンズオンはここまでです。お疲れ様
でした。
• 今回は、単純に三角形を描画するのみでした
が、任意の場所への描画や回転、拡大・縮
小、任意画像の描画などもできます。
• ・・・が、数学(行列)の知識が必要となります
ので、次回(?)のハンズオンにできればと
思っております。
46