Android的2D游戏的OpenGL [英] Android 2D Game With OpenGL
问题描述
最近我的工作在2D游戏中使用 SurfaceView
,我学到了很多关于游戏的循环和一切。但现在我要让使用OpenGL游戏一样。我读了 GLSurfaceView
是类,这将是相对于什么 SurfaceView
了。但我不知道其他的事情:
使用 SurfaceView
,我用了Bitmap类加载图像资源,这将是让说一个字符。这位将是我的字符
类的属性。而对于gameloop我用不同的发
我是新来的的OpenGL
,所以我想知道如何加载图像资源(我使用位图加载它们code>类?),或者改用什么
发的
为游戏循环?
我使用Bitmap类加载它们?
块引用>是的,你可以载入位图,并将其作为
textImage2D
。例如:
公共无效loadTextures(GL10 GL,上下文的背景下){
Log.e(LOG_TAGExplosionSprite :: loadTextures); mFrame = 0; InputStream为;
位图位图;
是= context.getResources()openRawResource(DRAW_SOURCE)。
位= BitmapFactory.de codeStream(是);
尝试{
is.close();
是=无效;
}赶上(IOException异常五){
} gl.glGenTextures(TEXTURE_COUNT,纹理,0); gl.glBindTexture(GL10.GL_TEXTURE_2D,纹理[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,位图,0); bitmap.recycle();
}4个月之前,我也一样,因为性能切换到OpenGL ES的2D。
它有点复杂,但有一段时间似乎很容易了。
我没有为单个图像,现在的例子,但有精灵表我在哪里我的动画图像pretty很好的例子。我敢肯定,你可以删除不相关的数据,使之成为一个静态图像。谷歌拥有足够的资源如何所以我会点什么,我用我的目的:
Cast_001_Sprite_.java
进口java.io.IOException异常;
进口的java.io.InputStream;
进口java.nio.ByteBuffer中;
进口java.nio.ByteOrder中;
进口java.nio.FloatBuffer中;进口javax.microedition.khronos.opengles.GL10;进口net.obviam.droidz.R;
进口net.obviam.droidz.model.components.ESpriteDirection;
进口android.content.Context;
进口android.graphics.Bitmap;
进口android.graphics.BitmapFactory;
进口android.opengl.GLUtils;
进口android.util.Log;公共类Cast_001_Sprite_ { 私有静态最后弦乐LOG_TAG = Cast_001_Sprite.class.getSimpleName(); / **雪碧表定义* /
私有静态最终诠释SPRITE_WIDTH = 5;
私有静态最终诠释SPRITE_HEIGHT = 4;
私人INT DRAW_SOURCE = R.drawable.a1; 私人INT MX = Location._1 [0]; // 100;
私人诠释我= Location._1 [1]; // 100;
私人浮动mScreenWidth,mScreenHeight,wRatio,hRatio;
私人INT mFrame = 0;
私人INT mSwitcher = 0;
私人最终静态INT TEXTURE_COUNT = 1; //为精灵表,我们使用1张图像所有的时间。
私人诠释[] =纹理新INT [TEXTURE_COUNT] //帧动画 保护FloatBuffer vertexBuffer; 私人最终静态ESpriteDirection mDirection = ESpriteDirection.TOP_TO_DOWN_LEFT_TO_RIGHT;
公众持股量X,Y,initPos,finalPos,initSpeed,currentPos; 私人ByteBuffer的BB1; 私人最终静态INT TOTAL_IMAGE_COUNT_IN_SPRITE = SPRITE_WIDTH * SPRITE_HEIGHT; 私人FloatBuffer [] = floatBufferArray新FloatBuffer [TOTAL_IMAGE_COUNT_IN_SPRITE] 私人浮动xOffset = 1.0F / SPRITE_WIDTH;
私人浮动yOffset = 1.0F / SPRITE_HEIGHT;
浮动[] =顶点新的浮动[] {
-1.0F,-1.0F,0.0,
-1.0F,1.0F,0.0,
1.0F,-1.0F,0.0,
1.0F,1.0F,0.0};
私人浮动储存[] [] =新的浮动[TOTAL_IMAGE_COUNT_IN_SPRITE] [];
私人诠释[] = sprite_X_Indexes新INT [SPRITE_WIDTH]; // {1,2,3,4};
私人诠释[] = sprite_Y_Indexes新INT [SPRITE_HEIGHT]; // {1,2,3,4}; 公共Cast_001_Sprite_(浮动屏幕宽度,浮screenHeight){ generateSpriteIndexes(); updateScreenData(屏幕宽度,screenHeight); INT索引= 0; 开关(mDirection){
案例TOP_TO_DOWN_LEFT_TO_RIGHT: 对于(INT行= 0;&行LT; SPRITE_HEIGHT;排++){
对于(INT列= 0;&列LT; SPRITE_WIDTH;柱++){
存储[指数] = generateTextures(列,行);
指数++;
}
}
打破;
案例DOWN_TO_TOP_LEFT_TO_RIGHT:
//去做
//为(INT行= spriteLength;排大于0;排 - ){
//为(INT列= 0;&列LT; spriteHeight;柱++){
//存储[指数] = generateTextures(行1列);
//指数++;
//}
//}
打破; 默认:
打破;
}
//顶点缓冲区
BB1 = ByteBuffer.allocateDirect(vertices.length * 4);
bb1.order(ByteOrder.nativeOrder());
vertexBuffer = bb1.asFloatBuffer();
vertexBuffer.put(顶点);
vertexBuffer.position(0); 的for(int i = 0; I< TOTAL_IMAGE_COUNT_IN_SPRITE;我++){
BB1 = ByteBuffer.allocateDirect(存储[I]。长度* 4);
bb1.order(ByteOrder.nativeOrder());
FloatBuffer textureBuffer = bb1.asFloatBuffer();
textureBuffer.put(存储[I]);
textureBuffer.position(0); floatBufferArray [I] = textureBuffer;
}
} 私人无效generateSpriteIndexes(){ 对(INT indexX = 0; indexX&下; SPRITE_WIDTH; indexX ++){
sprite_X_Indexes [indexX] = indexX + 1;
} 对(INT indexY = 0; indexY&下; SPRITE_HEIGHT; indexY ++){
sprite_Y_Indexes [indexY] = indexY + 1;
}
} 公共无效updateScreenData(浮动屏幕宽度,浮screenHeight){
//需要屏幕的高度和宽度
this.mScreenWidth =(屏幕宽度大于0)?屏幕宽度:1F;
this.mScreenHeight = screenHeight;
wRatio = 10F / mScreenWidth;
hRatio = mScreenHeight / 10F;
addExplosion(MX,我的);
}
公共无效addExplosion(浮法X,浮法Y){
this.x = X;
this.y = Y;
this.initPos = Y;
}
/ **
*按位置生成纹理
*
* @参数质感 - 填补当前的纹理
* @参数placeX - 在精灵规模X光图像的地方
* @参数placeY - 在精灵缩放Y形象的地方
* @返回
* /
私人浮动[] generateTextures(INT placeX,诠释placeY){ 浮纹[] =新的浮动[8]; / *
V1 V3 _____
| |
| |
V2 | _____ | V4
* /
// StringBuffer的BUFF =新的StringBuffer(); / ** * V1 /
质地[0] =(placeX == 0)0.0:xOffset * sprite_X_Indexes [placeX-1];
质地[1] = yOffset * sprite_Y_Indexes [placeY]; / ** * V2 /
质地[2] =(placeX == 0)0.0:xOffset * sprite_X_Indexes [placeX-1];
质地[3] =(placeY == 0)0.0:yOffset * sprite_Y_Indexes [placeY-1]; / ** * V3 /
质地[4] = xOffset * sprite_X_Indexes [placeX];
质地[5] = yOffset * sprite_Y_Indexes [placeY]; / ** * V4 /
质地[6] = xOffset * sprite_X_Indexes [placeX];
质地[7] =(placeY == 0)0.0:yOffset * sprite_Y_Indexes [placeY-1];
返回质感; }
私人无效更新(){
如果(mSwitcher == 1){
mFrame = ++ mFrame%TOTAL_IMAGE_COUNT_IN_SPRITE;
mSwitcher = 0;
// Log.e(LOG_TAGDevQuestSpriteBase ::+ mFrame);
}
其他{
mSwitcher ++;
}
} 公共无效复位(){
mFrame = 0;
}
公共无效loadTextures(GL10 GL,上下文的背景下){
Log.e(LOG_TAGExplosionSprite :: loadTextures); mFrame = 0; InputStream为;
位图位图;
是= context.getResources()openRawResource(DRAW_SOURCE)。
位= BitmapFactory.de codeStream(是);
尝试{
is.close();
是=无效;
}赶上(IOException异常五){
} gl.glGenTextures(TEXTURE_COUNT,纹理,0); gl.glBindTexture(GL10.GL_TEXTURE_2D,纹理[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,位图,0); bitmap.recycle(); } 公共无效画(GL10 GL){
//如果(mFrame == TOTAL_IMAGE_COUNT_IN_SPRITE - 1){
//返回;
//} gl.glPushMatrix();
尝试{
浮transx = +(wRatio * X);
浮transy = +(mScreenHeight * wRatio) - (wRatio * Y) - 1 / hRatio; // Log.e(LOG_TAGtransx:+ transx +; transy:+ transy +; sprite.x:+ sprite.x +; sprite.y:+ sprite.y); gl.glTranslatef(transx,transy,0.0); //########### 画 ############## gl.glBindTexture(GL10.GL_TEXTURE_2D,纹理[0]); gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_S,GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_T,GL10.GL_CLAMP_TO_EDGE); gl.glTexCoordPointer(2,GL10.GL_FLOAT,0,floatBufferArray [mFrame]); 更新(); gl.glColor4f(1F,1F,1F,0.2F); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glVertexPointer(3,GL10.GL_FLOAT,0,vertexBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,vertices.length / 3);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // ############################### }赶上(NullPointerException异常五){
}
gl.glPopMatrix();
}
}DevQuest1Activity.java
公共类DevQuest1Activity延伸活动{
私人DevQuestGLSurfaceView mGLView;@覆盖
公共无效的onCreate(捆绑savedInstanceState){
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow()。setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
mGLView =新DevQuestGLSurfaceView(本);
的setContentView(mGLView);
}@覆盖
保护无效的onPause(){
super.onPause();
mGLView.onPause();
}@覆盖
保护无效onResume(){
super.onResume();
mGLView.onResume();
}
}DevQuestGLRenderer.java
公共类DevQuestGLRenderer实现GLSurfaceView.Renderer {私有静态最后弦乐LOG_TAG =中带; // DevQuestGLRenderer.class.getSimpleName();私人上下文的背景下;
私人浮动比例;
私人诠释屏幕宽度,screenHeight;
公共Cast_001_Sprite Cast_001_Sprite;
公共DevQuestGLRenderer(上下文的背景下){
this.context =背景;
}@覆盖
公共无效onSurfaceCreated(GL10 GL,EGLConfig confid){
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearColor(0.0,0.0,0.0,1.0F);
gl.glClearDepthf(1.0F);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_NICEST);
gl.glEnable(GL10.GL_BLEND);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glTexEnvf(GL10.GL_TEXTURE_ENV,GL10.GL_TEXTURE_ENV_MODE,/*GL10.GL_REPLACE*/ GL10.GL_MODULATE);
}@覆盖
公共无效onSurfaceChanged(GL10 GL,诠释的宽度,高度INT){ Log.e(LOG_TAGonSurfaceChanged); // prevent 0 divise
如果(高== 0){身高= 1;}
屏幕宽度=宽度; screenHeight =高度;
比=(浮点)宽/高;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0,宽度,0,高度,-10F,10F);
gl.glViewport(0,0,屏幕宽度,screenHeight); Cast_001_Sprite =新Cast_001_Sprite(宽度,高度); Cast_001_Sprite.loadTextures(GL,背景);
}@覆盖
公共无效onDrawFrame(GL10 GL){ gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity(); gl.glPushMatrix();
gl.glScalef((屏幕宽度)/ 10,(screenHeight *比)/ 10,1.0F); Cast_001_Sprite.draw(GL); gl.glPopMatrix();
}
}DevQuestGLSurfaceView.java
公共类DevQuestGLSurfaceView扩展GLSurfaceView {
私人DevQuestGLRenderer mRenderer; 私人诠释计数= 0; 公共DevQuestGLSurfaceView(上下文的背景下){
超级(上下文);
mRenderer =新DevQuestGLRenderer(背景);
setRenderer(mRenderer);
} @覆盖
公共布尔onTouchEvent(MotionEvent事件){ 返回true;
}
}ESpriteDirection.java
公共枚举ESpriteDirection {
TOP_TO_DOWN_LEFT_TO_RIGHT,
DOWN_TO_TOP_LEFT_TO_RIGHT,
TOP_TO_DOWN_RIGHT_TO_LEFT,
DOWN_TO_TOP_RIGHT_TO_LEFT
}这是我用了一个形象:
Recently I worked on a 2D Game using
SurfaceView
and I learned a lot about game loops and everything. But now I want to make the same game using OpenGL. I read that theGLSurfaceView
is the class that would be relative to whatSurfaceView
was. But I'm not sure about other things as:Using
SurfaceView
, I used the Bitmap class to load a image resource that would be lets say a character. And that bitmap would be a property of myCharacter
class. And for the gameloop I used a differentThread
I'm new to
OpenGL
so I'd like to know how to load image resources (do I load them using theBitmap
class?), or what to use instead of aThread
for the game loop?解决方案do I load them using the Bitmap class?
Yes, you can load bitmap and use it as
textImage2D
.Example:
public void loadTextures(GL10 gl, Context context) { Log.e(LOG_TAG, "ExplosionSprite :: loadTextures"); mFrame = 0; InputStream is; Bitmap bitmap; is = context.getResources().openRawResource(DRAW_SOURCE); bitmap = BitmapFactory.decodeStream(is); try { is.close(); is = null; } catch (IOException e) { } gl.glGenTextures(TEXTURE_COUNT, textures, 0); gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); bitmap.recycle(); }
Before 4 month I did the same, because of performance switched to OpenGL ES 2D.
Its a bit complicated but after some time seems easy enough.
I don't have right now example for single image but have pretty good example for sprite sheet where I animate my Image. I'm sure you can remove not relevant data to make it for one static image. Google has enough resources "how to" so I'll point what I used for my purposes:
Cast_001_Sprite_.java
import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import javax.microedition.khronos.opengles.GL10; import net.obviam.droidz.R; import net.obviam.droidz.model.components.ESpriteDirection; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLUtils; import android.util.Log; public class Cast_001_Sprite_ { private static final String LOG_TAG = Cast_001_Sprite.class.getSimpleName(); /** Sprite sheet definition */ private static final int SPRITE_WIDTH = 5; private static final int SPRITE_HEIGHT = 4; private int DRAW_SOURCE = R.drawable.a1; private int mX = Location._1[0]; // 100; private int mY = Location._1[1]; // 100; private float mScreenWidth, mScreenHeight, wRatio, hRatio; private int mFrame = 0; private int mSwitcher = 0; private final static int TEXTURE_COUNT = 1; // for sprite sheet we use 1 image all the time. private int[] textures = new int[TEXTURE_COUNT]; // frame animation protected FloatBuffer vertexBuffer; private final static ESpriteDirection mDirection = ESpriteDirection.TOP_TO_DOWN_LEFT_TO_RIGHT; public float x, y, initPos, finalPos, initSpeed, currentPos; private ByteBuffer bb1; private final static int TOTAL_IMAGE_COUNT_IN_SPRITE = SPRITE_WIDTH * SPRITE_HEIGHT; private FloatBuffer[] floatBufferArray = new FloatBuffer[TOTAL_IMAGE_COUNT_IN_SPRITE]; private float xOffset = 1.0f/SPRITE_WIDTH; private float yOffset = 1.0f/SPRITE_HEIGHT; float[] vertices = new float[] { -1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f }; private float storage[][] = new float[TOTAL_IMAGE_COUNT_IN_SPRITE][]; private int[] sprite_X_Indexes = new int[SPRITE_WIDTH];//{1,2,3,4}; private int[] sprite_Y_Indexes = new int[SPRITE_HEIGHT];//{1,2,3,4}; public Cast_001_Sprite_(float screenWidth, float screenHeight){ generateSpriteIndexes(); updateScreenData(screenWidth, screenHeight); int index = 0; switch (mDirection) { case TOP_TO_DOWN_LEFT_TO_RIGHT: for(int row = 0; row<SPRITE_HEIGHT; row++){ for(int column = 0; column<SPRITE_WIDTH; column++){ storage[index] = generateTextures(column, row); index++; } } break; case DOWN_TO_TOP_LEFT_TO_RIGHT: //TODO // for(int row = spriteLength; row>0; row--){ // for(int column = 0; column<spriteHeight; column++){ // storage[index] = generateTextures( row-1, column); // index++; // } // } break; default: break; } // vertices buffer bb1 = ByteBuffer.allocateDirect(vertices.length * 4); bb1.order(ByteOrder.nativeOrder()); vertexBuffer = bb1.asFloatBuffer(); vertexBuffer.put(vertices); vertexBuffer.position(0); for(int i=0; i<TOTAL_IMAGE_COUNT_IN_SPRITE; i++){ bb1 = ByteBuffer.allocateDirect(storage[i].length * 4); bb1.order(ByteOrder.nativeOrder()); FloatBuffer textureBuffer = bb1.asFloatBuffer(); textureBuffer.put(storage[i]); textureBuffer.position(0); floatBufferArray[i] = textureBuffer; } } private void generateSpriteIndexes() { for(int indexX = 0; indexX<SPRITE_WIDTH; indexX++){ sprite_X_Indexes[indexX] = indexX+1; } for(int indexY = 0; indexY<SPRITE_HEIGHT; indexY++){ sprite_Y_Indexes[indexY] = indexY+1; } } public void updateScreenData(float screenWidth, float screenHeight){ // takes screen Height and Width this.mScreenWidth = (screenWidth > 0) ? screenWidth : 1f; this.mScreenHeight = screenHeight; wRatio = 10f/mScreenWidth; hRatio = mScreenHeight/10f; addExplosion(mX,mY); } public void addExplosion(float x, float y) { this.x = x; this.y = y; this.initPos = y; } /** * Generates texture by location * * @param texture - fill current texture * @param placeX - image place in sprite scale X * @param placeY - image place in sprite scale Y * @return */ private float[] generateTextures(int placeX, int placeY) { float texture[] = new float[8]; /* V1 _____ V3 | | | | V2|_____|V4 */ //StringBuffer buff = new StringBuffer(); /** V1 */ texture[0] = (placeX == 0)?0.0f : xOffset*sprite_X_Indexes[placeX-1]; texture[1] = yOffset*sprite_Y_Indexes[placeY]; /** V2 */ texture[2] = (placeX == 0)?0.0f : xOffset*sprite_X_Indexes[placeX-1]; texture[3] = (placeY == 0)?0.0f : yOffset*sprite_Y_Indexes[placeY-1]; /** V3 */ texture[4] = xOffset*sprite_X_Indexes[placeX]; texture[5] = yOffset*sprite_Y_Indexes[placeY]; /** V4 */ texture[6] = xOffset*sprite_X_Indexes[placeX]; texture[7] = (placeY == 0)?0.0f : yOffset*sprite_Y_Indexes[placeY-1]; return texture; } private void update() { if(mSwitcher == 1){ mFrame = ++mFrame % TOTAL_IMAGE_COUNT_IN_SPRITE; mSwitcher = 0; // Log.e(LOG_TAG, "DevQuestSpriteBase :: " + mFrame); } else{ mSwitcher++; } } public void reset(){ mFrame = 0; } public void loadTextures(GL10 gl, Context context) { Log.e(LOG_TAG, "ExplosionSprite :: loadTextures"); mFrame = 0; InputStream is; Bitmap bitmap; is = context.getResources().openRawResource(DRAW_SOURCE); bitmap = BitmapFactory.decodeStream(is); try { is.close(); is = null; } catch (IOException e) { } gl.glGenTextures(TEXTURE_COUNT, textures, 0); gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); bitmap.recycle(); } public void draw(GL10 gl){ // if(mFrame == TOTAL_IMAGE_COUNT_IN_SPRITE - 1){ // return; // } gl.glPushMatrix(); try { float transx = + (wRatio * x); float transy = + (mScreenHeight*wRatio) - (wRatio * y) - 1/hRatio; // Log.e(LOG_TAG, "transx: " + transx + "; transy: " + transy + "; sprite.x: "+ sprite.x + "; sprite.y: " + sprite.y); gl.glTranslatef(transx, transy, 0.0f); //########### draw ############## gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, floatBufferArray[mFrame]); update(); gl.glColor4f(1f, 1f, 1f, 0.2f); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); //############################### } catch (NullPointerException e) { } gl.glPopMatrix(); } }
DevQuest1Activity.java
public class DevQuest1Activity extends Activity { private DevQuestGLSurfaceView mGLView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); mGLView = new DevQuestGLSurfaceView(this); setContentView(mGLView); } @Override protected void onPause() { super.onPause(); mGLView.onPause(); } @Override protected void onResume() { super.onResume(); mGLView.onResume(); } }
DevQuestGLRenderer.java
public class DevQuestGLRenderer implements GLSurfaceView.Renderer { private static final String LOG_TAG = "Fess";//DevQuestGLRenderer.class.getSimpleName(); private Context context; private float ratio; private int screenWidth, screenHeight; public Cast_001_Sprite Cast_001_Sprite; public DevQuestGLRenderer(Context context){ this.context = context; } @Override public void onSurfaceCreated(GL10 gl, EGLConfig confid) { gl.glEnable(GL10.GL_TEXTURE_2D); gl.glShadeModel(GL10.GL_SMOOTH); gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.glClearDepthf(1.0f); gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); gl.glEnable(GL10.GL_BLEND); gl.glDisable(GL10.GL_DEPTH_TEST); gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, /*GL10.GL_REPLACE*/ GL10.GL_MODULATE); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { Log.e(LOG_TAG, "onSurfaceChanged"); // prevent 0 divise if(height == 0) { height=1;} screenWidth = width; screenHeight = height; ratio = (float) width/height; gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrthof(0, width, 0, height, -10f, 10f); gl.glViewport(0, 0, screenWidth, screenHeight); Cast_001_Sprite = new Cast_001_Sprite(width, height); Cast_001_Sprite.loadTextures(gl, context); } @Override public void onDrawFrame(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glPushMatrix(); gl.glScalef((screenWidth)/10, (screenHeight*ratio)/10, 1.0f); Cast_001_Sprite.draw(gl); gl.glPopMatrix(); } }
DevQuestGLSurfaceView.java
public class DevQuestGLSurfaceView extends GLSurfaceView { private DevQuestGLRenderer mRenderer; private int count = 0; public DevQuestGLSurfaceView(Context context) { super(context); mRenderer = new DevQuestGLRenderer(context); setRenderer(mRenderer); } @Override public boolean onTouchEvent(MotionEvent event) { return true; } }
ESpriteDirection.java
public enum ESpriteDirection { TOP_TO_DOWN_LEFT_TO_RIGHT, DOWN_TO_TOP_LEFT_TO_RIGHT, TOP_TO_DOWN_RIGHT_TO_LEFT, DOWN_TO_TOP_RIGHT_TO_LEFT }
And this is an image I used:
这篇关于Android的2D游戏的OpenGL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!