Android OpenGLの使い方 | パークのソフトウエア開発者ブログ|ICT技術(Java・Android・iPhone・C・Ruby)なら株式会社パークにお任せください

パークのソフトウエア開発者ブログ|ICT技術(Java・Android・iPhone・C・Ruby)なら株式会社パークにお任せください

開発の解決方法や新しい手法の情報を、パークのエンジニアが提供します。パークのエンジニアが必要な場合は、ぜひお気軽にお問い合わせ下さい。 株式会社パーク:http://www.pa-rk.co.jp/

今回はAndroid端末でOpenGL ESを動かしてみたいと思います。
そもそもOpenGL ESとは何かについてですが、元々はOpenGLという
3Dグラフィックを表示するライブラリを携帯端末など向けの組込みシステムで動かす物です。

さて、実際にどうすれば動くのかを解説してきたいと思います。
まずは前回までの記事を参考にAndroidプロジェクトを作ります。
その後メニューの「ウィンドウ」→「Android Virtual Device Manager」を起動します。

$ソフトウエア開発(android・iphone・windows・java等)の事なら株式会社パークにお任せください_パク太郎のソフトウエア開発者ブログ-AVD起動

そうしたら「Device Definitions」タブをクリックし、真ん中の「Nexus One」を選択し、
「Create AVD...」ボタンを押します。

$ソフトウエア開発(android・iphone・windows・java等)の事なら株式会社パークにお任せください_パク太郎のソフトウエア開発者ブログ-Devece_definitions選択

そうすると以下の様な画面が出るので、Targetを「Android 4.2.2 - API Level 17」に変更し、
CPU/ABIに「ARM(armeabi-v7a)」を選択して下の「OK」を押します。


$ソフトウエア開発(android・iphone・windows・java等)の事なら株式会社パークにお任せください_パク太郎のソフトウエア開発者ブログ-Create_new_AVD

そうしたら「Android Virtual Devices」タブに移動し、右側の真ん中辺りにある「Start...」ボタンを押します。
その後出てくるLaunch Optionsはそのまま「Launch」ボタンを押します。

$ソフトウエア開発(android・iphone・windows・java等)の事なら株式会社パークにお任せください_パク太郎のソフトウエア開発者ブログ-AVD

$ソフトウエア開発(android・iphone・windows・java等)の事なら株式会社パークにお任せください_パク太郎のソフトウエア開発者ブログ-Launch_options

そうするとAndroidのエミュレータが立ち上がります。
デフォルトのままだと言語が英語担っているので、お好みによって日本語に変えてください。
変え方は以下のとおりです

・settingを開く
・Language
・local languageを日本語に

$ソフトウエア開発(android・iphone・windows・java等)の事なら株式会社パークにお任せください_パク太郎のソフトウエア開発者ブログ-Language設定1

ソフトウエア開発(android・iphone・windows・java等)の事なら株式会社パークにお任せください_パク太郎のソフトウエア開発者ブログ-Language設定2

ソフトウエア開発(android・iphone・windows・java等)の事なら株式会社パークにお任せください_パク太郎のソフトウエア開発者ブログ-Language設定3

ソフトウエア開発(android・iphone・windows・java等)の事なら株式会社パークにお任せください_パク太郎のソフトウエア開発者ブログ-Language設定4

ソフトウエア開発(android・iphone・windows・java等)の事なら株式会社パークにお任せください_パク太郎のソフトウエア開発者ブログ-Language設定5

さて、事前準備が長くなりましたがここまでできたら実際にソースを書いていきましょう。
まずは必要なクラスを作ります。
以下の2つのクラスを作成してください。

・MyRenderer
 android.opengl.GLSurfaceView.Renderer(インタフェース)を継承
・MyGLView
 android.opengl.GLSurfaceViewを継承

そうしたら以下のソースを記述します。


package com.example.opengl_test;

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

import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;

public class MyRenderer implements Renderer {
MyCube cube = new MyCube();

@Override
public void onDrawFrame(GL10 arg0) {
// TODO 自動生成されたメソッド・スタブ
// 背景色を設定
arg0.glClearColor(0, 0, 1, 1.0f);
arg0.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

arg0.glMatrixMode(GL10.GL_MODELVIEW);
arg0.glLoadIdentity();
arg0.glTranslatef(0, 0, -3f);

arg0.glRotatef(30f, 0, 1, 0);
arg0.glRotatef(30f, 1, 0, 0);

cube.draw(arg0);
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO 自動生成されたメソッド・スタブ
gl.glViewport(0, 0, width, height);

gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 45f,(float) width / height, 1f, 50f);
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_LIGHTING);
gl.glEnable(GL10.GL_LIGHT0);
gl.glDepthFunc(GL10.GL_LEQUAL);
}

}



package com.example.opengl_test;

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

public class MyGLView extends GLSurfaceView {
private MyRenderer myRenderer;

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

myRenderer = new MyRenderer();
setRenderer(myRenderer);
}
}



package com.example.opengl_test;

import android.os.Bundle;
import android.app.Activity;

public class MainActivity extends Activity {
private MyGLView myGLView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myGLView = new MyGLView(this);
setContentView(myGLView);
}

@Override
protected void onResume(){
super.onResume();
myGLView.onResume();
}

@Override
protected void onPause(){
super.onPause();
myGLView.onPause();
}
}



package com.example.opengl_test;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

public class MyCube {
private final FloatBuffer mVertexBuffer;

public MyCube() {

float vertices[] = {
// 前
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,

// 後
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,

// 左
-0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,

// 右
0.5f, -0.5f, 0.5f,
0.5f, -0.5f, -0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f,

// 上
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,

// 底
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f };

ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asFloatBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);

}

public void draw(GL10 gl) {

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);

// Front
gl.glNormal3f(0, 0, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

// Back
gl.glNormal3f(0, 0, -1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);

// Left
gl.glNormal3f(-1.0f, 0, 0);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);

// Right
gl.glNormal3f(1.0f, 0, 0);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);

// Top
gl.glNormal3f(0, 1.0f, 0);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);

// Right
gl.glNormal3f(0, -1.0f, 0);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);
}
}


それではソースの記入が終わりビルドが終わったら早速実行します。

実行するには「実行」の「実行構成」を選びます。

$ソフトウエア開発(android・iphone・windows・java等)の事なら株式会社パークにお任せください_パク太郎のソフトウエア開発者ブログ-実行構成

そうしたら以下の様な画面が立ち上がりますので、「Android Application」をダブルクリックします。

$ソフトウエア開発(android・iphone・windows・java等)の事なら株式会社パークにお任せください_パク太郎のソフトウエア開発者ブログ-Android実行構成作成1

その後「新規構成」を選択し、右側の「Browse...」を押し今回作成したプロジェクトを選択します。
上記が済んだら下の「適用」を押し「実行」を押します。

$ソフトウエア開発(android・iphone・windows・java等)の事なら株式会社パークにお任せください_パク太郎のソフトウエア開発者ブログ-Android実行構成作成2

実行すると以下の様に四角が画面に表示されると思います。

$ソフトウエア開発(android・iphone・windows・java等)の事なら株式会社パークにお任せください_パク太郎のソフトウエア開発者ブログ-実行

今回は登場しませんでしたが3Dプログラムは行列やベクトルなど、結構複雑な数学の知識が必要になります。
今後そういうものも解説していきたいと思います。

それでは、今回はここまで!