android OpenGL学习笔记(二)

关于几何图形的描述:

文章的代码是程序在程序的代码中找的到。

3D模型由一些更小的元素(点,线,面,多边形)组成。

(1)顶点(Vertex)

在android中,我们需要定义一个浮点型的数组来保存顶点位置,并且这个浮点型数组转换位数组(这样可以提高性能)。

//四边形的顶点坐标,这四个顶点按照0,1,2,3的次序来排列,次序为了画图用,在第三部分讲解画几何图形的时候,会用到这个次序

privatefloatvertices[]={

-1.0f,1.0f,0.0f,//0,TopLeft

-1.0f,-1.0f,0.0f,//1,BottomLeft

1.0f,-1.0f,0.0f,//2,BottomRight

1.0f,1.0f,0.0f,//3,TopRight

}

//将顶点浮点型数组转换为位数组

privateFloatBuffervertexBuffer;

ByteBufferbyteBuf=ByteBuffer.allocateDirect(vertices.length*4);

byteBuf.order(ByteOrder.nativeOrder());

vertexBuffer=byteBuf.asFloatBuffer();

vertexBuffer.put(vertices);

vertexBuffer.position(0);

/*OpenglES有一些提供渲染的功能,这些功能大部分情况下,不能使用,如果你想使用,

*你必须记得打开这些函数功能,你也可能需要告诉这些功能需要和什么对象配合使用。

*下面的两行代码的意思是,在渲染过程中,能写或者使用顶点数组,并且指明这些顶点数组的位置。

*/

//指明这些顶点数组的位置

gl.glVertexPointer(3,GL10.GL_FLOAT,0,vertexBuffer);

//能写和使用顶点数组

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

(2)面(Face)

Face是一个三角形,也就是三个点和三个边围起来的面积。

设置Face的旋转方向是很重要的,因为选择不同的旋转方向意味这选择那一面为前面,那一面为后面。为什么这是重要的那?因为在一个由完全不透明的表面组成的场景中,多边形的后面部分是绝不可能看到的,有时候为了提升性能,需要只描绘正面,而后面的图形就省略部描绘,可以通过为函数glEnable(GL_CULL_FACE)和glDisable(GL_CULL_FACE)来决定是否省略描绘后面部分的图形。可以通过函数glFrontFace来改变方向从而决定多边形的那一面为正面。

glFrontFace:常量参数GL_CCW表示逆时针,GL_CW表示顺时针。默认情况下,逆时针的多边形坐标顺序是多边形是正面。例如对于三角形:

vertices[]={

0,1,0,

-1,-1,0,

1,-1,0

}

如果添加glEnable(GL_CULL_FACE)功能,逆时针可以正常显示图形,顺时针无法显示图形。

glCullFace:函数决定绘制多边形的背面还是正面。

(3)多变形(Polygon)

在前面已经介绍了四边行的四个顶点,次序也在数组vertices中排列好了,即第一个顶点的序号为0({-1.0f,1.0f,0.0f}),第二个顶点序号为1({-1.0f,-1.0f,0.0f})等。

现在说如何画这个四边型,前面已经设定Face的旋转为逆时针,数组vertices组成的是一个四边型,四边型由两个Face(也就是三角形)组成,按照逆时针画两个三角形,即组成一个四边行,第一个三角形的顶点顺序为0、1、2,即vertices中的前三个顶点组成的三角形,0、2、3三个顶点按照逆时针的顺序组成第二个三角形。这个过程组成了一个顺序数组如下:

privateshort[]indices={0,1,2,0,2,3};

为了提高性能,将数组转换为位数组,代码如下:

//shortis2bytes,thereforewemultiplythenumberifverticeswith2.

ByteBufferibb=ByteBuffer.allocateDirect(indices.length*2);

ibb.order(ByteOrder.nativeOrder());

ShortBufferindexBuffer=bb.asShortBuffer();

indexBuffer.put(indices);

indexBuffer.position(0);

(4)渲染(Render)

函数glDrawArrays和glDrawElements用来将上面的设置画在屏幕上。这两个函数的有一个相同的参数mode,接受GL_POINTS、GL_LINE_STRIP、GL_LINE_LOOP、GL_LINES、GL_TRIANGLES等常量。下面简单介绍一个常量的意思,

GL_POINTS:表示只画顶点;

GL_LINE_STRIP:从第一个顶点画到最后一个点;

GL_LINE_LOOP:和GL_LINE_STRIP相似,只是最后一点和第一个点链接,形成一个环路;

GL_LINES:每两个点画一条直线;

GL_TRIANGLES:没三个点为一组画成一个个的三角形;

GL_TRIANGLE_STRIP:按一定的顺序画一系列三角形如按照顶点v0,v1,v2,然后v2,v1,v3(注意顺序),最后v2,v3,v4,确定这些三角形能正确的形成一个多边形;

GL_TRIANGLE_FAN:相似GL_TRIANGLE_STRIP,但是顺序是v0,v1,v2,然后v0,v2,v3,最后v0,v3,v4,注意和GL_TRIANGLE_STRIP顺序区别;

publicabstractvoidglDrawArrays(intmode,intfirst,intcount):按照前面verticesBuffer数组的顶点来画图形。

publicabstractvoidglDrawElements(intmode,intcount,inttype,Bufferindices):需要知道顶点的顺序,才能画图行。在第三部分关于多边形的内容中,指定了顶点的顺序。type类型的含义是指明indices数组的类型,比如GL10.GL_UNSIGNED_SHORT,表示indices是short类型的数组。

参考的网站:

http://insanitydesign.com/wp/projects/nehe-android-ports/

相关推荐