Android之OpenGL ES基础知识篇

    技术2022-05-19  25

    本文由Pro Android2相关章节整理而来。

    大家知道,Android内置了OpenGL可以用来处理2D和3D图形,下面简单了解一下OpenGL的基础知识。将会涉及到以下API:

    glVertexPointerglDrawElementsglColorglCLeargluLookAtglFrustumglViewPort

    通过如上API的学习我们学习到如何

    使用基本的OpenGL ES 绘图API清除调色板定义颜色理解OpenGL 相机和坐标

    一、使用OpenGL进行基本的画图

        在OpenGL中,你是在3D空间中作图,每一个点都有三个坐标x/y/z,一些点可以组合成某些原始形状,比如点,线,三角等。OpenGL ES提供了两个主要的方法辅助绘图:

    glVertextPointerglDrawElements

        可以使用glVertextPointer来定义一系列的点或者一个面,而glDrawElements则用来把它们画出来。OpenGL中所有的方法都以gl开头,gl之后跟着方法名。

        glVertextPointer用来表示一组点,每一个点都有三个坐标,所以每个点会有三个值:x,y和z,如下所示在一个数组中定义了三个点代表一个三角形:

    float[] coords = { -0.5f, -0.5f, 0, //p1: (x1,y1,z1) 0.5f, -0.5f, 0, //p2: (x1,y1,z1) 0.0f, 0.5f, 0 //p3: (x1,y1,z1) };  想要把上面的点画出来,你需要把它们传给OpenGL ES的glVertexPointer方法。为了更有效,glVertexPointer接受一个native buffer而不是float数组。所以需要将java基本类型的数组转化为一个类似于C语言的native buffer类型,如下代码演示了如何使用nio buffers:

    jva.nio.ByteBuffer vbb = java.nio.ByteBuffer.allocateDirect(3 * 3 * 4); vbb.order(ByteOrder.nativeOrder()); java.nio.FloatBuffer mFVertexBuffer = vbb.asFloatBuffer();  当把点转换成native buffer后,就可以使用如下方式调用glVertexPointer了:

    glVertexPointer( // Are we using (x,y) or (x,y,z) in each point 3, // each value is a float value in the buffer GL10.GL_FLOAT, // Between two points there is no space 0, // pointer to the start of the buffer mFVertexBuffer);      然后来看一下各个参数的意义:第一个参数代表每个点或者顶点用几个坐标表示,本例中使用三个xyz。你也可以指定两个只用xy,这样话,z就为0.需要注意的是,第一个参数并不代表有几个点,如果你想要使用20个点来代表一个三角形,这里你需要传入的不是20而是2或3.

        第二个参数表示坐标值应当被解析为float类型(这样OpenGL就可以知道每个值占用几位),第三个参数可以称为“步长”,代表每个点之间有几位分割。本例中,0代表一个点挨着一个点,有时候你可能会在点的后面定义颜色,这时,你应该指出每个颜色占用的位长,以便OpenGL在解析时跳过这段长度。

        再来看glDrawElements ,当你通过glVertexPointer定义了一系列的点之后,你可以使用glDrawElements方法来画出OpenGL ES所允许的一些原始形状。注意OpenGL是有状态的,在执行下一个方法时,他能够记住前面方法的值,所以,你不必显式的将glVertexPointer传递给glDrawElement,glDrawElements就可以直接使用那些点。如下代码是这个方法的简单示例glDrawElements( // type of shape GL10.GL_TRIANGLE_STRIP, // Number of indices 3, // How big each index is GL10.GL_UNSIGNED_SHORT, // buffer containing the 3 indices mIndexBuffer);  其中第一个参数代表你想要画的几何图形(GL_TRIANGLE_STRIP代表一个三角strip)。其他可能的选项包括GL_POINTS,GL_LINE_STRIP,GL_LINES,GL_LINE_LOOP,GL_TRIANGLES和G:_TRIANGLE_FAN。

        一开始,怎么也没弄明白Strip的意思,查看翻译有“脱衣舞#条, 带; 连环漫画; 细长片;”的意思,具体介绍请参考这篇文章:http://hi.baidu.com/guopprui/blog/item/ed414525ea09943b8744f9f2.html

        glDrawElements其它的参数可以让你重用预定义的带你。比如说,一个四边形包括四个点,每一个四边形可以用两个三角形组合而来。如果你想使用两个三角形组合成一个四边形,你有必要去定义6个点吗?当然不是,你只需要定义四个点,然后引用6次画出两个三角形就可以了,这种处理被称为“indexing into the point buffer”如下所示:

    Points:(p1,p2,p3,p4)

    Draw indices(p1,p2,p3,   p2,p3,p4)

        知道了这些,glDrawElements的第二个参数就好理解了,它代表了index buffer中有几个坐标标示(可以理解为点)。

        第三个参数代表index 数组中值的类型,是GL_UNSIGNED_SHORT还是GL_UNSIGNED_BYTE。

        最后一个参数引用index buffer。为了填补index buffer,你需要像vertex buffer一样,做一些其他的工作,进行相应的转化,如下所示://Figure out how you want to arrange your points short[] myIndecesArray = {0,1,2}; //get a short buffer java.nio.ShortBuffer mIndexBuffer; //Allocate 2 bytes each for each index value ByteBuffer ibb = ByteBuffer.allocateDirect(3 * 2); ibb.order(ByteOrder.nativeOrder()); mIndexBuffer = ibb.asShortBuffer(); //stuff that into the buffer for (int i=0;i<3;i++) { mIndexBuffer.put(myIndecesArray[i]); }  


    终于完成了,累个半死。。。。

     

     


    最新回复(0)