【Android】OpenGL ES---绘制3D图形、应用纹理贴图

绘制3D图形

glDrawElements(int mode,int count,int type Buffer indices):

  • 根据indices指定的索引点来绘制三角形
  • 第一个参数mode指定绘制的图形类型,可设置为GL10.GL_TRIANGLES或GL10.GL_TRIANGLE_STRIPE;
  • 第二个参数指定一共包含多少个顶点。
  • indices参数最重要,它包装了一个长度为3N的数组,比如让该参数包装(0,2,3,
    1, 4,5 )数组,这意味着告诉OpenGL ES 要绘制两个三角形,第一个三角形的三个顶点为0、2、3顶点,第二个三角形的三个顶点为1、4、5顶点。

MyRenderer.java

public class MyRenderer implements GLSurfaceView.Renderer {
     
    float[] taperVertices = new float[]{
     
            0.0f,0.5f,0.0f,//0
            -0.5f,-0.5f,-0.2f,//1
            0.5f,-0.5f,-0.2f,//2
            0.0f,-0.6f,0.2f//3
    };
    int [] taperColors = new int[]{
     
            65535,0,0,0,
            0,65535,0,0,
            0,0,65535,0,
            65535,65535,0
    };
    byte[] taperFaces = new byte[]{
     
            0,1,2,
            0,1,3,
            1,2,3,
            0,2,3
    };
    FloatBuffer taperVerticesBuffer;
    IntBuffer taperColorsBuffer;
    ByteBuffer taperFacesBuffer;

    private float angle = 1.0f;

    public MyRenderer(){
     
        taperVerticesBuffer = Utils.getFloatBuffer(taperVertices);
        taperColorsBuffer = Utils.getIntBuffer(taperColors);
        taperFacesBuffer = Utils.getByteBuffer(taperFaces);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
     
        gl.glClearColor(0.1f,0.1f,0.1f,0.0f);
        gl.glShadeModel(GL10.GL_SMOOTH);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthFunc(GL10.GL_LEQUAL);

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
     
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        float ratio = (float) width/height;
        gl.glFrustumf(-ratio,ratio,-1,1,1,10);

    }

    @Override
    public void onDrawFrame(GL10 gl) {
     
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        gl.glClear(GL10.GL_DEPTH_BUFFER_BIT);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

        //所有的旋转和缩放都是在ModelView下进行的
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glTranslatef(0.0f,0.0f,-1.5f);
        gl.glRotatef(angle,0f,0.2f,0f);
        gl.glVertexPointer(3,GL10.GL_FLOAT,0,taperVerticesBuffer);
        gl.glColorPointer(4,GL10.GL_FIXED,0,taperColorsBuffer);

        gl.glDrawElements(GL10.GL_TRIANGLE_STRIP,taperFacesBuffer.remaining(),
                GL10.GL_UNSIGNED_BYTE,taperFacesBuffer);
        gl.glFinish();
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
        angle++;


    }
}

Utils.java

public class Utils {
     
    public static FloatBuffer getFloatBuffer(float[] floats){
     
        FloatBuffer floatBuffer;
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(floats.length*4);
        byteBuffer.order(ByteOrder.nativeOrder());
        floatBuffer = byteBuffer.asFloatBuffer();
        floatBuffer.put(floats);
        floatBuffer.position(0);
        return floatBuffer;
    }
    public static IntBuffer getIntBuffer(int[] arrays){
     
        IntBuffer intBuffer;
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(arrays.length*4);
        byteBuffer.order(ByteOrder.nativeOrder());
        intBuffer = byteBuffer.asIntBuffer();
        intBuffer.put(arrays);
        intBuffer.position(0);
        return  intBuffer;
    }
    public static ByteBuffer getByteBuffer(byte[] arrays){
     
        ByteBuffer byteBuffer;
        byteBuffer = ByteBuffer.allocateDirect(arrays.length*4);
        byteBuffer.order(ByteOrder.nativeOrder());
        byteBuffer.put(arrays);
        byteBuffer.position(0);
        return byteBuffer;
    }

}

MainActivity.java

public class MainActivity extends AppCompatActivity {
     

    @Override
    protected void onCreate(Bundle savedInstanceState) {
     
        super.onCreate(savedInstanceState);

        GLSurfaceView surfaceView = new GLSurfaceView(this);
        surfaceView.setRenderer(new MyRenderer());
        setContentView(surfaceView);

    }
}

绘制立方体

MyRenderer.java

public class MyRenderer implements GLSurfaceView.Renderer {
     
    float[] cubeVertices = new float[]{
     
            //前面四个顶点
            0.5f,0.5f,0.5f,//0
            -0.5f,0.5f,0.5f,//1
            -0.5f,-0.5f,0.5f,//2
            0.5f,-0.5f,0.5f,//3
            //后面四个顶点
            0.5f,0.5f,-0.5f,//4
            -0.5f,0.5f,-0.5f,//5
            -0.5f,-0.5f,-0.5f,//6
            0.5f,-0.5f,-0.5f//7
    };
    int [] cubeColors = new int[]{
     
            65535,0,0,0,
            0,65535,0,0,
            0,0,65535,0,
            65535,65535,0,

            65535,0,0,0,
            0,65535,0,0,
            0,0,65535,0,
            65535,65535,0
    };
    //正方体
    byte[] cubeFaces = new byte[]{
     
            //前后面
            0,1,2,
            0,2,3,

            4,5,6,
            4,6,7,
            //左右面
            1,2,5,
            2,5,6,

            0,3,4,
            3,4,7,
            //上下面
            0,1,4,
            1,4,5,

            2,3,6,
            3,6,7
    };
    FloatBuffer cubeVerticesBuffer;
    IntBuffer cubeColorsBuffer;
    ByteBuffer cubeFacesBuffer;

    private float angle = 1.0f;

    public MyRenderer(){
     
        cubeVerticesBuffer = Utils.getFloatBuffer(cubeVertices);
        cubeColorsBuffer = Utils.getIntBuffer(cubeColors);
        cubeFacesBuffer = Utils.getByteBuffer(cubeFaces);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
     
        gl.glClearColor(0.1f,0.1f,0.1f,0.0f);
        gl.glShadeModel(GL10.GL_SMOOTH);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthFunc(GL10.GL_LEQUAL);

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
     
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        float ratio = (float) width/height;
        gl.glFrustumf(-ratio,ratio,-1,1,1,10);

    }

    @Override
    public void onDrawFrame(GL10 gl) {
     
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        gl.glClear(GL10.GL_DEPTH_BUFFER_BIT);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

        //所有的旋转和缩放都是在ModelView下进行的
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glTranslatef(0.0f,0.0f,-2.5f);
        gl.glRotatef(angle,0f,0.2f,0f);
        gl.glRotatef(angle,0.2f,0f,0f);
        gl.glVertexPointer(3,GL10.GL_FLOAT,0, cubeVerticesBuffer);
        gl.glColorPointer(4,GL10.GL_FIXED,0, cubeColorsBuffer);
        //gl.glColor4f(1,0,0,0);

        gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, cubeFacesBuffer.remaining(),
                GL10.GL_UNSIGNED_BYTE, cubeFacesBuffer);
        gl.glFinish();
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
        angle++;


    }
}

应用纹理贴图

在onSurfaceCreated(GL10 gl, EGLConfig config)中启动纹理贴图

【Android】OpenGL ES---绘制3D图形、应用纹理贴图_第1张图片

【Android】OpenGL ES---绘制3D图形、应用纹理贴图_第2张图片
【Android】OpenGL ES---绘制3D图形、应用纹理贴图_第3张图片

【Android】OpenGL ES---绘制3D图形、应用纹理贴图_第4张图片
【Android】OpenGL ES---绘制3D图形、应用纹理贴图_第5张图片

MainActivity.java

public class MainActivity extends AppCompatActivity {
     

    @Override
    protected void onCreate(Bundle savedInstanceState) {
     
        super.onCreate(savedInstanceState);

        GLSurfaceView surfaceView = new GLSurfaceView(this);
        //surfaceView.setRenderer(new Texture2DRenderer(MainActivity.this));//正方形贴图
        surfaceView.setRenderer(new PureColorCubeRenderer());//立方体不同面纯色
        //surfaceView.setRenderer(new CubeGraduateRenderer());//正方体,纯色过度
        //surfaceView.setRenderer(new Texture3DRenderer(this));//立方体贴图
        //surfaceView.setRenderer(new Special3DFigureRenderer(this));
        setContentView(surfaceView);

    }
}

Texture3DRenderer.java

public class Texture3DRenderer implements GLSurfaceView.Renderer {
     
    float[] cubeVertices = new float[]{
     
            //前面四个顶点
//            0.5f,0.5f,0.5f,//0
//            -0.5f,0.5f,0.5f,//1
//            -0.5f,-0.5f,0.5f,//2
//            0.5f,-0.5f,0.5f,//3
//            //后面四个顶点
//            0.5f,0.5f,-0.5f,//4
//            -0.5f,0.5f,-0.5f,//5
//            -0.5f,-0.5f,-0.5f,//6
//            0.5f,-0.5f,-0.5f,//7

            0.5f,0.5f,0.5f,//0
            -0.5f,0.5f,0.5f,//1
            -0.5f,-0.5f,0.5f,//2

            0.5f,0.5f,0.5f,//0
            -0.5f,-0.5f,0.5f,//2
            0.5f,-0.5f,0.5f,//3

            0.5f,0.5f,-0.5f,//4
            -0.5f,0.5f,-0.5f,//5
            -0.5f,-0.5f,-0.5f,//6

            0.5f,0.5f,-0.5f,//4
            -0.5f,-0.5f,-0.5f,//6
            0.5f,-0.5f,-0.5f,//7

            -0.5f,0.5f,0.5f,//1
            -0.5f,-0.5f,0.5f,//2
            -0.5f,0.5f,-0.5f,//5

            -0.5f,-0.5f,0.5f,//2
            -0.5f,0.5f,-0.5f,//5
            -0.5f,-0.5f,-0.5f,//6

            0.5f,0.5f,0.5f,//0
            0.5f,-0.5f,0.5f,//3
            0.5f,0.5f,-0.5f,//4

            0.5f,-0.5f,0.5f,//3
            0.5f,0.5f,-0.5f,//4
            0.5f,-0.5f,-0.5f,//7

            0.5f,0.5f,0.5f,//0
            -0.5f,0.5f,0.5f,//1
            0.5f,0.5f,-0.5f,//4

            -0.5f,0.5f,0.5f,//1
            0.5f,0.5f,-0.5f,//4
            -0.5f,0.5f,-0.5f,//5

            -0.5f,-0.5f,0.5f,//2
            0.5f,-0.5f,0.5f,//3
            -0.5f,-0.5f,-0.5f,//6

            0.5f,-0.5f,0.5f,//3
            -0.5f,-0.5f,-0.5f,//6
            0.5f,-0.5f,-0.5f,//7
    };
    //正方体
    byte[] cubeFaces = new byte[]{
     
            //前后面
            0,1,2,
            3,4,5,

            6,7,8,
            9,10,11,
            //左右面
            12,13,14,
            15,16,17,

            18,19,20,
            21,22,23,
            //上下面
            24,25,26,
            27,28,29,

            30,31,32,
            33,34,35
    };
    float[] texturesVertices = new float[]{
     
            //前
            1.0f,0.0f,
            0.0f,0.0f,
            0.0f,1.0f,
            1.0f,0.0f,
            0.0f,1.0f,
            1.0f,1.0f,
            //后
            0.0f,0.0f,
            1.0f,0.0f,
            1.0f,1.0f,
            0.0f,0.0f,
            1.0f,1.0f,
            0.0f,1.0f,
            //左
            1.0f,0.0f,
            1.0f,1.0f,
            0.0f,0.0f,
            1.0f,1.0f,
            0.0f,0.0f,
            0.0f,1.0f,

            //右
            0.0f,0.0f,
            0.0f,1.0f,
            1.0f,0.0f,
            0.0f,1.0f,
            1.0f,0.0f,
            1.0f,1.0f,

            //上
            1.0f,1.0f,
            0.0f,1.0f,
            1.0f,0.0f,
            0.0f,1.0f,
            1.0f,0.0f,
            0.0f,0.0f,

            //下
            0.0f,0.0f,
            1.0f,0.0f,
            0.0f,1.0f,
            1.0f,0.0f,
            0.0f,1.0f,
            1.0f,1.0f

    };
    FloatBuffer cubeVerticesBuffer;
    ByteBuffer cubeFacesBuffer;
    FloatBuffer texturesVerticesBuffer;
    private Context context;
    private int texture;

    private float anglex = 1.0f;
    private float angley = 1.0f;

    public Texture3DRenderer(Context context){
     
        this.context = context;
        cubeVerticesBuffer = Utils.getFloatBuffer(cubeVertices);
        cubeFacesBuffer = Utils.getByteBuffer(cubeFaces);
        texturesVerticesBuffer = Utils.getFloatBuffer(texturesVertices);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
     
        gl.glClearColor(0.1f,0.1f,0.1f,0.0f);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthFunc(GL10.GL_LEQUAL);
        gl.glEnable(GL10.GL_TEXTURE_2D);
        loadTexture(gl);
    }



    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
     
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        float ratio = (float) width/height;
        gl.glFrustumf(-ratio,ratio,-1,1,1,10);


    }

    @Override
    public void onDrawFrame(GL10 gl) {
     
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        gl.glClear(GL10.GL_DEPTH_BUFFER_BIT);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        //所有的旋转和缩放都是在ModelView下进行的
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glTranslatef(0.0f,0.0f,-2.5f);
        gl.glRotatef(angley,0f,0.2f,0f);
        gl.glRotatef(anglex,0.2f,0f,0f);
        gl.glVertexPointer(3,GL10.GL_FLOAT,0, cubeVerticesBuffer);

        gl.glTexCoordPointer(2,GL10.GL_FLOAT,0,texturesVerticesBuffer);
        gl.glBindTexture(GL10.GL_TEXTURE_2D,texture);

        gl.glDrawElements(GL10.GL_TRIANGLES, cubeFacesBuffer.remaining(),
                GL10.GL_UNSIGNED_BYTE, cubeFacesBuffer);
        gl.glFinish();
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        anglex++;
        angley+=2;


    }
    private void loadTexture(GL10 gl) {
     
        Bitmap bitmap = null;

        bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.a1111);

        int[] textures = new int[4];
        gl.glGenTextures(1,textures,0);

        texture = textures[0];

        gl.glBindTexture(GL10.GL_TEXTURE_2D,texture);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_S,GL10.GL_REPEAT);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_T,GL10.GL_REPEAT);

        GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,bitmap,0);

    }
}


总结

在实现这个贴图的过程中当中,要注意纹理映射的顶点数组(textureVertices)中的值是要与顶点数组(cubeVertices)中的值一一对应的

你可能感兴趣的:(Android开发,android,opengles)