note 07- openGl ES for android

VortexActivity.java

package com.vortex_android;

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

public class VortexActivity extends Activity{
    
    private static final String LOG_TAG=VortexActivity.class.getSimpleName();
    private VortexView vortexView;
    
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState){
        
        super.onCreate(savedInstanceState);
        vortexView=new VortexView(this);
        setContentView(vortexView);
    }
    
}

  VortexView

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.vortex_android;

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

/**
 *
 * @author Administrator
 */
public class VortexView extends GLSurfaceView{
    
    private static final String LOG_TAG=VortexView.class.getSimpleName();
    private VortexRenderer renderer;
    
    private MotionEvent eventMediator;
    
    private float x=0;
    private float y=0;
    
    public VortexView(Context context){
        super(context);
        renderer=new VortexRenderer();
        this.setRenderer(renderer);
        
    }
    
    //GLSurfaceView equals to GLJPanel, also a view container;
    @Override
    public boolean onTouchEvent(final MotionEvent event){
        
        //2 method both will be OK . onDrawFrame(GL10 gl) will run
        //automatic when the GLSurfaceView.setRenderer; it is the same as
        //opengl2.
        //not need to get the runnable thread and control it
        //but it also works;
        
//        eventMediator=event;
////        this.queueEvent(glRunnable);
//        renderer.setColor(eventMediator.getX()/getWidth(), eventMediator.getY()/getHeight(), 1);
//        renderer.setAngleY(event.getX());
        
        if(event.getAction()==MotionEvent.ACTION_DOWN){
            x=event.getX();
            y=event.getY();
        }
        
        if(event.getAction()==MotionEvent.ACTION_MOVE){
            final float xdiff=(event.getX()-x);
            final float ydiff=(event.getY()-y);
            
            renderer.setAngleX(renderer.getAngleX()+ydiff);
            renderer.setAngleY(renderer.getAngleY()+xdiff);
            
            x=event.getX();
            y=event.getY();
        }

        return true;
    }
    
    private Runnable glRunnable=new Runnable(){

        public void run() {
            renderer.setColor(eventMediator.getX()/getWidth(), eventMediator.getY()/getHeight(), 1);
            
        }
        
    };
    
}

  VortexRenderer

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.vortex_android;

import android.opengl.GLSurfaceView;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

/**
 *
 * @author Administrator
 */
public class VortexRenderer implements GLSurfaceView.Renderer{
    
    private static final String LOG_TAG=VortexRenderer.class.getSimpleName();
    
    private float red=0.9f;
    private float green=0.2f;
    private float blue=0.2f;
    
    private ShortBuffer indexBuffer;
    private ShortBuffer indexBufferStatic;
    
    private FloatBuffer vertexBuffer;
    private FloatBuffer vertexBufferStatic;
    
//    private short[] indexArray;
//    private int numVertices=3;
    
    private FloatBuffer colorBuffer;
    
    private float angleX;
    private float angleY;
    
    private float width=320;
    private float height=480;

    
    //renderer equals to GLEventListener;
    //GLJPanle gljpanel.addGLEventListener(glListener);
    public VortexRenderer() {
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        
        //equlas to init(GLAutoDrawable drawable){};
        
        gl.glMatrixMode(GL10.GL_PROJECTION);
        
        //ortho
//        float ratio=width/height;
//        gl.glOrthof(-1, 1, -1/ratio, 1/ratio, -100, 100);
//        gl.glViewport(0,0,(int)width,(int)height);
        
        //frustum
//        float size=.01f * (float) Math.tan(Math.toRadians(45.0) / 2);
        float size=0.002f;
        float ratio=width/height;
        gl.glFrustumf(-size, size, -size/ratio, size/ratio, 0.01f, 100);
        gl.glViewport(0, 0, (int)width, (int)height);
        
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        
        gl.glEnable(GL10.GL_CULL_FACE);
        gl.glCullFace(GL10.GL_BACK);
        gl.glEnable(GL10.GL_CCW);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glEnable(GL10.GL_FRONT_AND_BACK);
        
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
        initTriangle();
//        initStaticTriangle();
        
    }

    public void onSurfaceChanged(GL10 gl, int w, int h) {
        
        //equals to reshape(GLAutoDrawbale drawable,int x,int y,int width,int height);
        width=w;
        height=h;
        gl.glViewport(0, 0, w, h);
        
    }

    public void onDrawFrame(GL10 gl) {
        
        //equals to display(GLAutoDrawable drawable){};
        gl.glClearColor(red, green, blue, 1);
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
        
        
          //draw one pyramid
        gl.glLoadIdentity();
        
        gl.glPushMatrix();
        gl.glTranslatef(0, 0, -5);
        gl.glRotatef(angleX,1,0,0);
        gl.glRotatef(angleY,0,1,0);
        

        gl.glVertexPointer(3,GL10.GL_FLOAT,0,vertexBuffer);
        gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
        
        // GL10 glDrawElement is different from GL2. GL10 can draw a whole quene of TRIANGLES
        // in GL2 must use glDrawRangeElement
        gl.glDrawElements(GL10.GL_TRIANGLES, vertexBuffer.capacity(), GL10.GL_UNSIGNED_SHORT, indexBuffer);
        
        gl.glPopMatrix();
        
        
        
        
        //draw multi pyramid
//        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
//        gl.glColorPointer(4,GL10.GL_FLOAT,0,colorBuffer);
//        
//        for(int i=0;i<11;i++){
//            gl.glLoadIdentity();
//            gl.glTranslatef(0, -1, -1-1.5f*i);
//            gl.glRotatef(angleX, 1, 0, 0);
//            gl.glRotatef(angleY, 0, 1, 0);
//            gl.glDrawElements(GL10.GL_TRIANGLES, vertexBuffer.capacity(), GL10.GL_UNSIGNED_SHORT, indexBuffer);
//            
//        }
        
    }
    
    private void initTriangle(){
        
        
        float[] coords=new float[]{
            -0.5f,  -0.5f,  0.5f,
            0.5f,   -0.5f,  0.5f,
            0,      -0.5f,  -0.5f,
            0,      0.5f,   0
            
        };
        
        float[] colors=new float[]{
            1,0,0,1,
            0,1,0,1,
            0,0,1,1,
            1,1,1,1
        };
        
        short[] indices=new short[]{
            0,2,1,
            0,1,3,
            0,3,2,
            1,2,3
        };
        
        vertexBuffer=FloatBuffer.allocate(coords.length);
        indexBuffer=ShortBuffer.allocate(indices.length);
        colorBuffer=FloatBuffer.allocate(colors.length);
        
        vertexBuffer.put(coords);
        indexBuffer.put(indices);
        colorBuffer.put(colors);
        
        vertexBuffer.rewind();
        indexBuffer.rewind();
        colorBuffer.rewind();
    }
    
//    private void initStaticTriangle(){
//        vertexBufferStatic=FloatBuffer.allocate(numVertices*3);
//        indexBufferStatic=ShortBuffer.allocate(indexArray.length);
//        
//        float[] coords=new float[]{
//            -0.4f,  -0.4f,  0,
//            0.4f,   -0.4f,  0,
//            0,      0.4f,   0,  
//        };
//        
//        vertexBufferStatic.put(coords);
//        indexBufferStatic.put(indexArray);
//        
//        vertexBuffer.rewind();
//        indexBuffer.rewind();
//        
//    }
    
    
    public void setAngleX(float ang){
        angleX=ang;
    }
    
    public float getAngleX(){
        return angleX;
    }
    
    public void setAngleY(float ang){
        angleY=ang;
    }
    
    public float getAngleY(){
        return angleY;
    }
    
    
    
    public void setColor(float r, float g, float b){
        red=r;
        green=g;
        blue=b;
    }
    
}

 Activity must set a GLSurfaceView or its children class

GLSurfaceView must set a renderer which extends  GLSurfaceView.Renderer;

must implement 3 functions :

1.  onSurfaceCreate(GL10 gl,  EGLConfig config)     refer to   init(Gl2 gl)

2.  onDrawFrame(GL10 gl)                                       refer to   display(GL2 gl)

3.  onSurfaceChanged(Gl10 gl, int w,int h)              refer to   reshape(GL2 gl , int x, int y, int width, int height)

the renderer nearly equals to the GLEventListener , the GLSurfaceView nearly equals to the GLJPanel

some points of warnings:

1.  the VBO is disable in GL10 ES , so just can use normal Buffer .

2.  must use unsigned-short instead of int for most android CPU.

So the drawing process would be:

1. enable all params necessery  in the onSurfaceCreate function;

2. make the buffers . vertexBuffer, colorBuffer, normalBuffer , indexBuffer .

    remenber to rewind() after put data.

3. indicate the pointer to each buffer .

4. drawElements

note that draw elements without VBO is a little different from the situation that with VBO.

VBO draw element must follow the buffer pointer .

So you must set the buffer pointer each time for the indexBuffer.

However,  without VBO , you can draw the whole vertexBuffer with the whole index buffer.

猜你喜欢

转载自julianjulian8.iteye.com/blog/1734227
今日推荐