Android OpenGL ES学习笔记之绘制一个立方体

前言

前面已经讲了如何绘制点、线、面,现在就来绘制一个立方体,OpenGL ES中任何一个立体图形都是由很多面组成的,这个面指的就是三角形,所以绘制立方体就是绘制多个三角形而组合起来。

绘制

立方体有6个面,左、右、前、后、上、下。共有8个顶点,每个面有4个顶点,代码如下
PS:一定要注意顶点的顺序,不能随意选择

        // 定义立方体的8个顶点  
        float[] cubeVertices = {               
                //左面 
                  -0.5f,0.5f,0.5f,
                  -0.5f,-0.5f,0.5f,
                  -0.5f,0.5f,-0.5f,
                  -0.5f,-0.5f,-0.5f,

                //右面
                  0.5f, 0.5f,0.5f,                
                  0.5f,-0.5f,0.5f,
                  0.5f,-0.5f,-0.5f,
                  0.5f,0.5f,-0.5f ,

                //前面
                 -0.5f,0.5f,0.5f,
                 -0.5f,-0.5f,0.5f,
                  0.5f,-0.5f,0.5f,
                  0.5f, 0.5f,0.5f,

                //后面 
                  0.5f,-0.5f,-0.5f,
                  0.5f,0.5f,-0.5f, 
                 -0.5f,0.5f,-0.5f,
                 -0.5f,-0.5f,-0.5f,

                //上面
                 -0.5f,0.5f,0.5f,
                  0.5f, 0.5f,0.5f,
                  0.5f,0.5f,-0.5f,
                  -0.5f,0.5f,-0.5f,

                //下面
                  -0.5f,-0.5f,0.5f,
                  0.5f,-0.5f,0.5f,
                  0.5f,-0.5f,-0.5f,
                  -0.5f,-0.5f,-0.5f
         };  

然后定义一个颜色数组

       //  颜色数组 
       float []  cubeColors = {   
                1f,0f,0f,1f ,  
                0f,1f,0f,1f,  
                0f,0f,1f,1f,  
                1f,0f,0f,1f,  

                1f,0f,0f,1f ,  
                0f,1f,0f,1f,  
                0f,0f,1f,1f,  
                1f,0f,0f,1f, 

                1f,0f,0f,1f ,  
                0f,1f,0f,1f,  
                0f,0f,1f,1f,  
                1f,0f,0f,1f, 

                1f,0f,0f,1f ,  
                0f,1f,0f,1f,  
                0f,0f,1f,1f,  
                1f,0f,0f,1f, 


                1f,0f,0f,1f ,  
                0f,1f,0f,1f,  
                0f,0f,1f,1f,  
                1f,0f,0f,1f, 

                1f,0f,0f,1f ,  
                0f,1f,0f,1f,  
                0f,0f,1f,1f,  
                1f,0f,0f,1f, 
           };    

然后是获取浮点型缓冲数据

            //获取浮点形缓冲数据
            VerticesBuffer = Utils.getFloatBuffer(cubeVertices);
            //获取浮点型颜色数据
            Colorbuffer= Utils.getFloatBuffer(cubeColors);

为了能看到立体的效果,就让这个矩阵一直绕Y轴旋转。因为默认的是一直绘制的渲染模式,所以指定一个角度,每次都加1即可。另外指定绘制线的模式为 GL_TRIANGLE_STRIP 。即相邻三个顶点绘制一个三角形。

代码如下


        @Override
        public void onDrawFrame(GL10 gl) { 
        // 清除屏幕缓存和深度缓存  
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);  
            // 启用顶点座标数据  
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  
            // 启用顶点颜色数据  
            gl.glEnableClientState(GL10.GL_COLOR_ARRAY);  

             // 重置当前的模型视图矩阵  
             gl.glLoadIdentity();  
             // 沿着Y轴旋转  
             gl.glRotatef(rotate, 0f, 1f, 0f);  

             // 设置顶点的位置数据  
            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, VerticesBuffer);  

            // 设置顶点的颜色数据  
            gl.glColorPointer(4, GL10.GL_FLOAT, 0, Colorbuffer);  

            //绘制三角形  
            gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP  , 0, 24); 

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

            // 旋转角度增加1  
            rotate-=1;  
           }

效果如下:

这里写图片描述

可以看到有很多三角形,那么这并不是我们想要的效果,这时候要用到索引了。


索引绘制

索引就是让不同的顶点按照规定的顺序来绘制,这样就不会导致各种三角形的错乱。

首先定义一个索引数组,这里的0,1,2等指的是顶点顺序,比如0,1,2就是按照0,1,2的顺序绘制三角形,0,2,3就是按照02,3的顺序绘制三角形,就不会出现0,1,2 和1,2,3 以及 023都绘制的情况。

       //索引数组
       private short[] indices={  
                0,1,2,  
                0,2,3,  

                4,5,6,  
                4,6,7,  

                8,9,10,  
                8,10,11,  

                12,13,14,  
                12,14,15,  

                16,17,18,  
                16,18,19,  

                20,21,22,  
                20,22,23,  
        };  

获取浮点型索引数据

//获取浮点型索引数据
indexbuffer= Utils.getShortBuffer(indices);

最后在onDrawFrame方法里,把以下去掉

     //绘制三角形  
     //gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP  , 0, 24); 

换成

gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexbuffer);  

这里讲一下glDrawElements方法,Android OpenGL ES学习笔记之绘制点
里讲了
OpenGL ES提供了两类方法来绘制一个空间几何图形:

 -public abstract void glDrawArrays(int mode, int first, int count) 使用VetexBuffer 来绘制,顶点的顺序由vertexBuffer中的顺序指定。


 - public abstract void glDrawElements(int mode, int count, int type, Buffer indices) ,可以重新定义顶点的顺序,顶点的顺序由indices Buffer 指定。

glDrawElements各个参数如下:

 - mode——指明被渲染的是哪种图元,被允许的符号常量有GL_POINTS,GL_LINE_STRIP,GL_LINE_LOOP,GL_LINES,GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN 和GL_TRIANGLES

 - count——指明被渲染的元素个数。

 - type——指明索引指的类型,不是GL_UNSIGNED_BYTE 就是GL_UNSIGNED_SHORT。

 - indices——指明存储索引的位置指针。

现在看下效果

这里写图片描述

总结

绘制正方体就这样完成了。
Demo地址:点击打开
密码:arxc

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