AndroidでOpenGLを使って描画したい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
大白定義
記事: 14
登録日時: 14年前
住所: 三重県

AndroidでOpenGLを使って描画したい

#1

投稿記事 by 大白定義 » 13年前

タイトルのとおり、AndroidでopenGLを使って2Dを表示する処理を作ろうと考えています。

そこで、下記のようなプログラムを組んだのですが、画像が表示されませんでした。
画面は白くなっているので、問題はTextureクラスにあるものだと思っています。
しかし、その中のどれが悪さをしているのかがわかりません。
どのようにすれば良いか教えてください。

使っている端末はRStream A1で、Androidのバージョンは2.3.7です。

GlGameActivityクラス

コード:

package ooshiro.gl.game;

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

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

public class GlGameActivity extends Activity {
    //ビュー
	GlGameView view;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //画面を縦に固定
        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        view = new GlGameView(this);
        setContentView(view);
    }

    //表示するクラス
    private class GlGameView extends GLSurfaceView implements GLSurfaceView.Renderer{
    	//コンテキスト
    	Context context;
    	//試しに描画するテクスチャ
    	Texture tex;
    	//テクスチャID
    	int[] textures;

    	/**
    	 * コンストラクタ
    	 * @param context	テクスチャに画像を読み込ませる為に必要
    	 */
		public GlGameView(Context context) {
			super(context);
			this.setRenderer(this);

			this.context = context;
			this.textures = new int[1];
		}

		@Override
		public void onDrawFrame(GL10 arg0) {
			GL11 gl = (GL11)arg0;

			// 画面を白で塗りつぶし
			gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
			//色バッファを元に戻す
			gl.glClear(GL11.GL_COLOR_BUFFER_BIT);
			//ひとつめの階層に全てを描画
			gl.glPushMatrix();
			//テクスチャ機能を有効にし、描画に使用するテクスチャを指定
			gl.glEnable(GL11.GL_TEXTURE_2D);

			//テクスチャの描画処理
			tex.onDraw(gl, textures, 50, 50);

			//テクスチャ機能を無効に戻す
			gl.glDisable(GL11.GL_TEXTURE_2D);
			//階層を元に戻す
			gl.glPopMatrix();
		}

		@Override
		public void onSurfaceChanged(GL10 arg0, int arg1, int arg2) {
		}

		@Override
		public void onSurfaceCreated(GL10 arg0, EGLConfig arg1) {
			((GL11)arg0).glGenTextures(1, textures, 0);
			tex = new Texture(context, textures, 0, arg0, 1, 1, R.drawable.ic_launcher);
		}

    }
}
Textureクラス

コード:

package ooshiro.gl.game;

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.khronos.opengles.GL;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11Ext;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
import android.util.Log;

public class Texture {
	//テクスチャID配列の番号
	private int ID;
	//分割する数
	private int divX, divY;
	//表示する大きさ
	private int width, height;
	//表示見本
	private int[][][] rect;

	/**
	 * コンストラクタ。
	 * @param context	画像のロードに必要
	 * @param textures	テクスチャID取得に必要
	 * @param id		配列の何番目にあるかを確認するのに必要
	 * @param gl		テクスチャの設定に必要
	 * @param divx		X方向に分割する数を設定するのに必要
	 * @param divy		Y方面に分割する数を設定するのに必要
	 * @param res		表示する画像を取得するのに必要
	 */
	public Texture(Context context, int[] textures, int id, GL gl, int divx, int divy, int res){
		//分割する数が0以下ならエラー
		assert(divx <= 0 || divy <= 0);

		//各データの設定
		ID = id;
		divX = divx;
		divY = divy;
		rect = new int[divX][divY][4];

		//テクスチャを2Dにする
		((GL11) gl).glBindTexture(GL11.GL_TEXTURE_2D, textures[ID]);

        // テクスチャのパラメータ設定
		// 縮小するときピクセルの中心に最も近いテクスチャ要素で補完
        ((GL11) gl).glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
        // 拡大するときピクセルの中心付近の線形で補完
        ((GL11) gl).glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);

        // s座標の1を超える端処理をループにしない
        ((GL11) gl).glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE);
        // t座標の1を超える端処理をループにしない
        ((GL11) gl).glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE);

        // テクスチャとモデルの合成方法の指定(この場合置き換え)
        ((GL11) gl).glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_REPLACE);

        //画像読み込み
		InputStream is = context.getResources().openRawResource(res);
		Bitmap bitmap;
		try{
		    bitmap = BitmapFactory.decodeStream(is);
		    //画像サイズから表示するサイズを設定
		    width = bitmap.getWidth() / divX;
		    height = bitmap.getHeight() / divY;
		}
		finally{
		    try{
		        is.close();
		    }
		    catch(IOException e){
		        // Ignore.
		    }
		}
		//テクスチャと画像を結びつける
		GLUtils.texImage2D(textures[ID], 0, bitmap, 0);
		bitmap.recycle();

		//表示見本の設定
		for(int i=0; i<divY; i++){
			for(int j=0; j<divX; j++){
				rect[j][i][0] = j * width;
				rect[j][i][1] = (i+1) * height;
				rect[j][i][2] = width;
				rect[j][i][3] = -height;
			}
		}
	}

	/**
	 * 分割する場合の描画処理
	 * @param gl		描画するのに必要
	 * @param textures	描画するテクスチャIDを取得するのに必要
	 * @param x			表示するX座標を設定するのに必要
	 * @param y			表示するY座標を設定するのに必要
	 * @param divx		何番目の画像かを決めるのに使う
	 * @param divy		何番目の画像化を決めるのに使う
	 */
	public void onDraw(GL gl, int[] textures, float x, float y, int divx, int divy){
		((GL11)gl).glBindTexture(GL11.GL_TEXTURE_2D, textures[ID]);
		((GL11)gl).glTexParameteriv(textures[ID], GL11Ext.GL_TEXTURE_CROP_RECT_OES, rect[divx][divy], 0);

		((GL11Ext)gl).glDrawTexfOES(x, y, 0, width, height);
	}

	/**
	 * 分割しない場合の描画処理
	 * @param gl		描画するのに必要
	 * @param textures	描画するテクスチャIDを取得するのに必要
	 * @param x			表示するX座標を設定するのに必要
	 * @param y			表示するY座標を設定するのに必要
	 */
	public void onDraw(GL gl, int[] textures, float x, float y){
		((GL11)gl).glBindTexture(GL11.GL_TEXTURE_2D, textures[ID]);
		((GL11)gl).glTexParameteriv(textures[ID], GL11Ext.GL_TEXTURE_CROP_RECT_OES, rect[0][0], 0);

		((GL11Ext)gl).glDrawTexfOES(x, y, 0, width, height);
	}
}

コード:

printf("hoge");
       ↓

コード:

printf("hoge");

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: AndroidでOpenGLを使って描画したい

#2

投稿記事 by ISLe » 13年前

とりあえず、81行目と106行目と120行目のtextures[ID]をGL11.GL_TEXTURE_2Dに変更すれば表示されます。

画像の読み込み部分は

コード:

		BitmapFactory.Options opt = new BitmapFactory.Options();
		opt.inScaled = false;
		Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), res, opt);
のほうが分かりやすいかもしれません。

アバター
大白定義
記事: 14
登録日時: 14年前
住所: 三重県

Re: AndroidでOpenGLを使って描画したい

#3

投稿記事 by 大白定義 » 13年前

言われたとおりに変更してみたところ、シミュレータのほうで表示されたのを確認しました。

ただ、実機では表示されませんでした。
そこで背景色を灰色に変えてみたところ白い四角形だけが表示されていました。
これはテクスチャの画像サイズが2のべき乗でないために表示されないようです。

とはいえ、あとは問題点が分かっているので大丈夫そうです。
ありがとうございました!

コード:

printf("hoge");
       ↓

コード:

printf("hoge");

閉鎖

“C言語何でも質問掲示板” へ戻る