Android OpenGL10 輸入響應

OpenGL的承載體是GLSurfaceView,而GLSurfaceView類在很多方面類似於View,那麼它同樣具有與View的一些待遇,比如也能夠響應KeyEvent,MotionEvent事件等等,從前面幾篇中,有很多立方體的圖形可以在每次重繪的時候,設置不同的位置和旋轉角度,就可以實現圖形的位置的變化,這裏就可以通過觸摸事件產生的座標位置,讓圖形跟隨觸摸方向移動或者變換.

整體上不是很難.

<1> : 新建Android studio工程,工程名爲PumpKinBasicInput,繪製立方體借鑑了前一篇的.

主類:

package org.pumpkin.pumpkinbasicinput;

import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;


public class PumpKinMainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        InputSurfaceView inputSurfaceView=new InputSurfaceView(this);
        setContentView(inputSurfaceView/*R.layout.activity_pump_kin_main*/);

    }

}

繼承GLSurfaceView類:

package org.pumpkin.pumpkinbasicinput;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.view.KeyEvent;
import android.view.MotionEvent;

/**
 * Created by Administrator on 2016/5/6.
 */
public class InputSurfaceView extends GLSurfaceView {

    private final float TOUCH_SCALE_FACTOR = 180.0f / 320.0f;
    private float previousX;
    private float previousY;

    private InputRenderer renderer;

    public InputSurfaceView(Context context) {
        super(context);
        renderer=new InputRenderer(context);
        this.setRenderer(renderer);
        this.requestFocus();
        this.setFocusableInTouchMode(true);
    }

    @Override
    public boolean onKeyDown(int keyCode,KeyEvent event){

        switch (event.getAction()){
            case KeyEvent.KEYCODE_DPAD_LEFT:
                renderer.speedY -= 0.1f;
                break;
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                renderer.speedY += 0.1f;
                break;
            case KeyEvent.KEYCODE_DPAD_DOWN:
                renderer.speedX -= 0.1f;
                break;
            case KeyEvent.KEYCODE_DPAD_UP:
                renderer.speedX += 0.1f;
                break;
            case KeyEvent.KEYCODE_DPAD_CENTER:
                break;
        }
        return true;//super.onKeyDown(keyCode,event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        float currentX = event.getX();
        float currentY = event.getY();
        float deltaX, deltaY;

        switch(event.getAction()){
            case MotionEvent.ACTION_DOWN:

                break;
            case MotionEvent.ACTION_UP:

                break;
            case MotionEvent.ACTION_MOVE:
                deltaX = currentX - previousX;
                deltaY = currentY - previousY;
                renderer.angleX += deltaY * TOUCH_SCALE_FACTOR;
                renderer.angleY += deltaX * TOUCH_SCALE_FACTOR;
                break;
        }

        previousX = currentX;
        previousY = currentY;
        return true;//super.onTouchEvent(event);
    }
}

下面是立方體的繪製:

package org.pumpkin.pumpkinbasicinput;

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

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

import javax.microedition.khronos.opengles.GL10;

/**
 * Created by Administrator on 2016/5/5.
 */
public class MulTextureCube {

    private int[] textures;
    private Bitmap[] mBitmap=new Bitmap[6];

    private FloatBuffer vertexBuffer;
    private FloatBuffer texBuffer;

    private float[] vertices={
            -1.0f, -1.0f, 0.0f,  // 0. left-bottom-front
            1.0f, -1.0f, 0.0f,  // 1. right-bottom-front
            -1.0f,  1.0f, 0.0f,  // 2. left-top-front
            1.0f,  1.0f, 0.0f   // 3. right-top-front
    };

    float[] texCoords={
            0.0f, 1.0f,  // A. left-bottom (NEW)
            1.0f, 1.0f,  // B. right-bottom (NEW)
            0.0f, 0.0f,  // C. left-top (NEW)
            1.0f, 0.0f   // D. right-top (NEW)
    };

    int[] textureIDs=new int[1];

    public MulTextureCube(Context context){

        mBitmap[0] = BitmapFactory.decodeResource(context.getResources(), R.drawable.gh);
        mBitmap[1] = BitmapFactory.decodeResource(context.getResources(), R.drawable.ghh);
        mBitmap[2] = BitmapFactory.decodeResource(context.getResources(), R.drawable.gtr);
        mBitmap[3] = BitmapFactory.decodeResource(context.getResources(), R.drawable.ghr);
        mBitmap[4] = BitmapFactory.decodeResource(context.getResources(), R.drawable.yel);
        mBitmap[5] = BitmapFactory.decodeResource(context.getResources(), R.drawable.hj);

        ByteBuffer vbb=ByteBuffer.allocateDirect(vertices.length*4);
        vbb.order(ByteOrder.nativeOrder());

        vertexBuffer=vbb.asFloatBuffer();
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);

        ByteBuffer tbb=ByteBuffer.allocateDirect(texCoords.length*4);
        tbb.order(ByteOrder.nativeOrder());
        texBuffer=tbb.asFloatBuffer();
        texBuffer.put(texCoords);
        texBuffer.position(0);

    }

    public void loadTexture(GL10 gl){

        IntBuffer textBuffer=IntBuffer.allocate(6);
        gl.glGenTextures(6,textBuffer);
        textures=textBuffer.array();

        gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[0]);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,mBitmap[0],0);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);

        gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[1]);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,mBitmap[1],0);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);

        gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[2]);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,mBitmap[2],0);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);

        gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[3]);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,mBitmap[3],0);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);

        gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[4]);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,mBitmap[4],0);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);

        gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[5]);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,mBitmap[5],0);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);

    }

    public void draw(GL10 gl){

        gl.glFrontFace(GL10.GL_CCW);
        gl.glEnable(GL10.GL_CULL_FACE);
        gl.glCullFace(GL10.GL_BACK);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glVertexPointer(3,GL10.GL_FLOAT,0,vertexBuffer);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        gl.glTexCoordPointer(2,GL10.GL_FLOAT,0,texBuffer);

        //front
        gl.glPushMatrix();
        gl.glTranslatef(0.0f, 0.0f, 1.0f);
        gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[0]);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,4);
        gl.glPopMatrix();

        //left
        gl.glPushMatrix();
        gl.glRotatef(270.0f,0.0f,1.0f,0.0f);
        gl.glTranslatef(0.0f,0.0f,1.0f);
        gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[1]);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,4);
        gl.glPopMatrix();

        //back
        gl.glPushMatrix();
        gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
        gl.glTranslatef(0.0f, 0.0f, 1.0f);
        gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[2]);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
        gl.glPopMatrix();

        // right
        gl.glPushMatrix();
        gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
        gl.glTranslatef(0.0f, 0.0f, 1.0f);
        gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[3]);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
        gl.glPopMatrix();

        // top
        gl.glPushMatrix();
        gl.glRotatef(270.0f, 1.0f, 0.0f, 0.0f);
        gl.glTranslatef(0.0f, 0.0f, 1.0f);
        gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[4]);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
        gl.glPopMatrix();

        // bottom
        gl.glPushMatrix();
        gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
        gl.glTranslatef(0.0f, 0.0f, 1.0f);
        gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[5]);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
        gl.glPopMatrix();

        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisable(GL10.GL_CULL_FACE);

    }



}


渲染器:

package org.pumpkin.pumpkinbasicinput;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;

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

/**
 * Created by Administrator on 2016/5/6.
 */
public class InputRenderer implements GLSurfaceView.Renderer {

    private Context mContext;
    private MulTextureCube mulTextureCube;

    float angleX = 0;
    float angleY = 0;
    float speedX = 0;
    float speedY = 0;
    float z = -6.0f;

    public InputRenderer(Context context){

        mContext=context;
        mulTextureCube=new MulTextureCube(context);

    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

        gl.glClearColor(0.0f,0.0f,0.0f,1.0f);
        gl.glClearDepthf(1.0f);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthFunc(GL10.GL_LEQUAL);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_NICEST);
        gl.glShadeModel(GL10.GL_SMOOTH);
        gl.glDisable(GL10.GL_DITHER);

        mulTextureCube.loadTexture(gl);
        gl.glEnable(GL10.GL_TEXTURE_2D);

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {

        if(height==0){
            height=1;
        }
        float aspect=(float)width/height;

        gl.glViewport(0,0,width,height);

        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        GLU.gluPerspective(gl, 45, aspect, 0.1f, 100.0f);

        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();

    }

    @Override
    public void onDrawFrame(GL10 gl) {

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        gl.glLoadIdentity();
        gl.glTranslatef(0.0f, 0.0f, z);
        gl.glRotatef(angleX, 1.0f, 0.0f, 0.0f);
        gl.glRotatef(angleY, 0.0f, 1.0f, 0.0f);

        mulTextureCube.draw(gl);

        angleX += speedX;
        angleY += speedY;

    }

}


同樣運行,在屏幕上滑動,既可以看到立方體隨之變換.

結果不再截圖.












發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章