OpenGL ES を使ったAndroidゲームの雛形について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
TOMY

OpenGL ES を使ったAndroidゲームの雛形について

#1

投稿記事 by TOMY » 13年前

現在OpenGL ESを使ったAndroidゲームの雛形を作ろうとしていますが。なかなかうまくいきません。
内容といたしましては
・各種クラスごとにファイル分割し、拡張性があるようにしたい(Activity、MyView、 ゲームの処理をさせる各種クラス)
・主な流れとしてはメインループ内にフレームナンバー(ゲームの状態)ごとに生成、描画を分ける
・場合によってはCanvas等と共存させたい(文字の描画を出来れば使いたいので)
今のところといたしましてこれくらいです。

一応Canvasだけを使ったゲームの雛形があるのでこれを拡張してOpenGL ESも対応できるようにしたいです。
プログラムが長くなるかもしれないのでファイルごとに上げます。

TOMY

Re: OpenGL ES を使ったAndroidゲームの雛形について

#2

投稿記事 by TOMY » 13年前

↓以下自作中のOpenGLESゲーム雛形(Activityクラス)(動きませんし、模索しながらのプログラムです。)

コード:

package jp.denpa.tomy.games;

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

//Androidアプリ起動クラス
public class  TouchBoll2Activity extends Activity {

	//描画対象View			(MyViewはGLSurfaceView class を継承している)
	private MyView  myView = null;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);

//		myView = new MyView(this);
//		myView.setRenderer(new MyView(this));		//必ずしもsetRendererはここでやる必要は無いらしい
		setContentView(myView);
	}

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

    //Activity復帰時の処理
    @Override
    protected void onResume(){
    	super.onResume();
    	myView.onResume();
    }
}


TOMY

Re: OpenGL ES を使ったAndroidゲームの雛形について

#3

投稿記事 by TOMY » 13年前

MyViewクラス

コード:

package jp.denpa.tomy.games;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

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


//import jp.denpa.TouchBoll.GameMain;
//import jp.denpa.TouchBoll.MyView;
//import jp.denpa.TouchBoll.Result;
//import jp.denpa.TouchBoll.Start;
//import jp.denpa.TouchBoll.MyView.FlameNo;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

//画面描画クラス
class MyView extends GLSurfaceView {

	//定数	(列挙名が付いている場合は整数固定ではなくクラスみたいな扱いになる【int感覚で使えない】)
	enum Touch{
		TOUCH_CLEAR,	//タッチ クリア
		TOUCH_DOWN,		//タッチ ダウン
		TOUCH_UP,		//タッチ アップ
		TOUCH_MOVE,  	//タッチ ムーブ
		TOUCH_NULL,		//なんの操作もされてない時(画面に触れてない時)
	}

	enum FlameNo{
		START_INIT,
		START_MAIN,
		MENU_INIT,   	//メニュー準備
		MENU_MAIN,   	//メニュー処理
		GAME_INIT,   	//ゲーム準備
		GAME_MAIN,		//ゲーム処理
		RESULT_INIT,	//ゲーム終了時の得点表示
		RESULT_MAIN,	//ゲーム終了時の得点表示
	}

	//グローバル変数
	static SurfaceHolder holder;          //サーフェースオブジェクト
	static Canvas canvas;                 //キャンバスオブジェクト
	static int screenW,screenH;           //スクリーン座標
	static int touchDownX,touchDownY;     //タッチダウン座標
	static int touchUpX,touchUpY;         //タッチアップ座標
	static int touchMoveX,touchMoveY;     //タッチ移動処理
	static int width ,height;             //画面のサイズ
	static Vector2 V2TouchPos = new Vector2(0,0);			  //Vector2型のタッチ座標(アップ、ダウン兼用)

	static Touch touchFlg;                //タッチフラグ
	static FlameNo gameFlg = FlameNo.START_INIT;        //ゲームフラグ
	static Resources resource;            //リソースオブジェクト


	//コンストラクタ
	MyView(Context context){
	  super(context);
	  holder = getHolder();
	  holder.addCallback(this);
	  resource = context.getResources();
	}




	public void exe(){
		MyView.gameFlg=FlameNo.START_INIT;		//戻るでアプリを中断した際にバーチャルでstaticしたゲーム情報が残るので必ず通るここで初期化
	    width = getWidth();
	    height = getHeight();
	    ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();	//マルチスレッド処理
	    ex.scheduleAtFixedRate(new Runnable(){
	    	Start start = new Start();
//	        GameMain game = new GameMain();
//	        Result	result = new Result();
	        public void run(){
	            canvas = holder.lockCanvas();          //描画開始
	            switch(gameFlg){
	                case START_INIT:                     //メニュー初期化
	            	    setRenderer(start);				//setRenderer内でonDrawFrameのみループし続けている?
//	                	start.onSurfaceCreated(gl10, eglconfing);
//	                	start.onSurfaceChanged(gl10, w, h);
//	                	start.onDrawFrame(gl10);
//	                	break;
	                case START_MAIN:                     //メニューメイン
//	                	start.work();
//	                	start.update();
//	                	start.draw(canvas);
	                	break;
	                case GAME_INIT:                     //ゲーム初期化
//	                	game.init(resource);
	                	break;
	                case GAME_MAIN:                     //ゲームメイン
//	                	game.work();
//	                	game.update();
//	                	game.draw(canvas);
	                	break;
	                case RESULT_INIT:
//	                	result.init(resource);
//	                	result.ResultScore=game.Score;
	                	break;
	                case RESULT_MAIN:
//	                	result.update();
//	                	result.draw(canvas);
	                	break;
	            }
	            holder.unlockCanvasAndPost(canvas);    //描画終了
	        }
	    }, 0, 16, TimeUnit.MILLISECONDS);				//16ミリ秒ごとに更新する
	}
	//タッチ処理
	public boolean onTouchEvent(MotionEvent event){
	    if(event.getAction()==MotionEvent.ACTION_DOWN){
	        touchFlg = Touch.TOUCH_DOWN;
	        touchDownX = (int)event.getX();
	        touchDownY = (int)event.getY();
	        V2TouchPos.SetVector2((int)event.getX(),(int)event.getY());
	    }
	    if(event.getAction()  == MotionEvent.ACTION_UP){
	        touchFlg = Touch.TOUCH_UP;
	        touchUpX = (int)event.getX();
	        touchUpY = (int)event.getY();
	        V2TouchPos.SetVector2((int)event.getX(),(int)event.getY());
	    }
	    if(event.getAction()==MotionEvent.ACTION_MOVE){
	        touchFlg = Touch.TOUCH_MOVE;
	        touchMoveX = (int)event.getX();
	        touchMoveY = (int)event.getY();
	        V2TouchPos.SetVector2((int)event.getX(),(int)event.getY());
	    }
	    return true;
	}

}


TOMY

Re: OpenGL ES を使ったAndroidゲームの雛形について

#4

投稿記事 by TOMY » 13年前

(Startクラス)

コード:

package jp.denpa.tomy.games;

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

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


import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;

public class Start implements GLSurfaceView.Renderer{
	private int textureName;


	//サーフェイス作成時の処理
	@Override
	public void onSurfaceCreated(GL10 gl10, EGLConfig eglconfing){
//		Toast.makeText(MyOpenGL_ES_BaseActivity.this,"massage",Toast.LENGTH_LONG).show();
	}

	//画面上のどの領域を使用するかの設定、あとポリゴン色とかの設定
	@Override
	public void onSurfaceChanged(GL10 gl10, int w,int h ){
		gl10.glViewport(0, 0, w, h);
		MyView.screenW = w;
		MyView.screenH= h;

		//テクスチャに関する処理---------------------------------------
		Bitmap bitmap =	BitmapFactory.decodeResource(MyView.resource, R.drawable.image_512);

//        log("bitmap size : " + bitmap.getWidth() + " x " + bitmap.getHeight());
		gl10.glEnable(GL10.GL_TEXTURE_2D);
		int[] buffers = new int[1];
		//texture夜のメモリを指定数確保
		gl10.glGenTextures(1,buffers,0);
		//テクスチャ名を保存する
		textureName = buffers[0];

		gl10.glBindTexture(GL10.GL_TEXTURE_2D, textureName);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

		//拡大縮小時の処理を指定
		gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
		gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);

		//ビットマップを廃棄
		bitmap.recycle();

	}

	private void drawQuad(GL10 gl10, int x, int y, int w, int h){
		float left =((float) x / (float) MyView.screenW)* 2.0f - 1.0f;
		float top  =((float) y / (float) MyView.screenH) * 2.0f - 1.0f;

		float right = left + ((float) w/ (float) MyView.screenW) * 2.0f;
		float bottom =top + ((float) h / (float) MyView.screenH) * 2.0f;

		//上下を反転させる
		top = -top;
		bottom = -bottom;

		//位置情報テスト----------------------------------
		float positions[] = {			//x,y,zの順に定義
				left,top,0,					//左上
				left,bottom,0,					//左下
				right,bottom,0,					//右上
				right,top,0,
		};

		//OpenGLはビッグエンディアンではなく
		//CPUごとの”ネイティブエンディアン”で数値を伝える必要がある。
		//その為Javaヒープを直接的には扱えず、
		//”Java.nio”配下のクラスへ一度値を格納する必要がある。(面倒くせぇ)
		ByteBuffer bb=ByteBuffer.allocateDirect(positions.length * 4);  //GL_ESが扱えるのはallocateDirectで確保した領域のみ
		bb.order(ByteOrder.nativeOrder());		//実行環境に合わせて最適な値を指定できるようにnativeOrderを使う
		FloatBuffer fb = bb.asFloatBuffer();	//確保したバッファをfloatに格納(新たにメモリを確保しているわけではない)
		fb.put(positions);						//バッファをfloat配列に転送(この時点でエンディアンに関する変換はもう終わっている)
		fb.position(0);							//putすると書き込み位置が一つ進められるのでpositionで最初に戻す

		gl10.glEnableClientState(GL10.GL_VERTEX_ARRAY);	//頂点バッファの成分を切り替えている(ここでは有効化)
		gl10.glVertexPointer(3,GL10.GL_FLOAT,0,fb);		//OpenGL ESに頂点バッファを関連付ける(コピーではないことに注意)
		gl10.glDrawArrays(GL10.GL_TRIANGLE_FAN,0,4);	//描画
		//end---------------------------------------------

	}

	//毎フレーム描画処理
	@Override
	public void onDrawFrame(GL10 gl10){

		//背景塗りつぶし----------------------------------
		gl10.glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
		gl10.glClear(GL10.GL_COLOR_BUFFER_BIT);
		//end---------------------------------------------

		//テクスチャ全体のUV座標を指定(TRIANGLE_FANでの描画のためUV座標が変わることをすっかり忘れてた)
		{
			float uv[]={
					//uv
					1,0,
					1,1,
					0,1,
					0,0,

			};

			ByteBuffer bb = ByteBuffer.allocateDirect(uv.length * 4);
			bb.order(ByteOrder.nativeOrder());
			FloatBuffer fb = bb.asFloatBuffer();
			fb.put(uv);
			fb.position(0);

			gl10.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
			gl10.glTexCoordPointer(2, GL10.GL_FLOAT, 0, fb);
		}
		//end------------------------------------------------------------------------------------------
		gl10.glColor4f(1.0f, 1, 1, 1.0f);
		drawQuad(gl10, 0,0,512,512);

//		gl10.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
//		drawQuad(gl10, screenWidth /2,  screenHeight /2, 800, 100);


	}

}


TOMY

Re: OpenGL ES を使ったAndroidゲームの雛形について

#5

投稿記事 by TOMY » 13年前

記述忘れましたが、ゲームの処理(Startクラス内)では


・Initメソッド    (各種初期設定)
・Workメソッド  (座標の更新処理)
・Updateメソッド (座標以外の更新処理 操作時の処理もここで)
・Drawメソッド   (描画処理)

を出来るようにしたいです。

また、同じような形で Gameクラス、 Resultクラス
というふうにしたいです。

初めてのOpenGLを読んで見たり、ネットで調べてみたりしてはいますが、いかんせんそんな都合のいいサイトやサンプルプログラム
がないのでここに頼らせていただくことにしました。

後、以下はCanvasを用いたゲームプログラムの雛形(MyViewクラスのみ)です。
Start、Game、Resultクラスは上記に記したようにInit、Work、Uodate、Drawメソッドに分けてあります。

コード:

package jp.denpa.TouchBoll;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

//画面描画クラス
class MyView extends SurfaceView implements SurfaceHolder.Callback{

	//定数	(列挙名が付いている場合は整数固定ではなくクラスみたいな扱いになる【int感覚で使えない】)
	enum Touch{
		TOUCH_CLEAR,	//タッチ クリア
		TOUCH_DOWN,		//タッチ ダウン
		TOUCH_UP,		//タッチ アップ
		TOUCH_MOVE,  	//タッチ ムーブ
		TOUCH_NULL,		//なんの操作もされてない時(画面に触れてない時)
	}

	enum FlameNo{
		START_INIT,
		START_MAIN,
		MENU_INIT,   	//メニュー準備
		MENU_MAIN,   	//メニュー処理
		GAME_INIT,   	//ゲーム準備
		GAME_MAIN,		//ゲーム処理
		RESULT_INIT,	//ゲーム終了時の得点表示
		RESULT_MAIN,	//ゲーム終了時の得点表示
	}

	//グローバル変数
	static SurfaceHolder holder;          //サーフェースオブジェクト
	static Canvas canvas;                 //キャンバスオブジェクト
	static int screenW,screenH;           //スクリーン座標
	static int touchDownX,touchDownY;     //タッチダウン座標
	static int touchUpX,touchUpY;         //タッチアップ座標
	static int touchMoveX,touchMoveY;     //タッチ移動処理
	static int width ,height;             //画面のサイズ
	static Vector2 V2TouchPos = new Vector2(0,0);			  //Vector2型のタッチ座標(アップ、ダウン兼用)

	static Touch touchFlg;                //タッチフラグ
	static FlameNo gameFlg = FlameNo.START_INIT;        //ゲームフラグ
	static Resources resource;            //リソースオブジェクト

	//コンストラクタ
	MyView(Context context){
	  super(context);
	  holder = getHolder();
	  holder.addCallback(this);
	  resource = context.getResources();
	}

	public void surfaceCreated(SurfaceHolder holder){exe();}
	public void surfaceChanged(SurfaceHolder holder,int format,int w,int h){}
	public void surfaceDestroyed(SurfaceHolder holder){}

	//メインループ(戻るボタン押した時にメインループ内の変数を解放する処理を入れないと変数保持されてバグる)
	//(戻るボタン時の変数解放処理はすべてのモード内でしないといけない?かも。)
	public void exe(){
		MyView.gameFlg=FlameNo.START_INIT;		//戻るでアプリを中断した際にバーチャルでstaticしたゲーム情報が残るので必ず通るここで初期化
	    width = getWidth();
	    height = getHeight();
	    ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
	    ex.scheduleAtFixedRate(new Runnable(){
	        Start start = new Start();
	        GameMain game = new GameMain();
	        Result	result = new Result();
	        public void run(){
	            canvas = holder.lockCanvas();          //描画開始
	            switch(gameFlg){
	                case START_INIT:                     //メニュー初期化
	                	start.init(resource);
	                	break;
	                case START_MAIN:                     //メニューメイン
	                	start.work();
	                	start.update();
	                	start.draw(canvas);
	                	break;
	                case GAME_INIT:                     //ゲーム初期化
	                	game.init(resource);
	                	break;
	                case GAME_MAIN:                     //ゲームメイン
	                	game.work();
	                	game.update();
	                	game.draw(canvas);
	                	break;
	                case RESULT_INIT:
	                	result.init(resource);
	                	result.ResultScore=game.Score;
	                	break;
	                case RESULT_MAIN:
	                	result.update();
	                	result.draw(canvas);
	                	break;
	            }
	            holder.unlockCanvasAndPost(canvas);    //描画終了
	        }
	    }, 0, 16, TimeUnit.MILLISECONDS);
	}

	//タッチ処理
	public boolean onTouchEvent(MotionEvent event){
	    if(event.getAction()==MotionEvent.ACTION_DOWN){
	        touchFlg = Touch.TOUCH_DOWN;
	        touchDownX = (int)event.getX();
	        touchDownY = (int)event.getY();
	        V2TouchPos.SetVector2((int)event.getX(),(int)event.getY());
	    }
	    if(event.getAction()  == MotionEvent.ACTION_UP){
	        touchFlg = Touch.TOUCH_UP;
	        touchUpX = (int)event.getX();
	        touchUpY = (int)event.getY();
	        V2TouchPos.SetVector2((int)event.getX(),(int)event.getY());
	    }
	    if(event.getAction()==MotionEvent.ACTION_MOVE){
	        touchFlg = Touch.TOUCH_MOVE;
	        touchMoveX = (int)event.getX();
	        touchMoveY = (int)event.getY();
	        V2TouchPos.SetVector2((int)event.getX(),(int)event.getY());
	    }
	    return true;
	}

}


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

Re: OpenGL ES を使ったAndroidゲームの雛形について

#6

投稿記事 by ISLe » 13年前

TOMY さんが書きました:記述忘れましたが、ゲームの処理(Startクラス内)では

・Initメソッド    (各種初期設定)
・Workメソッド  (座標の更新処理)
・Updateメソッド (座標以外の更新処理 操作時の処理もここで)
・Drawメソッド   (描画処理)

を出来るようにしたいです。

また、同じような形で Gameクラス、 Resultクラス
というふうにしたいです。
とりあえず、上記の点については、Javaのインターフェイスという機能をご存知ないのでしょうか?

アバター
Dixq (管理人)
管理人
記事: 1662
登録日時: 14年前
住所: 北海道札幌市
連絡を取る:

Re: OpenGL ES を使ったAndroidゲームの雛形について

#7

投稿記事 by Dixq (管理人) » 13年前

ひな形を作りたいんですよね?
であれば、メインループにあたる部分にあのように書かれるのはおかしくないでしょうか?
ゲーム作りを楽にしたいなら、まずOpenGL ESをラッピングしたライブラリ的なものを先に作りそれを利用してはどうでしょう。
メインループには何も書かずに、
gl.clearScreen(); のような呼び出しで消せるように作っておき、
その他のメインループの記述はゲームの実質的な処理を書いていくべきなのではないでしょうか。
いちいちuv座標云々を全て考慮しないと作れないような状態だとゲーム制作がはかどらないと思います。

アバター
TOMY
記事: 53
登録日時: 13年前
住所: 愛知県
連絡を取る:

Re: OpenGL ES を使ったAndroidゲームの雛形について

#8

投稿記事 by TOMY » 13年前

[quote="ISLeとりあえず、上記の点については、Javaのインターフェイスという機能をご存知ないのでしょうか?[/quote]

↑上記の点につきましては私はまだJava知識が浅いため、知りませんでした。調べた限りでは継承すること前提のクラスと捉えていいでしょうか?
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。

アバター
TOMY
記事: 53
登録日時: 13年前
住所: 愛知県
連絡を取る:

Re: OpenGL ES を使ったAndroidゲームの雛形について

#9

投稿記事 by TOMY » 13年前

Dixq (管理人) さんが書きました:ひな形を作りたいんですよね?
であれば、メインループにあたる部分にあのように書かれるのはおかしくないでしょうか?
ゲーム作りを楽にしたいなら、まずOpenGL ESをラッピングしたライブラリ的なものを先に作りそれを利用してはどうでしょう。
メインループには何も書かずに、
gl.clearScreen(); のような呼び出しで消せるように作っておき、
その他のメインループの記述はゲームの実質的な処理を書いていくべきなのではないでしょうか。
いちいちuv座標云々を全て考慮しないと作れないような状態だとゲーム制作がはかどらないと思います。

uv座標など、OpenGLやDirectX等のCG座標系などについては粗方わかっているので雛形として最低限の実装をしたら、各種処理を使いやすくしたクラスを作ろうとはしています。

ラッピングについてはjava知識が浅いため知りませんでしたので調べて見ました。(おそらく)使いやすいように自分流のクラスを作るということで合っていますかね?
C++だとプログラムは大体理解できるし、DirectXを用いたPCゲームの雛形は作れるのですがいかんせん、殆ど触ったことのないjavaなので、たまに詰まったときは先生や本に聞いていはいますが、予めjavaの機能を生かしたプログラミングは苦手です。
そんな中で制作していますので自分はjava知識的に足りないところが多いと思います。

あえて今まで書きませんでしたがこれは学校の課題の延長線上にあるものなので完成させなければなりません。
(課題はAndroidゲーム作成)
先ほど記述した通りjava知識は浅く残念なものですが出来上がるまで付き合ってもらえませんでしょうか?


後、mixCに登録させていただきましたそこで私のプログラミング能力について詳細に書いてあります。
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。

アバター
TOMY
記事: 53
登録日時: 13年前
住所: 愛知県
連絡を取る:

Re: OpenGL ES を使ったAndroidゲームの雛形について

#10

投稿記事 by TOMY » 13年前

現在の進行状況。
たまたまあるサイトでOpenGL ESのラッパーライブラリのサンプルがあったのでそれを参考に何とか動くプログラムを組むことができました。以下まだまだ粗いですが自作のゲーム雛形です。(途中。でも一応ちゃんと動きます)

(Activity)

コード:

package jp.denpa.tomy.games;


import jp.denpa.tomy.opengl_es.wrap.MainRenderer;
import android.app.Activity;
import android.os.Bundle;
import android.view.*;

//Androidアプリ起動クラス
public class  TouchBoll2Activity extends Activity {

	//描画対象View			(MyViewはGLSurfaceView class を継承している)
	private MyView  myView;
	private MainRenderer myRenderer;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);

		myView = new MyView(this);
		myRenderer = new MainRenderer(this);
		myView.setRenderer(myRenderer);		//必ずしもsetRendererはここでやる必要は無いらしい
		setContentView(myView);
	}

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

    //Activity復帰時の処理
    @Override
    protected void onResume(){
    	super.onResume();
    	myView.onResume();
    }
}
(MyView)

コード:

package jp.denpa.tomy.games;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

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


//import jp.denpa.TouchBoll.GameMain;
//import jp.denpa.TouchBoll.MyView;
//import jp.denpa.TouchBoll.Result;
//import jp.denpa.TouchBoll.Start;
//import jp.denpa.TouchBoll.MyView.FlameNo;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

//画面描画クラス
public class MyView extends GLSurfaceView {

	//定数	(列挙名が付いている場合は整数固定ではなくクラスみたいな扱いになる【int感覚で使えない】)
	enum Touch{
		TOUCH_CLEAR,	//タッチ クリア
		TOUCH_DOWN,		//タッチ ダウン
		TOUCH_UP,		//タッチ アップ
		TOUCH_MOVE,  	//タッチ ムーブ
		TOUCH_NULL,		//なんの操作もされてない時(画面に触れてない時)
	}

	//グローバル変数
	public static SurfaceHolder holder;          //サーフェースオブジェクト
	public static Canvas canvas;                 //キャンバスオブジェクト

	public static int touchDownX,touchDownY;     //タッチダウン座標
	public static int touchUpX,touchUpY;         //タッチアップ座標
	public static int touchMoveX,touchMoveY;     //タッチ移動処理
	public static Vector2 V2TouchPos = new Vector2(0,0);		//Vector2型のタッチ座標(アップ、ダウン兼用)

	public static Touch touchFlg;            					//タッチフラグ

//	static Resources resource;       					//リソースオブジェクト


	//コンストラクタ
	MyView(Context context){
	  super(context);
	  holder = getHolder();
	  holder.addCallback(this);
//	  resource = context.getResources();
	}




//	public void exe(){
//		MyView.gameFlg=FlameNo.START_INIT;		//戻るでアプリを中断した際にバーチャルでstaticしたゲーム情報が残るので必ず通るここで初期化
//	    width = getWidth();
//	    height = getHeight();
//	    ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();	//マルチスレッド処理
//	    ex.scheduleAtFixedRate(new Runnable(){
//	    	Start start = new Start();
//	        public void run(){
//	            canvas = holder.lockCanvas();          //描画開始
//	            switch(gameFlg){
///	                case START_INIT:                     //メニュー初期化
//	            	    break;
//	                case START_MAIN:                     //メニューメイン
//	                	break;
//	                case GAME_INIT:                     //ゲーム初期化
//	                	break;
//	                case GAME_MAIN:                     //ゲームメイン
//	                	break;
//	                case RESULT_INIT:
//	                	break;
//	                case RESULT_MAIN:
//	                	break;
//	            }
//	            holder.unlockCanvasAndPost(canvas);    //描画終了
//	        }
//	    }, 0, 16, TimeUnit.MILLISECONDS);				//16ミリ秒ごとに更新する
//	}
	//タッチ処理
	public boolean onTouchEvent(MotionEvent event){
	    if(event.getAction()==MotionEvent.ACTION_DOWN){
	        touchFlg = Touch.TOUCH_DOWN;
	        touchDownX = (int)event.getX();
	        touchDownY = (int)event.getY();
	        V2TouchPos.SetVector2((int)event.getX(),(int)event.getY());
	    }
	    if(event.getAction()  == MotionEvent.ACTION_UP){
	        touchFlg = Touch.TOUCH_UP;
	        touchUpX = (int)event.getX();
	        touchUpY = (int)event.getY();
	        V2TouchPos.SetVector2((int)event.getX(),(int)event.getY());
	    }
	    if(event.getAction()==MotionEvent.ACTION_MOVE){
	        touchFlg = Touch.TOUCH_MOVE;
	        touchMoveX = (int)event.getX();
	        touchMoveY = (int)event.getY();
	        V2TouchPos.SetVector2((int)event.getX(),(int)event.getY());
	    }
	    return true;
	}

}
(MainRenderer) //ゲームのメインループ処理をさせている場所(新しく追加)

コード:

package jp.denpa.tomy.opengl_es.wrap;


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

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;

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

import jp.denpa.tomy.games.MyView;
import jp.denpa.tomy.games.R;


//OpenGL の Rendererに関するクラス メインループもここでする(←?)

public class MainRenderer implements GLSurfaceView.Renderer{

	//定数	(列挙名が付いている場合は整数固定ではなくクラスみたいな扱いになる【int感覚で使えない】)
	enum Touch{
		TOUCH_CLEAR,	//タッチ クリア
		TOUCH_DOWN,		//タッチ ダウン
		TOUCH_UP,		//タッチ アップ
		TOUCH_MOVE,  	//タッチ ムーブ
		TOUCH_NULL,		//なんの操作もされてない時(画面に触れてない時)
	}

	enum FlameNo{
		START_INIT,
		START_MAIN,
		MENU_INIT,   	//メニュー準備
		MENU_MAIN,   	//メニュー処理
		GAME_INIT,   	//ゲーム準備
		GAME_MAIN,		//ゲーム処理
		RESULT_INIT,	//ゲーム終了時の得点表示
		RESULT_MAIN,	//ゲーム終了時の得点表示
	}

	
	private Context context;
	
	
	static FlameNo gameFlg = FlameNo.START_INIT;        //ゲームフラグ
	
	static int screenW;           //スクリーン座標
	static int screenH;




	public  MainRenderer(Context ctext){

		context=ctext;
	}

	private int textureName;


	//サーフェイス作成時の処理(サーフェイスが生成される際・または再生成される際に呼ばれる)
	@Override
	public void onSurfaceCreated(GL10 gl10, EGLConfig eglconfing){
		//⑦背景色
		gl10.glClearColor(1.0f,1.0f,1.0f,1.0f);
	    // ディザを無効化
	    gl10.glDisable(GL10.GL_DITHER);
	    // 深度テストを有効に
	    gl10.glEnable(GL10.GL_DEPTH_TEST);
	 	//テクスチャ機能ON
	  	gl10.glEnable(GL10.GL_TEXTURE_2D);
	    //透明可能に
	  	gl10.glEnable(GL10.GL_ALPHA_TEST);
	   	//ブレンド可能に
	   	gl10.glEnable(GL10.GL_BLEND);
	  	//色のブレンド方法
	  	gl10.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE_MINUS_SRC_ALPHA);
	}

	//画面上のどの領域を使用するかの設定、あとポリゴン色とかの設定(サーフェイスのサイズ変更時に呼ばれる)
	@Override
	public void onSurfaceChanged(GL10 gl10, int w,int h ){
		gl10.glViewport(0, 0, w, h);
		screenW = w;
		screenH = h;

		//テクスチャに関する処理---------------------------------------
		Bitmap bitmap =	BitmapFactory.decodeResource(context.getResources(), R.drawable.image_512);

//        log("bitmap size : " + bitmap.getWidth() + " x " + bitmap.getHeight());
		gl10.glEnable(GL10.GL_TEXTURE_2D);
		int[] buffers = new int[1];
		//texture夜のメモリを指定数確保
		gl10.glGenTextures(1,buffers,0);
		//テクスチャ名を保存する
		textureName = buffers[0];

		gl10.glBindTexture(GL10.GL_TEXTURE_2D, textureName);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

		//拡大縮小時の処理を指定
		gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
		gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);

		//ビットマップを廃棄
		bitmap.recycle();

	}

	private void drawQuad(GL10 gl10, int x, int y, int w, int h){
		float left =((float) x / (float) screenW)* 2.0f - 1.0f;
		float top  =((float) y / (float) screenH) * 2.0f - 1.0f;

		float right = left + ((float) w/ (float) screenW) * 2.0f;
		float bottom =top + ((float) h / (float) screenH) * 2.0f;

		//上下を反転させる
		top = -top;
		bottom = -bottom;

		//位置情報テスト----------------------------------
		float positions[] = {			//x,y,zの順に定義
				left,top,0,					//左上
				left,bottom,0,					//左下
				right,bottom,0,					//右上
				right,top,0,
		};

		//OpenGLはビッグエンディアンではなく
		//CPUごとの”ネイティブエンディアン”で数値を伝える必要がある。
		//その為Javaヒープを直接的には扱えず、
		//”Java.nio”配下のクラスへ一度値を格納する必要がある。(面倒くせぇ)
		ByteBuffer bb=ByteBuffer.allocateDirect(positions.length * 4);  //GL_ESが扱えるのはallocateDirectで確保した領域のみ
		bb.order(ByteOrder.nativeOrder());		//実行環境に合わせて最適な値を指定できるようにnativeOrderを使う
		FloatBuffer fb = bb.asFloatBuffer();	//確保したバッファをfloatに格納(新たにメモリを確保しているわけではない)
		fb.put(positions);						//バッファをfloat配列に転送(この時点でエンディアンに関する変換はもう終わっている)
		fb.position(0);							//putすると書き込み位置が一つ進められるのでpositionで最初に戻す

		gl10.glEnableClientState(GL10.GL_VERTEX_ARRAY);	//頂点バッファの成分を切り替えている(ここでは有効化)
		gl10.glVertexPointer(3,GL10.GL_FLOAT,0,fb);		//OpenGL ESに頂点バッファを関連付ける(コピーではないことに注意)
		gl10.glDrawArrays(GL10.GL_TRIANGLE_FAN,0,4);	//描画
		//end---------------------------------------------

	}

	//毎フレーム描画処理
	@Override
	public void onDrawFrame(GL10 gl10){

		//背景塗りつぶし----------------------------------
		gl10.glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
		gl10.glClear(GL10.GL_COLOR_BUFFER_BIT);
		//end---------------------------------------------

		//テクスチャ全体のUV座標を指定(TRIANGLE_FANでの描画のためUV座標が変わることをすっかり忘れてた)
		{
			float uv[]={
					//uv
					1,0,
					1,1,
					0,1,
					0,0,

			};

			ByteBuffer bb = ByteBuffer.allocateDirect(uv.length * 4);
			bb.order(ByteOrder.nativeOrder());
			FloatBuffer fb = bb.asFloatBuffer();
			fb.put(uv);
			fb.position(0);

			gl10.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
			gl10.glTexCoordPointer(2, GL10.GL_FLOAT, 0, fb);
		}
		//end------------------------------------------------------------------------------------------
		gl10.glColor4f(1.0f, 1, 1, 1.0f);
		drawQuad(gl10, 0,0,512,512);

//		gl10.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
//		drawQuad(gl10, screenWidth /2,  screenHeight /2, 800, 100);


	}
	
	

}

一応一つ問題は解決しましたが、まだ納得の行くゲーム雛形が完成していませんので解決にチェックはまだかけないでおきます
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。

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

Re: OpenGL ES を使ったAndroidゲームの雛形について

#11

投稿記事 by ISLe » 13年前

TOMY さんが書きました:
ISLe さんが書きました:とりあえず、上記の点については、Javaのインターフェイスという機能をご存知ないのでしょうか?
↑上記の点につきましては私はまだJava知識が浅いため、知りませんでした。調べた限りでは継承すること前提のクラスと捉えていいでしょうか?
C++はだいたい理解できるとおっしゃっていますが、(純粋)仮想関数を使ったインターフェイスの設計手法はご存じないですか?

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

Re: OpenGL ES を使ったAndroidゲームの雛形について

#12

投稿記事 by ISLe » 13年前

インターフェイスは文法的にはこんな感じのものです。

コード:

// インターフェイス
interface Task {
	public void Init();
	public void Work();
	public void Update();
	public void Draw();
}
// インターフェイスを継承して各メソッドを独自に実装
class Start implements Task {
	@Override
	public void Init() { }
	@Override
	public void Work() { }
	@Override
	public void Update() { }
	@Override
	public void Draw() { }
}
// インターフェイスを継承して各メソッドを独自に実装
class Game implements Task {
	@Override
	public void Init() { }
	@Override
	public void Work() { }
	@Override
	public void Update() { }
	@Override
	public void Draw() { }
}
// インターフェイスを継承して各メソッドを独自に実装
class Result implements Task {
	@Override
	public void Init() { }
	@Override
	public void Work() { }
	@Override
	public void Update() { }
	@Override
	public void Draw() { }
}

// 呼び出し部分のサンプル
final int START  = 0;
final int GAME   = 1;
final int RESULT = 2;
Task[] tasks = new Task[3];
tasks[START]  = new Start();
tasks[GAME]   = new Game();
tasks[RESULT] = new Result();
int state = START;
// インターフェイスで統一した呼び出しが可能
tasks[state].Work();
tasks[state].Update();
tasks[state].Draw();
配列よりはコンテナで管理するほうが良いと思います。
ライフサイクルが外部依存しなくなるので、クラスが増える度にswitchのcaseも増やすような手間はかかりません。

こちらのサイトの『Androidの館』にはクラスを継承した方法の解説があります。
インターフェイスではないですがやってることは同じです。

アバター
TOMY
記事: 53
登録日時: 13年前
住所: 愛知県
連絡を取る:

Re: OpenGL ES を使ったAndroidゲームの雛形について

#13

投稿記事 by TOMY » 13年前

ISLe さんが書きました:C++はだいたい理解できるとおっしゃっていますが、(純粋)仮想関数を使ったインターフェイスの設計手法はご存じないですか?
この質問につきましては仮想関数や純粋仮想関数などについてはわかっていましたが、それを生かしての設計手法、というものがまだまだ未熟な為知りませんでした。
というか、設計手法が多分自分にとって一番ネックなのだと思います。現に学校でもそこを何度か指摘されたことがあるので。様々な書籍で勉強してみたりしているのですが、
やはり実際に設計をして組むという経験が少ないのは痛いのかもしれません。(今まで何度か試して入るのですが結局少し滅茶苦茶なプログラムになったりします。)
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。

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

Re: OpenGL ES を使ったAndroidゲームの雛形について

#14

投稿記事 by ISLe » 13年前

TOMY さんが書きました:というか、設計手法が多分自分にとって一番ネックなのだと思います。現に学校でもそこを何度か指摘されたことがあるので。様々な書籍で勉強してみたりしているのですが、
やはり実際に設計をして組むという経験が少ないのは痛いのかもしれません。(今まで何度か試して入るのですが結局少し滅茶苦茶なプログラムになったりします。)
設計をしてから組むという経験は必要無いです。
自分の書いたコードを、書いた端から改良していけば良いのです。

ゲームの雛形というと、ソースファイルをコピーして、そこにアプリ独自のコードを書き込んでいくのをイメージするかもしれません。
ですが、それはソースファイル全体をコピペしているのと同じですから、既存のソースファイルに一切手を加えず再利用するほうが効率は良いです。
コピペはすればするほど時間を無駄にします。

ちなみにわたしは完全な独学です。
ネットの情報だけで十分勉強できますよ。

アバター
TOMY
記事: 53
登録日時: 13年前
住所: 愛知県
連絡を取る:

Re: OpenGL ES を使ったAndroidゲームの雛形について

#15

投稿記事 by TOMY » 13年前

ふぅむ・・・参考になるなぁ。
自分の勉強不足が露骨の露呈する・・・
interfaceなんて微塵にも思いつかなかった・・・
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。

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

Re: OpenGL ES を使ったAndroidゲームの雛形について

#16

投稿記事 by ISLe » 13年前

TOMY さんが書きました:自分の勉強不足が露骨の露呈する・・・
interfaceなんて微塵にも思いつかなかった・・・
いわゆるインターフェイスは言語に依らない概念です。
interfaceを知っているから使うのではなく、Javaでこういう実装をするにはどうしたら良いかと調べることでinterfaceに行き着くわけです。

事前にそういう知識がまったく無くても、既存の仕組みを真似するだけでも得られるものがたくさんあります。
AndroidにはActivityのライフサイクルとイベントメソッドの仕組みがあり、Viewにも同じようにコールバック用のメソッドがあります。
Viewの仕組みあたりはTOMYさんがやりたいことそのものじゃないかと思いますけどね。

アバター
TOMY
記事: 53
登録日時: 13年前
住所: 愛知県
連絡を取る:

ポリゴンの生成やテクスチャの貼り付けを簡単にする為のclassを作る

#17

投稿記事 by TOMY » 13年前

大まかなメインループ処理ができたので次はポリゴンの生成や、貼り付けなどを簡単に行うためのclassを現在制作しております。
ですが、中々できず制作が停滞してしまいました。

求める機能としては
・中心座標、サイズを元にポリゴンの生成
・関数群は Init(各種初期化)、SetPos(座標更新処理の確定)、SetUV(任意のUV座標指定)、SetColor(ポリゴンカラーの任意変更)、Draw(描画)です。
・UVの指定と、ポリゴンカラーの設定はしていない場合Init内で予め決められた処理を行う。
・Drawメソッドではテクスチャ情報を渡すとテクスチャがはられたポリゴンが描画される。そうでない場合はテクスチャがはられていないポリゴンが描画される。

製作途中データ(GL2DVertexクラス) プロジェクトの方もzipファイルで上げます

コード:

//ポリゴンの生成、更新、描画を簡単にさせるためのクラス

package jp.denpa.tomy.opengl_es.wrap;

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

import javax.microedition.khronos.opengles.GL10;



public class GL2DVertex {

	public Vector2 center;			//中心座標
	public Vector2 size;			//ポリゴンサイズ
	public float   rad;				//回転角度

	private GL10   gl10;
	private float a,r,g,b;

	public void Init(GL10 gl){		//初期化
		//色の初期設定
		a=1.0f;
		r=1.0f;
		g=1.0f;
		b=1.0f;
		gl10=gl;
		float uv[] = {
				1,0,		//左上
				1,1,		//右上
				0,1,		//右下
				0,0,		//左下
		};
		ByteBuffer bb = ByteBuffer.allocateDirect(uv.length * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer fb = bb.asFloatBuffer();
		fb.put(uv);
		fb.position(0);

		gl10.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		gl10.glTexCoordPointer(2, GL10.GL_FLOAT, 0, fb);
	}

	public void SetUV(int cx,int cy,int nx,int ny,boolean turn){		//UV座標セット
		float w = 1.0f/cx;
		float h = 1.0f/cy;

		float left	= w * nx;
		float top	= h * ny;
		float right	= w * (nx+1);
		float bottom= h * (ny+1);

		if(turn){			//反転フラグがtrueの時の処理
			float tu=right;
			right=left;
			left=tu;
		}
		float uv[] = {			//UV座標
			left,top,			//左上
			right,top,			//右上
			right,bottom,		//右下
			left,bottom,		//左下
		};

		ByteBuffer bb = ByteBuffer.allocateDirect(uv.length * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer fb = bb.asFloatBuffer();
		fb.put(uv);
		fb.position(0);

		gl10.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		gl10.glTexCoordPointer(2, GL10.GL_FLOAT, 0, fb);
	}

	public void SetColor(float A,float R,float G,float B){		//色の設定
		a=A;r=R;g=G;b=B;
	}

	public void SetPos(){		//座標の更新(確定)
		float left = ((float) center.x / (float) MainRenderer.screenW) * 2.0f - 1.0f;
		float top  = ((float) center.y / (float) MainRenderer.screenH) * 2.0f - 1.0f;

		float right = left + ((float)size.x / (float)MainRenderer.screenW) * 2.0f;
		float bottom = top + ((float)size.y / (float)MainRenderer.screenH) * 2.0f;
		//上下を反転
		top = -top;
		bottom = -bottom;
		//位置情報
		float positions[] = {			//x,y,zの順に定義
				left,top,0,					//左上
				left,bottom,0,				//左下
				right,bottom,0,				//右上
				right,top,0,
		};
		//OpenGLはビッグエンディアンではなく
		//CPUごとの”ネイティブエンディアン”で数値を伝える必要がある。
		//その為Javaヒープを直接的には扱えず、
		//”Java.nio”配下のクラスへ一度値を格納する必要がある。(面倒くせぇ)
		ByteBuffer bb=ByteBuffer.allocateDirect(positions.length * 4);  //GL_ESが扱えるのはallocateDirectで確保した領域のみ
		bb.order(ByteOrder.nativeOrder());		//実行環境に合わせて最適な値を指定できるようにnativeOrderを使う
		FloatBuffer fb = bb.asFloatBuffer();	//確保したバッファをfloatに格納(新たにメモリを確保しているわけではない)
		fb.put(positions);						//バッファをfloat配列に転送(この時点でエンディアンに関する変換はもう終わっている)
		fb.position(0);							//putすると書き込み位置が一つ進められるのでpositionで最初に戻す
		gl10.glVertexPointer(3,GL10.GL_FLOAT,0,fb);		//OpenGL ESに頂点バッファを関連付ける(コピーではないことに注意)


	}

	public void Draw(){		//描画
		gl10.glColor4f(r, g, b, a);

		gl10.glEnableClientState(GL10.GL_VERTEX_ARRAY);	//頂点バッファの成分を切り替えている(ここでは有効化)
		gl10.glDrawArrays(GL10.GL_TRIANGLE_FAN,0,4);	//描画
	}


}

添付ファイル
TouchBoll2.zip
(2.41 MiB) ダウンロード数: 128 回
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。

アバター
TOMY
記事: 53
登録日時: 13年前
住所: 愛知県
連絡を取る:

ポリゴンについて続き

#18

投稿記事 by TOMY » 13年前

すみません具体的な症例を記述していませんでした。
症例といたしましては
・自作クラス(GL2DVertex)を用いたポリゴンの描画をしようとしたら画面真っ黒になった後、強制終了。
・自分の予想といたしましてはおそらく、座標設定もしくはUV座標設定がちゃんとできていない
or
・GL10をクラス内で保持させてつかうことが間違っていたかもしれない。

またこのクラスはまだ作りかけで、とりあえずテクスチャを貼らずにポリゴンが描画されるかテスト中のプログラムです。
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。

アバター
Dixq (管理人)
管理人
記事: 1662
登録日時: 14年前
住所: 北海道札幌市
連絡を取る:

Re: OpenGL ES を使ったAndroidゲームの雛形について

#19

投稿記事 by Dixq (管理人) » 13年前

別経由でお伝えしましたが、一応こちらにも書いておきます。

MainReandererの
GL2DVertex test;
がnewせずにそのまま使われていることが落ちる原因ですね。
LogCatに表示される

07-17 22:47:03.488: E/AndroidRuntime(16359): java.lang.NullPointerException
07-17 22:47:03.488: E/AndroidRuntime(16359): at jp.denpa.tomy.opengl_es.wrap.MainRenderer.onDrawFrame(MainRenderer.java:161)

を見ると分かります。
強制終了した時はログが一面真っ赤になるので、そこを見ればおかしいところは分かりますよ。

アバター
TOMY
記事: 53
登録日時: 13年前
住所: 愛知県
連絡を取る:

Re: OpenGL ES を使ったAndroidゲームの雛形について

#20

投稿記事 by TOMY » 13年前

Dixq (管理人) さんが書きました: 強制終了した時はログが一面真っ赤になるので、そこを見ればおかしいところは分かりますよ。
なるほど、LogCatの文字色にはそんな意味があったのですね。
描画はできましたが、まだポリゴンの座標やら、UVのカットやらに問題がありそうだし、それ以前に貼った覚えのないテクスチャがはられているという問題(←どうせテクスチャの設定して忘れてるだけだろうけど)がおきているので、ここはまだ継続させて頂きます
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。

アバター
TOMY
記事: 53
登録日時: 13年前
住所: 愛知県
連絡を取る:

Re: OpenGL ES を使ったAndroidゲームの雛形について

#21

投稿記事 by TOMY » 13年前

一応ポリゴンの配置とUVの設定がうまく行ったので途中経過をアップ。
まだこのあと、radianでのポリゴン回転要素を入れるつもりだけどとりあえずテクスチャを管理するクラスを優先して作ろうかな。

コード:

//ポリゴンの生成、更新、描画を簡単にさせるためのクラス

package jp.denpa.tomy.opengl_es.wrap;

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

import javax.microedition.khronos.opengles.GL10;



public class GL2DVertex {

	public Vector2 center;			//中心座標
	public Vector2 size;			//ポリゴンサイズ
	public float   rad;				//回転角度

	private GL10   gl10;
	private float a,r,g,b;

	public void Init(GL10 gl){		//初期化
		//色の初期設定
		a=1.0f;
		r=1.0f;
		g=1.0f;
		b=1.0f;
		gl10=gl;
		float uv[] = {
				1,0,		//左上
				1,1,		//右上
				0,1,		//右下
				0,0,		//左下
		};
		ByteBuffer bb = ByteBuffer.allocateDirect(uv.length * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer fb = bb.asFloatBuffer();
		fb.put(uv);
		fb.position(0);

		gl10.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		gl10.glTexCoordPointer(2, GL10.GL_FLOAT, 0, fb);
	}

	public void SetUV(int cx,int cy,int nx,int ny,boolean turn){		//UV座標セット(cx,cy=分割数。 nx,ny=描画番号 ※左上原点でお考えください)
		float w = 1.0f/cx;
		float h = 1.0f/cy;

		float left	= w * nx;
		float top	= h * (ny+1);
		float right	= w * (nx+1);
		float bottom= h * ny;

		if(turn==true){			//反転フラグがtrueの時の処理
			float tu=right;
			right=left;
			left=tu;
		}
		float uv[] = {			//UV座標
			left,bottom,		//左下
			left,top,			//左上
			right,top,			//右上
			right,bottom,		//右下
		};

		ByteBuffer bb = ByteBuffer.allocateDirect(uv.length * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer fb = bb.asFloatBuffer();
		fb.put(uv);
		fb.position(0);

		gl10.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		gl10.glTexCoordPointer(2, GL10.GL_FLOAT, 0, fb);
	}

	public void SetColor(float A,float R,float G,float B){		//色の設定
		a=A;r=R;g=G;b=B;
	}

	public void SetPos(){		//座標の更新(確定)
		float left = ((center.x - size.x / 2)/ (float) MainRenderer.screenW) * 2.0f - 1.0f;
		float top  = ((center.y - size.y / 2)/ (float) MainRenderer.screenH) * 2.0f - 1.0f;

		float right = left + ((float)size.x / (float)MainRenderer.screenW) * 2.0f;
		float bottom = top + ((float)size.y / (float)MainRenderer.screenH) * 2.0f;
		//上下を反転
		top = -top;
		bottom = -bottom;
		//位置情報
		float positions[] = {			//x,y,zの順に定義
				left,top,0,					//左上
				left,bottom,0,				//左下
				right,bottom,0,				//右上
				right,top,0,
		};
		//OpenGLはビッグエンディアンではなく
		//CPUごとの”ネイティブエンディアン”で数値を伝える必要がある。
		//その為Javaヒープを直接的には扱えず、
		//”Java.nio”配下のクラスへ一度値を格納する必要がある。(面倒くせぇ)
		ByteBuffer bb=ByteBuffer.allocateDirect(positions.length * 4);  //GL_ESが扱えるのはallocateDirectで確保した領域のみ
		bb.order(ByteOrder.nativeOrder());		//実行環境に合わせて最適な値を指定できるようにnativeOrderを使う
		FloatBuffer fb = bb.asFloatBuffer();	//確保したバッファをfloatに格納(新たにメモリを確保しているわけではない)
		fb.put(positions);						//バッファをfloat配列に転送(この時点でエンディアンに関する変換はもう終わっている)
		fb.position(0);							//putすると書き込み位置が一つ進められるのでpositionで最初に戻す
		gl10.glVertexPointer(3,GL10.GL_FLOAT,0,fb);		//OpenGL ESに頂点バッファを関連付ける(コピーではないことに注意)


	}

	public void Draw(){		//描画
		gl10.glColor4f(r, g, b, a);

		gl10.glEnableClientState(GL10.GL_VERTEX_ARRAY);	//頂点バッファの成分を切り替えている(ここでは有効化)
		gl10.glDrawArrays(GL10.GL_TRIANGLE_FAN,0,4);	//描画
	}


}

百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。

アバター
TOMY
記事: 53
登録日時: 13年前
住所: 愛知県
連絡を取る:

Re: OpenGL ES を使ったAndroidゲームの雛形について

#22

投稿記事 by TOMY » 13年前

テクスチャを管理するクラスを作っててふと疑問に思ったんですが、
OpenGL ES のテクスチャっていうのは
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
と、定義した後は以降
gl10.glDrawArrays(GL10.GL_TRIANGLE_FAN,0,4); //描画
と記述したすべてのポリゴンにテクスチャが適用されますよね。
そこで質問なのですが、
正方形ポリゴンが二枚あり、1枚にはテクスチャが貼られ、そのあとにテクスチャが貼られてないポリゴンを描画したい場合、どうすればいいのでしょうか?

DirectXではこんな感じでテクスチャの貼り付けをしていましたが、こんな記述をOpenGL ESでもすることは出来るのでしょうか?
以下C++ DirectXでのテクスチャ貼り付けプログラム(一部)

コード:

//ポリゴンの生成に関するクラス内の描画メソッド部分
//-----------------------------------------------------------------------------------------------
// 関数名:CTLVer::Draw
// 内 容:2Dポリゴンの描画
// 引数1:DirectX描画デバイス
// 引数2:テクスチャポインタ
//-----------------------------------------------------------------------------------------------
void CTLVer::Draw(LPDIRECT3DDEVICE9 d , LPDIRECT3DTEXTURE9 tex)
{
	d->SetRenderState(D3DRS_LIGHTING , FALSE);
	d->SetFVF(FVF_TLVERTEX);
	d->SetTexture(0,tex);
	d->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, ver, sizeof(TLVERTEX));
}

このC++のコードではテクスチャポインタの引数にNULLを入れることによってテクスチャの貼られていないただのポリゴンが描画できました。
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。

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

Re: OpenGL ES を使ったAndroidゲームの雛形について

#23

投稿記事 by ISLe » 13年前

TOMY さんが書きました:テクスチャを管理するクラスを作っててふと疑問に思ったんですが、
OpenGL ES のテクスチャっていうのは
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
と、定義した後は以降
gl10.glDrawArrays(GL10.GL_TRIANGLE_FAN,0,4); //描画
と記述したすべてのポリゴンにテクスチャが適用されますよね。
そこで質問なのですが、
正方形ポリゴンが二枚あり、1枚にはテクスチャが貼られ、そのあとにテクスチャが貼られてないポリゴンを描画したい場合、どうすればいいのでしょうか?
【前処理】
glGenTextures テクスチャ(管理番号)を生成
glEnable(GL_TEXTURE_2D) テクスチャの使用を有効化
glBindTexure(GL_TEXTURE_2D, ~) テクスチャをターゲットに割り当て
glTexImage2D(GL_TEXTURE_2D, ~) ターゲット(に割り当てたテクスチャ)にイメージを読み込み
glDisable(GL_TEXTURE_2D) テクスチャの使用を無効化
【描画処理】
glEnable(GL_TEXTURE_2D) テクスチャの使用を有効化
glEnableClientState(GL_TEXTURE_COORD_ARRAY) テクスチャ座標配列を有効化
glEnableClientState(GL_VERTEX_ARRAY) 頂点座標配列を有効化
glTexCoordPointer(~) テクスチャ座標配列をセット
glVertexPointer(~) 頂点座標配列をセット
glBindTexure(GL_TEXTURE_2D, ~) テクスチャをターゲットに割り当て
glDrawArrays(~) 描画
glDisableClientState(GL_TEXTURE_COORD_ARRAY) テクスチャ座標配列を無効化
glDisableClientState(GL_VERTEX_ARRAY) 頂点座標配列を無効化
glDisable(GL_TEXTURE_2D) テクスチャの使用を無効化
というのが一連の流れです。
意図しない描画が行われないように基本的にはいちいち有効化したら無効化します。

テクスチャを貼らないポリゴンは、
glEnableClientState(GL_COLOR_ARRAY) 頂点カラー配列を有効化
glEnableClientState(GL_VERTEX_ARRAY) 頂点座標配列を有効化
glColorPointer(~) 頂点カラー配列をセット
glVertexPointer(~) 頂点座標配列をセット
glDrawArrays(~) 描画
glDisableClientState(GL_COLOR_ARRAY) 頂点カラー配列を無効化
glDisableClientState(GL_VERTEX_ARRAY) 頂点座標配列を無効化
というふうに描画したら良いと思います。

単色なら
glColor4f(~) 描画色をセット
glEnableClientState(GL_VERTEX_ARRAY) 頂点座標配列を有効化
glVertexPointer(~) 頂点座標配列をセット
glDrawArrays(~) 描画
glDisableClientState(GL_VERTEX_ARRAY) 頂点座標配列を無効化
のほうが良いですかね。


メソッドごとにglEnableClientState & gl~Pointerをしているのは問題があります。
描画時に一気に行うべき処理です。
複数のポリゴンを描画するときには混ざってしまって意図しない描画が行われることになります。

アバター
TOMY
記事: 53
登録日時: 13年前
住所: 愛知県
連絡を取る:

Re: OpenGL ES を使ったAndroidゲームの雛形について

#24

投稿記事 by TOMY » 13年前

すみませんglColorPointerについてが少しわかりません。調べてみたんですが第4引数のBuffer型の配列っていうのがちょっとわかりません。
そこの部分だけ何か例的なプログラムを提示してもらってよろしいでしょうか?
GL2DTLVertexクラスは三角形ポリゴン2枚を使用し、TRIANGLE_FANで設定しています。
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。

アバター
TOMY
記事: 53
登録日時: 13年前
住所: 愛知県
連絡を取る:

Re: OpenGL ES を使ったAndroidゲームの雛形について

#25

投稿記事 by TOMY » 13年前

なんか頭の中が滅茶苦茶になってしまったので途中経過だけ貼り付けておきます。
イメージとしてはGL2DVertexクラスのDrawメソッドに引数としてGLTextureクラスを入れたらそのポリゴンにテクスチャが貼られ、
nullをいれたらポリゴンだけ表示されるイメージ

(GL2DVertexクラス)

コード:

]
//ポリゴンの生成、更新、描画を簡単にさせるためのクラス

package jp.denpa.tomy.opengl_es.wrap;

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

import javax.microedition.khronos.opengles.GL10;



public class GL2DVertex {

	public Vector2 center;			//中心座標
	public Vector2 size;			//ポリゴンサイズ
	public float   rad;				//回転角度(radian)

	private GL10   gl10;
	private float a,r,g,b;

	public void Init(GL10 gl){		//初期化
		//色の初期設定
		a=1.0f;
		r=1.0f;
		g=1.0f;
		b=1.0f;
		gl10=gl;
		float uv[] = {
				1,0,		//左上
				1,1,		//右上
				0,1,		//右下
				0,0,		//左下
		};
		ByteBuffer bb = ByteBuffer.allocateDirect(uv.length * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer fb = bb.asFloatBuffer();
		fb.put(uv);
		fb.position(0);

//		gl10.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		gl10.glTexCoordPointer(2, GL10.GL_FLOAT, 0, fb);
	}

	public void SetUV(int cx,int cy,int nx,int ny,boolean turn){		//UV座標セット(cx,cy=分割数。 nx,ny=描画番号 ※左上原点でお考えください)
		float w = 1.0f/cx;
		float h = 1.0f/cy;

		float left	= w * nx;
		float top	= h * (ny+1);
		float right	= w * (nx+1);
		float bottom= h * ny;

		if(turn==true){			//反転フラグがtrueの時の処理
			float tu=right;
			right=left;
			left=tu;
		}
		float uv[] = {			//UV座標
			left,bottom,		//左下
			left,top,			//左上
			right,top,			//右上
			right,bottom,		//右下
		};

		ByteBuffer bb = ByteBuffer.allocateDirect(uv.length * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer fb = bb.asFloatBuffer();
		fb.put(uv);
		fb.position(0);

//		gl10.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		gl10.glTexCoordPointer(2, GL10.GL_FLOAT, 0, fb);				//ストリームに登録
	}

	public void SetColor(float A,float R,float G,float B){		//色の設定
		a=A;r=R;g=G;b=B;
	}

	public void SetPos(){		//座標の更新(確定)		//あとで回転の計算も入れる
		float left = ((center.x - size.x / 2)/ (float) MainRenderer.screenW) * 2.0f - 1.0f;
		float top  = ((center.y - size.y / 2)/ (float) MainRenderer.screenH) * 2.0f - 1.0f;

		float right = left + ((float)size.x / (float)MainRenderer.screenW) * 2.0f;
		float bottom = top + ((float)size.y / (float)MainRenderer.screenH) * 2.0f;
		//上下を反転
		top = -top;
		bottom = -bottom;
		//位置情報
		float positions[] = {			//x,y,zの順に定義
				left,top,0,					//左上
				left,bottom,0,				//左下
				right,bottom,0,				//右上
				right,top,0,
		};
		//OpenGLはビッグエンディアンではなく
		//CPUごとの”ネイティブエンディアン”で数値を伝える必要がある。
		//その為Javaヒープを直接的には扱えず、
		//”Java.nio”配下のクラスへ一度値を格納する必要がある。(面倒くせぇ)
		ByteBuffer bb=ByteBuffer.allocateDirect(positions.length * 4);  //GL_ESが扱えるのはallocateDirectで確保した領域のみ
		bb.order(ByteOrder.nativeOrder());		//実行環境に合わせて最適な値を指定できるようにnativeOrderを使う
		FloatBuffer fb = bb.asFloatBuffer();	//確保したバッファをfloatに格納(新たにメモリを確保しているわけではない)
		fb.put(positions);						//バッファをfloat配列に転送(この時点でエンディアンに関する変換はもう終わっている)
		fb.position(0);							//putすると書き込み位置が一つ進められるのでpositionで最初に戻す
		gl10.glVertexPointer(3,GL10.GL_FLOAT,0,fb);		//OpenGL ESに頂点バッファを関連付ける(コピーではないことに注意)


	}

	public void Draw(GLTexture gltex){		//描画
		if(gltex ==  null){
			gl10.glColor4f(r, g, b, a);
			gl10.glEnableClientState(GL10.GL_VERTEX_ARRAY);		//頂点バッファの成分を切り替えている(有効化)
			gl10.glDrawArrays(GL10.GL_TRIANGLE_FAN,0,4);		//描画
			gl10.glDisableClientState(GL10.GL_VERTEX_ARRAY);	//頂点バッファの成分を切り替えている(無効化)

		}else{
			gl10.glEnable(GL10.GL_TEXTURE_2D);					//テクスチャの有効化
			gltex.SetTex();
			gl10.glColor4f(r, g, b, a);
			gl10.glEnableClientState(GL10.GL_VERTEX_ARRAY);		//頂点バッファの成分を切り替えている(有効化)
			gl10.glDrawArrays(GL10.GL_TRIANGLE_FAN,0,4);		//描画
			gl10.glDisableClientState(GL10.GL_VERTEX_ARRAY);	//頂点バッファの成分を切り替えている(無効化)
			gl10.glDisable(GL10.GL_TEXTURE_2D);					//テクスチャの無効化


		}
	}


}

(GLTextureクラス)

コード:

package jp.denpa.tomy.opengl_es.wrap;

import javax.microedition.khronos.opengles.GL10;

import jp.denpa.tomy.games.MyView;
import jp.denpa.tomy.games.R;
//import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;


//テクスチャ管理クラス(1枚単位)
class GLTexture {
//	private Context context;			//このクラスでContextからgetResoucesするとエラーのち強制終了
	private Bitmap bitmap;
	private int textureName;
	private GL10 gl10;

	//テクスチャの読み込み
	public void LoadTexture(GL10 gl,Resources res,int id){
		gl10=gl;
		//テクスチャに関する処理---------------------------------------
		bitmap =	BitmapFactory.decodeResource(res, id);

		int[] buffers = new int[1];
		//texture夜のメモリを指定数確保
		gl10.glGenTextures(1,buffers,0);
		//テクスチャ名を保存する
		textureName = buffers[0];

	}

	public void SetTex(){
		gl10.glBindTexture(GL10.GL_TEXTURE_2D, textureName);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);				//テクスチャ確定

		//拡大縮小時の処理を指定
		gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
		gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);

		//ビットマップを廃棄
		bitmap.recycle();
	}
	

	//開放処理
	public void Release(){}

}

(実装はこんな感じ MyRendererクラス)

コード:

package jp.denpa.tomy.opengl_es.wrap;


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

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;

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

import jp.denpa.tomy.games.MyView;
import jp.denpa.tomy.games.R;


//OpenGL の Rendererに関するクラス メインループもここでする(←?)

public class MainRenderer implements GLSurfaceView.Renderer{

	private GL2DVertex test = new GL2DVertex();
	private GL2DVertex test2 = new GL2DVertex();
	private GLTexture  tex1  = new GLTexture();
	private GLTexture  tex2  = new GLTexture();


	enum FlameNo{
		START_INIT,
		START_MAIN,
		MENU_INIT,   	//メニュー準備
		MENU_MAIN,   	//メニュー処理
		GAME_INIT,   	//ゲーム準備
		GAME_MAIN,		//ゲーム処理
		RESULT_INIT,	//ゲーム終了時の得点表示
		RESULT_MAIN,	//ゲーム終了時の得点表示
	}


	private Context context;


	static FlameNo gameFlg = FlameNo.START_INIT;        //ゲームフラグ

	static int screenW;           //スクリーン座標
	static int screenH;




	public  MainRenderer(Context ctext){

		context=ctext;
	}

	private int textureName;


	//サーフェイス作成時の処理(サーフェイスが生成される際・または再生成される際に呼ばれる)
	@Override
	public void onSurfaceCreated(GL10 gl10, EGLConfig eglconfing){
		//⑦背景色
		gl10.glClearColor(1.0f,1.0f,1.0f,1.0f);
	    // ディザを無効化
	    gl10.glDisable(GL10.GL_DITHER);
	    // 深度テストを有効に
	    gl10.glEnable(GL10.GL_DEPTH_TEST);
	 	//テクスチャ機能ON
//	  	gl10.glEnable(GL10.GL_TEXTURE_2D);
	    //透明可能に
	  	gl10.glEnable(GL10.GL_ALPHA_TEST);
	   	//ブレンド可能に
	   	gl10.glEnable(GL10.GL_BLEND);
	  	//色のブレンド方法
	  	gl10.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE_MINUS_SRC_ALPHA);
	}

	//画面上のどの領域を使用するかの設定、あとポリゴン色とかの設定(サーフェイスのサイズ変更時に呼ばれる)
	@Override
	public void onSurfaceChanged(GL10 gl10, int w,int h ){
		gl10.glViewport(0, 0, w, h);
		screenW = w;
		screenH = h;

		//テクスチャに関する処理---------------------------------------
//		Bitmap bitmap =	BitmapFactory.decodeResource(context.getResources(), R.drawable.image_512);
//
//        log("bitmap size : " + bitmap.getWidth() + " x " + bitmap.getHeight());
//		gl10.glEnable(GL10.GL_TEXTURE_2D);
//		int[] buffers = new int[1];
//		//texture夜のメモリを指定数確保
//		gl10.glGenTextures(1,buffers,0);
//		//テクスチャ名を保存する
//		textureName = buffers[0];
//
//		gl10.glBindTexture(GL10.GL_TEXTURE_2D, textureName);
//		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
//
//		//拡大縮小時の処理を指定
//		gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
//		gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
//
//		//ビットマップを廃棄
//		bitmap.recycle();

	}



	//毎フレーム描画処理
	@Override
	public void onDrawFrame(GL10 gl10){

		//背景塗りつぶし----------------------------------
		gl10.glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
		gl10.glClear(GL10.GL_COLOR_BUFFER_BIT);
		//end---------------------------------------------

		tex1.LoadTexture(gl10, context.getResources(), R.drawable.image_512);
		tex2.LoadTexture(gl10, context.getResources(), R.drawable.image_128);


		test.center=new Vector2(50,50);
		test.size=new Vector2(100,100);
		test.Init(gl10);
		//test.SetUV(2, 2, 1, 1, false);		//成功


		test.SetPos();
		test.Draw(tex2);


		test2.center=new Vector2(300,300);
		test2.size=new Vector2(100,100);
		test2.Init(gl10);
		test2.SetUV(2, 2, 1, 0, false);		//成功

		test2.SetPos();
		test2.Draw(null);

	}
}


百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。

アバター
TOMY
記事: 53
登録日時: 13年前
住所: 愛知県
連絡を取る:

Re: OpenGL ES を使ったAndroidゲームの雛形について

#26

投稿記事 by TOMY » 13年前

プロジェクトもあげときます(動きます)
添付ファイル
TouchBoll2.zip
(2.41 MiB) ダウンロード数: 178 回
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。

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

Re: OpenGL ES を使ったAndroidゲームの雛形について

#27

投稿記事 by ISLe » 13年前

TOMY さんが書きました:すみませんglColorPointerについてが少しわかりません。調べてみたんですが第4引数のBuffer型の配列っていうのがちょっとわかりません。
そこの部分だけ何か例的なプログラムを提示してもらってよろしいでしょうか?
glTexCoordPointerでテクスチャ座標を、glVertexPointerで頂点座標をセットしているのとまったく同じで、頂点カラー情報の入った配列をセットするだけですが。
TOMY さんが書きました:なんか頭の中が滅茶苦茶になってしまったので途中経過だけ貼り付けておきます。
イメージとしてはGL2DVertexクラスのDrawメソッドに引数としてGLTextureクラスを入れたらそのポリゴンにテクスチャが貼られ、
nullをいれたらポリゴンだけ表示されるイメージ
前回の投稿に書いた描画の手順をきちんと見てください。
必要なことは既に書いてあります。

一括して行うべき処理が分散しているので、メソッドの呼び出し順に依存する、たいへん使いにくいクラスになっていますが良いのでしょうか?
描画するたびにテクスチャにイメージ(および属性)をセットしなおしているのが非効率です。画像データのロードと同時に一回行えば十分です。
gl~Pointerで使う配列バッファを何度も作りなおすのも非効率です。

アバター
TOMY
記事: 53
登録日時: 13年前
住所: 愛知県
連絡を取る:

Re: OpenGL ES を使ったAndroidゲームの雛形について

#28

投稿記事 by TOMY » 13年前

ISLe さんが書きました:一括して行うべき処理が分散しているので、メソッドの呼び出し順に依存する、たいへん使いにくいクラスになっていますが良いのでしょうか?
描画するたびにテクスチャにイメージ(および属性)をセットしなおしているのが非効率です。画像データのロードと同時に一回行えば十分です。
gl~Pointerで使う配列バッファを何度も作りなおすのも非効率です。
ええ、多少はわかっているつもりなのですが(先生にも聞いたりしてみて)なんか・・・複雑に考えすぎているのか、考えるごとに脳みそがごっちゃになってわけが分からなくなり、滅茶苦茶に組んでいるみたいなので少しクールダウンしてきます。
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。

閉鎖

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