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/