OpenGL ES を使ったAndroidゲームの雛形について
OpenGL ES を使ったAndroidゲームの雛形について
現在OpenGL ESを使ったAndroidゲームの雛形を作ろうとしていますが。なかなかうまくいきません。
内容といたしましては
・各種クラスごとにファイル分割し、拡張性があるようにしたい(Activity、MyView、 ゲームの処理をさせる各種クラス)
・主な流れとしてはメインループ内にフレームナンバー(ゲームの状態)ごとに生成、描画を分ける
・場合によってはCanvas等と共存させたい(文字の描画を出来れば使いたいので)
今のところといたしましてこれくらいです。
一応Canvasだけを使ったゲームの雛形があるのでこれを拡張してOpenGL ESも対応できるようにしたいです。
プログラムが長くなるかもしれないのでファイルごとに上げます。
内容といたしましては
・各種クラスごとにファイル分割し、拡張性があるようにしたい(Activity、MyView、 ゲームの処理をさせる各種クラス)
・主な流れとしてはメインループ内にフレームナンバー(ゲームの状態)ごとに生成、描画を分ける
・場合によってはCanvas等と共存させたい(文字の描画を出来れば使いたいので)
今のところといたしましてこれくらいです。
一応Canvasだけを使ったゲームの雛形があるのでこれを拡張してOpenGL ESも対応できるようにしたいです。
プログラムが長くなるかもしれないのでファイルごとに上げます。
Re: OpenGL ES を使ったAndroidゲームの雛形について
↓以下自作中の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();
}
}
Re: OpenGL ES を使ったAndroidゲームの雛形について
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;
}
}
Re: OpenGL ES を使ったAndroidゲームの雛形について
(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);
}
}
Re: OpenGL ES を使ったAndroidゲームの雛形について
記述忘れましたが、ゲームの処理(Startクラス内)では
・Initメソッド (各種初期設定)
・Workメソッド (座標の更新処理)
・Updateメソッド (座標以外の更新処理 操作時の処理もここで)
・Drawメソッド (描画処理)
を出来るようにしたいです。
また、同じような形で Gameクラス、 Resultクラス
というふうにしたいです。
初めてのOpenGLを読んで見たり、ネットで調べてみたりしてはいますが、いかんせんそんな都合のいいサイトやサンプルプログラム
がないのでここに頼らせていただくことにしました。
後、以下はCanvasを用いたゲームプログラムの雛形(MyViewクラスのみ)です。
Start、Game、Resultクラスは上記に記したようにInit、Work、Uodate、Drawメソッドに分けてあります。
・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;
}
}
Re: OpenGL ES を使ったAndroidゲームの雛形について
とりあえず、上記の点については、Javaのインターフェイスという機能をご存知ないのでしょうか?TOMY さんが書きました:記述忘れましたが、ゲームの処理(Startクラス内)では
・Initメソッド (各種初期設定)
・Workメソッド (座標の更新処理)
・Updateメソッド (座標以外の更新処理 操作時の処理もここで)
・Drawメソッド (描画処理)
を出来るようにしたいです。
また、同じような形で Gameクラス、 Resultクラス
というふうにしたいです。
- Dixq (管理人)
- 管理人
- 記事: 1662
- 登録日時: 14年前
- 住所: 北海道札幌市
- 連絡を取る:
Re: OpenGL ES を使ったAndroidゲームの雛形について
ひな形を作りたいんですよね?
であれば、メインループにあたる部分にあのように書かれるのはおかしくないでしょうか?
ゲーム作りを楽にしたいなら、まずOpenGL ESをラッピングしたライブラリ的なものを先に作りそれを利用してはどうでしょう。
メインループには何も書かずに、
gl.clearScreen(); のような呼び出しで消せるように作っておき、
その他のメインループの記述はゲームの実質的な処理を書いていくべきなのではないでしょうか。
いちいちuv座標云々を全て考慮しないと作れないような状態だとゲーム制作がはかどらないと思います。
であれば、メインループにあたる部分にあのように書かれるのはおかしくないでしょうか?
ゲーム作りを楽にしたいなら、まずOpenGL ESをラッピングしたライブラリ的なものを先に作りそれを利用してはどうでしょう。
メインループには何も書かずに、
gl.clearScreen(); のような呼び出しで消せるように作っておき、
その他のメインループの記述はゲームの実質的な処理を書いていくべきなのではないでしょうか。
いちいちuv座標云々を全て考慮しないと作れないような状態だとゲーム制作がはかどらないと思います。
Re: OpenGL ES を使ったAndroidゲームの雛形について
[quote="ISLeとりあえず、上記の点については、Javaのインターフェイスという機能をご存知ないのでしょうか?[/quote]
↑上記の点につきましては私はまだJava知識が浅いため、知りませんでした。調べた限りでは継承すること前提のクラスと捉えていいでしょうか?
↑上記の点につきましては私はまだJava知識が浅いため、知りませんでした。調べた限りでは継承すること前提のクラスと捉えていいでしょうか?
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: OpenGL ES を使ったAndroidゲームの雛形について
Dixq (管理人) さんが書きました:ひな形を作りたいんですよね?
であれば、メインループにあたる部分にあのように書かれるのはおかしくないでしょうか?
ゲーム作りを楽にしたいなら、まずOpenGL ESをラッピングしたライブラリ的なものを先に作りそれを利用してはどうでしょう。
メインループには何も書かずに、
gl.clearScreen(); のような呼び出しで消せるように作っておき、
その他のメインループの記述はゲームの実質的な処理を書いていくべきなのではないでしょうか。
いちいちuv座標云々を全て考慮しないと作れないような状態だとゲーム制作がはかどらないと思います。
uv座標など、OpenGLやDirectX等のCG座標系などについては粗方わかっているので雛形として最低限の実装をしたら、各種処理を使いやすくしたクラスを作ろうとはしています。
ラッピングについてはjava知識が浅いため知りませんでしたので調べて見ました。(おそらく)使いやすいように自分流のクラスを作るということで合っていますかね?
C++だとプログラムは大体理解できるし、DirectXを用いたPCゲームの雛形は作れるのですがいかんせん、殆ど触ったことのないjavaなので、たまに詰まったときは先生や本に聞いていはいますが、予めjavaの機能を生かしたプログラミングは苦手です。
そんな中で制作していますので自分はjava知識的に足りないところが多いと思います。
あえて今まで書きませんでしたがこれは学校の課題の延長線上にあるものなので完成させなければなりません。
(課題はAndroidゲーム作成)
先ほど記述した通りjava知識は浅く残念なものですが出来上がるまで付き合ってもらえませんでしょうか?
後、mixCに登録させていただきましたそこで私のプログラミング能力について詳細に書いてあります。
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: OpenGL ES を使ったAndroidゲームの雛形について
現在の進行状況。
たまたまあるサイトでOpenGL ESのラッパーライブラリのサンプルがあったのでそれを参考に何とか動くプログラムを組むことができました。以下まだまだ粗いですが自作のゲーム雛形です。(途中。でも一応ちゃんと動きます)
(Activity)
(MyView)
(MainRenderer) //ゲームのメインループ処理をさせている場所(新しく追加)
一応一つ問題は解決しましたが、まだ納得の行くゲーム雛形が完成していませんので解決にチェックはまだかけないでおきます
たまたまあるサイトで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();
}
}
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;
}
}
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);
}
}
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: OpenGL ES を使ったAndroidゲームの雛形について
C++はだいたい理解できるとおっしゃっていますが、(純粋)仮想関数を使ったインターフェイスの設計手法はご存じないですか?TOMY さんが書きました:↑上記の点につきましては私はまだJava知識が浅いため、知りませんでした。調べた限りでは継承すること前提のクラスと捉えていいでしょうか?ISLe さんが書きました:とりあえず、上記の点については、Javaのインターフェイスという機能をご存知ないのでしょうか?
Re: OpenGL ES を使ったAndroidゲームの雛形について
インターフェイスは文法的にはこんな感じのものです。
配列よりはコンテナで管理するほうが良いと思います。
ライフサイクルが外部依存しなくなるので、クラスが増える度にswitchのcaseも増やすような手間はかかりません。
こちらのサイトの『Androidの館』にはクラスを継承した方法の解説があります。
インターフェイスではないですがやってることは同じです。
// インターフェイス
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の館』にはクラスを継承した方法の解説があります。
インターフェイスではないですがやってることは同じです。
Re: OpenGL ES を使ったAndroidゲームの雛形について
この質問につきましては仮想関数や純粋仮想関数などについてはわかっていましたが、それを生かしての設計手法、というものがまだまだ未熟な為知りませんでした。ISLe さんが書きました:C++はだいたい理解できるとおっしゃっていますが、(純粋)仮想関数を使ったインターフェイスの設計手法はご存じないですか?
というか、設計手法が多分自分にとって一番ネックなのだと思います。現に学校でもそこを何度か指摘されたことがあるので。様々な書籍で勉強してみたりしているのですが、
やはり実際に設計をして組むという経験が少ないのは痛いのかもしれません。(今まで何度か試して入るのですが結局少し滅茶苦茶なプログラムになったりします。)
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: OpenGL ES を使ったAndroidゲームの雛形について
設計をしてから組むという経験は必要無いです。TOMY さんが書きました:というか、設計手法が多分自分にとって一番ネックなのだと思います。現に学校でもそこを何度か指摘されたことがあるので。様々な書籍で勉強してみたりしているのですが、
やはり実際に設計をして組むという経験が少ないのは痛いのかもしれません。(今まで何度か試して入るのですが結局少し滅茶苦茶なプログラムになったりします。)
自分の書いたコードを、書いた端から改良していけば良いのです。
ゲームの雛形というと、ソースファイルをコピーして、そこにアプリ独自のコードを書き込んでいくのをイメージするかもしれません。
ですが、それはソースファイル全体をコピペしているのと同じですから、既存のソースファイルに一切手を加えず再利用するほうが効率は良いです。
コピペはすればするほど時間を無駄にします。
ちなみにわたしは完全な独学です。
ネットの情報だけで十分勉強できますよ。
Re: OpenGL ES を使ったAndroidゲームの雛形について
ふぅむ・・・参考になるなぁ。
自分の勉強不足が露骨の露呈する・・・
interfaceなんて微塵にも思いつかなかった・・・
自分の勉強不足が露骨の露呈する・・・
interfaceなんて微塵にも思いつかなかった・・・
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: OpenGL ES を使ったAndroidゲームの雛形について
いわゆるインターフェイスは言語に依らない概念です。TOMY さんが書きました:自分の勉強不足が露骨の露呈する・・・
interfaceなんて微塵にも思いつかなかった・・・
interfaceを知っているから使うのではなく、Javaでこういう実装をするにはどうしたら良いかと調べることでinterfaceに行き着くわけです。
事前にそういう知識がまったく無くても、既存の仕組みを真似するだけでも得られるものがたくさんあります。
AndroidにはActivityのライフサイクルとイベントメソッドの仕組みがあり、Viewにも同じようにコールバック用のメソッドがあります。
Viewの仕組みあたりはTOMYさんがやりたいことそのものじゃないかと思いますけどね。
ポリゴンの生成やテクスチャの貼り付けを簡単にする為のclassを作る
大まかなメインループ処理ができたので次はポリゴンの生成や、貼り付けなどを簡単に行うためのclassを現在制作しております。
ですが、中々できず制作が停滞してしまいました。
求める機能としては
・中心座標、サイズを元にポリゴンの生成
・関数群は Init(各種初期化)、SetPos(座標更新処理の確定)、SetUV(任意のUV座標指定)、SetColor(ポリゴンカラーの任意変更)、Draw(描画)です。
・UVの指定と、ポリゴンカラーの設定はしていない場合Init内で予め決められた処理を行う。
・Drawメソッドではテクスチャ情報を渡すとテクスチャがはられたポリゴンが描画される。そうでない場合はテクスチャがはられていないポリゴンが描画される。
製作途中データ(GL2DVertexクラス) プロジェクトの方もzipファイルで上げます
ですが、中々できず制作が停滞してしまいました。
求める機能としては
・中心座標、サイズを元にポリゴンの生成
・関数群は 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 回
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
ポリゴンについて続き
すみません具体的な症例を記述していませんでした。
症例といたしましては
・自作クラス(GL2DVertex)を用いたポリゴンの描画をしようとしたら画面真っ黒になった後、強制終了。
・自分の予想といたしましてはおそらく、座標設定もしくはUV座標設定がちゃんとできていない
or
・GL10をクラス内で保持させてつかうことが間違っていたかもしれない。
またこのクラスはまだ作りかけで、とりあえずテクスチャを貼らずにポリゴンが描画されるかテスト中のプログラムです。
症例といたしましては
・自作クラス(GL2DVertex)を用いたポリゴンの描画をしようとしたら画面真っ黒になった後、強制終了。
・自分の予想といたしましてはおそらく、座標設定もしくはUV座標設定がちゃんとできていない
or
・GL10をクラス内で保持させてつかうことが間違っていたかもしれない。
またこのクラスはまだ作りかけで、とりあえずテクスチャを貼らずにポリゴンが描画されるかテスト中のプログラムです。
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
- Dixq (管理人)
- 管理人
- 記事: 1662
- 登録日時: 14年前
- 住所: 北海道札幌市
- 連絡を取る:
Re: OpenGL ES を使ったAndroidゲームの雛形について
別経由でお伝えしましたが、一応こちらにも書いておきます。
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)
を見ると分かります。
強制終了した時はログが一面真っ赤になるので、そこを見ればおかしいところは分かりますよ。
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)
を見ると分かります。
強制終了した時はログが一面真っ赤になるので、そこを見ればおかしいところは分かりますよ。
Re: OpenGL ES を使ったAndroidゲームの雛形について
なるほど、LogCatの文字色にはそんな意味があったのですね。Dixq (管理人) さんが書きました: 強制終了した時はログが一面真っ赤になるので、そこを見ればおかしいところは分かりますよ。
描画はできましたが、まだポリゴンの座標やら、UVのカットやらに問題がありそうだし、それ以前に貼った覚えのないテクスチャがはられているという問題(←どうせテクスチャの設定して忘れてるだけだろうけど)がおきているので、ここはまだ継続させて頂きます
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: OpenGL ES を使ったAndroidゲームの雛形について
一応ポリゴンの配置とUVの設定がうまく行ったので途中経過をアップ。
まだこのあと、radianでのポリゴン回転要素を入れるつもりだけどとりあえずテクスチャを管理するクラスを優先して作ろうかな。
まだこのあと、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); //描画
}
}
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: OpenGL ES を使ったAndroidゲームの雛形について
テクスチャを管理するクラスを作っててふと疑問に思ったんですが、
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でのテクスチャ貼り付けプログラム(一部)
このC++のコードではテクスチャポインタの引数にNULLを入れることによってテクスチャの貼られていないただのポリゴンが描画できました。
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));
}
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: OpenGL ES を使ったAndroidゲームの雛形について
【前処理】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をしているのは問題があります。
描画時に一気に行うべき処理です。
複数のポリゴンを描画するときには混ざってしまって意図しない描画が行われることになります。
Re: OpenGL ES を使ったAndroidゲームの雛形について
すみませんglColorPointerについてが少しわかりません。調べてみたんですが第4引数のBuffer型の配列っていうのがちょっとわかりません。
そこの部分だけ何か例的なプログラムを提示してもらってよろしいでしょうか?
GL2DTLVertexクラスは三角形ポリゴン2枚を使用し、TRIANGLE_FANで設定しています。
そこの部分だけ何か例的なプログラムを提示してもらってよろしいでしょうか?
GL2DTLVertexクラスは三角形ポリゴン2枚を使用し、TRIANGLE_FANで設定しています。
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: OpenGL ES を使ったAndroidゲームの雛形について
なんか頭の中が滅茶苦茶になってしまったので途中経過だけ貼り付けておきます。
イメージとしてはGL2DVertexクラスのDrawメソッドに引数としてGLTextureクラスを入れたらそのポリゴンにテクスチャが貼られ、
nullをいれたらポリゴンだけ表示されるイメージ
(GL2DVertexクラス)
(GLTextureクラス)
(実装はこんな感じ MyRendererクラス)
イメージとしては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); //テクスチャの無効化
}
}
}
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(){}
}
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);
}
}
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: OpenGL ES を使ったAndroidゲームの雛形について
プロジェクトもあげときます(動きます)
- 添付ファイル
-
- TouchBoll2.zip
- (2.41 MiB) ダウンロード数: 178 回
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: OpenGL ES を使ったAndroidゲームの雛形について
glTexCoordPointerでテクスチャ座標を、glVertexPointerで頂点座標をセットしているのとまったく同じで、頂点カラー情報の入った配列をセットするだけですが。TOMY さんが書きました:すみませんglColorPointerについてが少しわかりません。調べてみたんですが第4引数のBuffer型の配列っていうのがちょっとわかりません。
そこの部分だけ何か例的なプログラムを提示してもらってよろしいでしょうか?
前回の投稿に書いた描画の手順をきちんと見てください。TOMY さんが書きました:なんか頭の中が滅茶苦茶になってしまったので途中経過だけ貼り付けておきます。
イメージとしてはGL2DVertexクラスのDrawメソッドに引数としてGLTextureクラスを入れたらそのポリゴンにテクスチャが貼られ、
nullをいれたらポリゴンだけ表示されるイメージ
必要なことは既に書いてあります。
一括して行うべき処理が分散しているので、メソッドの呼び出し順に依存する、たいへん使いにくいクラスになっていますが良いのでしょうか?
描画するたびにテクスチャにイメージ(および属性)をセットしなおしているのが非効率です。画像データのロードと同時に一回行えば十分です。
gl~Pointerで使う配列バッファを何度も作りなおすのも非効率です。
Re: OpenGL ES を使ったAndroidゲームの雛形について
ええ、多少はわかっているつもりなのですが(先生にも聞いたりしてみて)なんか・・・複雑に考えすぎているのか、考えるごとに脳みそがごっちゃになってわけが分からなくなり、滅茶苦茶に組んでいるみたいなので少しクールダウンしてきます。ISLe さんが書きました:一括して行うべき処理が分散しているので、メソッドの呼び出し順に依存する、たいへん使いにくいクラスになっていますが良いのでしょうか?
描画するたびにテクスチャにイメージ(および属性)をセットしなおしているのが非効率です。画像データのロードと同時に一回行えば十分です。
gl~Pointerで使う配列バッファを何度も作りなおすのも非効率です。
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。