3D オブジェクトのマテリアル ( 表面材質 ) のお世話 前編 ( Android OpenGL フレームワーク “Rajawali” と戯れる #03 )

2012.12.05

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

Android OpenGL フレームワーク "Rajawali" と戯れるシリーズ
第 03 回目は、Rajawali が提供しているマテリアル ( 表面材質 ) のクラスについて説明します。

マテリアルのクラス

マテリアルクラスのオブジェクトは、Rajawali の 3D オブジェクトの基底クラスである BaseObject3D クラスの setMaterial() メソッドを使用して設定することがルール決めされています。セットできるマテリアルのクラスは rajawali.materials パッケージにまとめられており、次のようなものが用意されています。

SimpleMaterial

単純な単色マテリアルです。光や影の影響を受けず設定された色で表示されます。

GouraudMaterial

グーローシェーディングのマテリアルです。3D オブジェクトの表面での光と色の変化をシミュレートして表示されます。
詳しい説明はこちら (Wikipedia) を参考にしてください。

PhongMaterial

フォンシェーディングのマテリアルです。
詳しい説明はこちら (Wikipedia) を参考にしてください。

ToonMaterial

トゥーン ( セル ) シェーディングのマテリアルです。
詳しい説明はこちら (Wikipedia) を参考にしてください。

実装例

下準備は前回の内容と同じですが、Rajawali 専用の OpenGL レンダラ (RajawaliRenderer) クラスを使って下記コードのように実装します。

Lesson02Renderer.java

package jp.classmethod.sample.renderer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import rajawali.BaseObject3D; import rajawali.lights.PointLight; import rajawali.materials.GouraudMaterial; import rajawali.materials.PhongMaterial; import rajawali.materials.SimpleMaterial; import rajawali.materials.ToonMaterial; import rajawali.primitives.Cube; import rajawali.renderer.RajawaliRenderer; import android.content.Context; /** * RajawaliRenderer のサブクラス */ public class Lesson02Renderer extends RajawaliRenderer { /** 立方体 ( SimpleMaterial 用 ) */ private Cube mCube0; /** 立方体 ( GouraudMaterial 用 ) */ private Cube mCube1; /** 立方体 ( PhongMaterial 用 ) */ private Cube mCube2; /** 立方体 ( ToonMaterial 用 ) */ private Cube mCube3; /** ライト */ private PointLight mLight; /** * コンストラクタ */ public Lesson02Renderer(Context context) { super(context); }

@Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { super.onSurfaceCreated(gl, config);

mLight = new PointLight(); mLight.setPower(1f); mLight.setPosition(0f, 0f, -.5f);

//シンプルなマテリアル (Simple) SimpleMaterial simpleMaterial = new SimpleMaterial(); simpleMaterial.setUseColor(true); mCube0 = createCube(0.5f, -0.5f, 0.5f, 45, 45); mCube0.setColor(0xff9900); mCube0.setMaterial(simpleMaterial); mCube0.addLight(mLight);

//グーローシェーディング (Gouraud shading) GouraudMaterial gouraud = new GouraudMaterial(); gouraud.setSpecularColor(0xffffff00); //スペキュラ ( 鏡面反射光 ) 色 gouraud.setUseColor(true); mCube1 = createCube(0.5f, 0.5f, 0.5f, 45, 45); mCube1.setMaterial(gouraud); mCube1.addLight(mLight);

//フォンシェーディング (Phong shading) PhongMaterial phong = new PhongMaterial(); phong.setSpecularColor(0xff0000ff); //スペキュラ ( 鏡面反射光 ) 色 phong.setAmbientColor(0xffff0000); //アンビエント ( 環境光 ) 色 phong.setShininess(0.5f); //シャイネス ( スペキュラのサイズ ) phong.setUseColor(true); mCube2 = createCube(0.5f, -0.5f, -0.5f, 45, 45); mCube2.setColor(0xffffff); mCube2.setMaterial(phong); mCube2.addLight(mLight);

//トゥーン ( セル ) シェーディング (Toon(cel) shading) ToonMaterial toon = new ToonMaterial(true); toon.setAmbientColor(0xff0000ff); //アンビエント ( 環境光 ) 色 toon.setUseColor(true); mCube3 = createCube(0.5f, 0.5f, -0.5f, 45, 45); mCube3.setMaterial(toon); mCube3.addLight(mLight);

addChild(mCube0); addChild(mCube1); addChild(mCube2); addChild(mCube3);

startRendering();

} @Override public void onDrawFrame(GL10 glUnused) { super.onDrawFrame(glUnused); rotateObject(mCube0); rotateObject(mCube1); rotateObject(mCube2); rotateObject(mCube3); moveLight(mLight); } /** * Cube オブジェクトの生成 * @param size サイズ * @param lx X 座標 * @param ly Y 座標 * @param rotX X 角度 * @param rotY Y 角度 * @return 生成した Cube オブジェクト */ protected Cube createCube(float size, float lx, float ly, int rotX, int rotY) { Cube cube = new Cube(size); cube.setX(lx); cube.setY(ly); cube.setRotX(rotX); cube.setRotY(rotY); return cube; } /** * 3D オブジェクトの回転 * @param obj 任意の BaseObject3D オブジェクト */ protected void rotateObject(BaseObject3D obj) { obj.setRotation(obj.getRotX() + .1f, 0, obj.getRotZ() + .1f); } /** * ライトの移動量 */ private float lightDx = .01f; /** * ライトの移動 * @param light 任意の PointLight オブジェクト */ protected void moveLight(PointLight light) { float maxX = 1.0f; float minX = -1.0f; float lx = light.getX(); lx += lightDx; if(lx > maxX) { lx = maxX; lightDx *= -1; } else if(lx < minX) { lx = minX; lightDx *= -1; } light.setX(lx); } } [/java]

出力結果

次回

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