Android的2D游戏的OpenGL [英] Android 2D Game With OpenGL

查看:270
本文介绍了Android的2D游戏的OpenGL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我的工作在2D游戏中使用 SurfaceView ,我学到了很多关于游戏的循环和一切。但现在我要让使用OpenGL游戏一样。我读了 GLSurfaceView 是类,这将是相对于什么 SurfaceView 了。但我不知道其他的事情:

使用 SurfaceView ,我用了Bitmap类加载图像资源,这将是让说一个字符。这位将是我的字符类的属性。而对于gameloop我用不同的

我是新来的的OpenGL ,所以我想知道如何加载图像资源(我使用位图类?),或者改用什么发的为游戏循环?


解决方案

  

我使用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很好的例子。我敢肯定,你可以删除不相关的数据,使之成为一个静态图像。谷歌拥有足够的资源如何所以我会点什么,我用我的目的:

链接1

链接2

链接3

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 the GLSurfaceView is the class that would be relative to what SurfaceView 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 my Character class. And for the gameloop I used a different Thread

I'm new to OpenGL so I'd like to know how to load image resources (do I load them using the Bitmap class?), or what to use instead of a Thread 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:

link 1

link 2

link 3

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆