プリミティブな 3D オブジェクトを作ってみる ( Android OpenGL フレームワーク “Rajawali” と戯れる #02 )

2012.04.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Android OpenGL フレームワーク "Rajawali" と戯れるシリーズ
第 02 回目は、プリミティブな 3D オブジェクトを作って動かしてみます。

下準備 ( Rajawali プロジェクトの取得 )

github から最新のソースを取得します。
ここでは、Eclipse の EGit プラグイン ( http://www.eclipse.org/egit/ ) を使用します。

パッケージエクスプローラからインポートを選択します。

[Git] の [Projects from Git] を選択します。

リポジトリのソース種別では [URL] を選択します。

git の URI を入力して [Next] ボタンを押します。

何もせず [Next] ボタンを押します。

任意の場所 ( ワークスペース等 ) にパスを指定します。

何もせず [Next] ボタンを押します。

何もせず [Next] ボタンを押します。

下準備 ( 取得した Rajawali プロジェクトをライブラリとして利用する )

任意の Android プロジェクトを作成します。
( ここでは RajawaliLesson01 とします。 )

作成したプロジェクト設定画面から [Android] メニューを選択して、ビルドターゲットを指定します。
次に、Rajawali を追加するためにダイアログ右端中段下にある [Add] ボタンを押します。

Rajawali が表示されるので選択します。
以上で Rajawali が使用できる状態になりました。

専用の Activity と Renderer の使用

Rajawali には、専用のアクティビティ (RajawaliFragmentActivity) クラスと、OpenGL レンダラ (RajawaliRenderer) クラスが用意されていますので、下記コードのように使用します。

MainActivity.java

package jp.classmethod.sample;
import jp.classmethod.sample.renderer.Lesson01Renderer;
import rajawali.RajawaliFragmentActivity;
import android.os.Bundle;
/**
 * RajawaliFragmentActivity のサブクラス
 */
public class MainActivity extends RajawaliFragmentActivity {
   /**
    * 自前で用意する RajawaliRenderer のサブクラス
    */
    private Lesson01Renderer mRenderer;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mRenderer = new Lesson01Renderer(this);
        
        //レンダラに Rajawali が提供する GLSurfaceView オブジェクトをセット
        mRenderer.setSurfaceView(mSurfaceView);
        
        //アクティビティにレンダラをセット
        setRenderer(mRenderer);
    }

}

Lesson01Renderer.java

package jp.classmethod.sample.renderer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import rajawali.renderer.RajawaliRenderer;
import android.content.Context;
/**
 * RajawaliRenderer のサブクラス
 */
public class Lesson01Renderer extends RajawaliRenderer {
   /**
    * コンストラクタ
    */
    public Lesson01Renderer(Context context) {
        super(context);
    }
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        super.onSurfaceCreated(gl, config);
        
        //ここでプリミティブな 3D オブジェクトを作成
        
        //このメソッドを呼び出すと onDrawFrame() メソッドがフレーム毎に実行される
        startRendering();
    }
    @Override
    public void onDrawFrame(GL10 glUnused) {
        super.onDrawFrame(glUnused);
        //フレーム毎に実行する処理 ( アニメーションなど )
    }
}

プリミティブな 3D オブジェクトの生成 / 表示

作成したレンダラ内の onSurfaceCreated() メソッド内でオブジェクトを作成します。
Rajawali が提供するプリミティブな 3D オブジェクトクラスには、Cube ( 立方体 )、Plane ( 板 )、Sphere ( 球体 ) などが用意されています。

オブジェクトの生成には new を使用し、表示には addChild() メソッドを使用します。( ActionScript に精通している方には馴染みやすいかと思います )

実際に、3D オブジェクトを生成した表示させたコードは下記のようになります。

Lesson01Renderer.java

package jp.classmethod.sample.renderer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import rajawali.materials.SimpleMaterial;
import rajawali.primitives.Cube;
import rajawali.primitives.Plane;
import rajawali.primitives.Sphere;
import rajawali.renderer.RajawaliRenderer;
import android.content.Context;
/**
 * RajawaliRenderer のサブクラス
 */
public class Lesson01Renderer extends RajawaliRenderer {
   /**
    * 立方体
    */
    private Cube mCube;
   /**
    * 球体
    */
    private Sphere mSphere;
   /**
    * 板
    */
    private Plane mPlane;
   /**
    * コンストラクタ
    */
    public Lesson01Renderer(Context context) {
        super(context);
    }
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        super.onSurfaceCreated(gl, config);

        SimpleMaterial material = new SimpleMaterial();
        material.setUseColor(true);

        mCube = new Cube(.5f);
        mCube.setColor(0xff9900);
        mCube.setMaterial(material);
        mCube.setRotX(45);
        mCube.setRotY(45);
        mCube.setX(-.5f);
        mCube.setY(.5f);

        mSphere = new Sphere(.5f, 12, 12);
        mSphere.setColor(0x0099ff);
        mSphere.setMaterial(material);
        mSphere.setX(.5f);
        mSphere.setY(.5f);

        mPlane = new Plane(.7f, .7f, 1, 1);
        mPlane.setColor(0x9900ff);
        mPlane.setMaterial(material);
        mPlane.setY(-.5f);
        //板ポリを両面化
        mPlane.setDoubleSided(true);

        addChild(mCube);
        addChild(mSphere);
        addChild(mPlane);

        startRendering();

    }
    @Override
    public void onDrawFrame(GL10 glUnused) {
        super.onDrawFrame(glUnused);
        mCube.setRotation(mCube.getRotX() + 1, 0, mCube.getRotZ() + 1);
        mSphere.setRotation(mSphere.getRotX() + 1, 0, mSphere.getRotZ() + 1);
        mPlane.setRotation(mPlane.getRotX() + 1, 0, mPlane.getRotZ() + 1);
    }
}

作成した 3D オブジェクトを表示するときには、マテリアル ( 表面材質 ) または、テクスチャを設定する必要があります。
このサンプルでは、Rajawali が提供する SimpleMaterial クラスを使用しました。

出力結果

次回は

マテリアルについて解説します。