« Androidで作られたゲーム第一号 | トップページ | Androidでゲーム第二弾 ブロック崩し »

AndroidのOpenGL ESでテクスチャ

OpenGL ES系のネタ。せっかくテクスチャも張れるということなので、 ためしに張ってみました。画像読み込み関連はいつものごとくSchlechte Weltさんを参考にしました。

以下サンプルソース

package net.chephes.graphics;

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

import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.os.Bundle;
import android.view.*;
import android.graphics.*;
import android.content.Context;
import android.content.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;


public class Android3D extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        View view = new View3D(this);
        setContentView(view);
    }
}

class View3D extends View{
private float angle = 0;
private OpenGLContext glContext;
    private ByteBuffer  mIndexBuffer;
    private IntBuffer   mVertexBuffer;
    private IntBuffer   mColorBuffer;
    private FloatBuffer mTextureBuffer;
    private int texid;
   
    private boolean isDraw = false;
   
    int one = 0x10000;
    int vertices[] = {
           -one, -one, -one,
            one, -one, -one,
            one,  one, -one,
           -one,  one, -one,
        };
       
    int colors[] = {
              0,    0,    0,  one,
            one,    0,    0,  one,
            one,  one,    0,  one,
              0,  one,    0,  one,
        };
    byte indices[] = {
            0, 1, 2,    2, 3, 0
    };

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

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

    ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
    cbb.order(ByteOrder.nativeOrder());
mColorBuffer = cbb.asIntBuffer();
mColorBuffer.put(colors);
mColorBuffer.position(0);

mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
mIndexBuffer.put(indices);
mIndexBuffer.position(0);
glContext = new OpenGLContext(0);
GL10 gl = (GL10)(glContext.getGL());
        gl.glEnable(gl.GL_TEXTURE_2D);
int a[] = new int[1];
gl.glGenTextures(1, a, 0);
texid = a[0];
gl.glBindTexture(gl.GL_TEXTURE_2D, texid);

Canvas canvas = loadImage(R.drawable.kirby, 128, 128);
a = canvas.getPixels();
ByteBuffer tb = ByteBuffer.allocateDirect(a.length * 4);
tb.order(ByteOrder.nativeOrder());
IntBuffer ib = tb.asIntBuffer();
ib.put(a);
ib.position(0);

gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, 128, 128, 0,
gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, ib);

tb = ByteBuffer.allocateDirect(256);
float b[] = {0, 0,
1, 0,
1, 1,
0, 1};
tb.order(ByteOrder.nativeOrder());
mTextureBuffer = tb.asFloatBuffer();
mTextureBuffer.put(b);
mTextureBuffer.position(0);
isDraw = true;
}

public Canvas loadImage(int fileid, int width, int height) {
Resources r = this.getContext().getResources();
Bitmap bitmap = Bitmap.createBitmap(width, height, true);
Drawable drawable = r.getDrawable(fileid);
Canvas canvas = new Canvas(bitmap);

drawable.setBounds(0, 0, width, height);
drawable.draw(canvas);

return canvas;
}

    @Override
    protected void onDraw(Canvas canvas) {
    if(!isDraw){ return;}

GL10 gl = (GL10)(glContext.getGL());
glContext.waitNative(canvas, this);

gl.glClear(gl.GL_COLOR_BUFFER_BIT);

        gl.glMatrixMode(gl.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glTranslatef(0, 0, -3.0f);
        gl.glScalef(0.8f, 0.8f, 0.8f);
        gl.glRotatef(angle += 1.2f, 1, 1, 0);

        gl.glColor4f(1f, 1f, 1f, 1f);
        gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
        gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY);

    gl.glTexEnvx(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE);

        gl.glDisable(gl.GL_CULL_FACE);

        gl.glTexCoordPointer(2, gl.GL_FLOAT, 0, mTextureBuffer);
        gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
        gl.glDrawElements(gl.GL_TRIANGLES, 6, gl.GL_UNSIGNED_BYTE, mIndexBuffer);
invalidate();
glContext.waitGL();

    }
}

どうやってもテクスチャがはれずに大ハマリしました。とりあえず報告なので、 細かい解説はのちのちやります。リソースは各自適当な物を用意してください。

また、上部にタイトルバーが若干のこってておかしいですが、それの直し方を 知ってる人がいたら、教えてくれると助かります。

11/18追記
requestWindowFeature(Window.FEATURE_NO_TITLE);
でタイトルバー問題は解決。ありがとうs_weltさん

|

« Androidで作られたゲーム第一号 | トップページ | Androidでゲーム第二弾 ブロック崩し »

Android」カテゴリの記事

コメント

タイトルバーですが、onCreate内に次の一文を追加すると消せます。 requestWindowFeature(Window.FEATURE_NO_TITLE);

クールなキャラクタが動くのは良いですね!
3Dを扱うときには参考にさせていただきます。

投稿: s_welt | 2007年11月16日 (金) 23時46分

おー、無事できました。
ありがとうございます。

投稿: chephes | 2007年11月18日 (日) 13時37分

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/486213/8945671

この記事へのトラックバック一覧です: AndroidのOpenGL ESでテクスチャ:

« Androidで作られたゲーム第一号 | トップページ | Androidでゲーム第二弾 ブロック崩し »