本文由Pro Android2相关章节整理而来。
大家知道,Android内置了OpenGL可以用来处理2D和3D图形,下面简单了解一下OpenGL的基础知识。将会涉及到以下API:
glVertexPointer
glDrawElements
glColor
glCLear
gluLookAt
glFrustum
glViewPort
通过如上API的学习我们学习到如何
- 使用基本的OpenGL ES 绘图API
- 清除调色板
- 定义颜色
- 理解OpenGL 相机和坐标
一、使用OpenGL进行基本的画图
在OpenGL中,你是在3D空间中作图,每一个点都有三个坐标x/y/z,一些点可以组合成某些原始形状,比如点,线,三角等。OpenGL ES提供了两个主要的方法辅助绘图:
- glVertextPointer
- glDrawElements
可以使用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)
};
jva.nio.ByteBuffer vbb = java.nio.ByteBuffer.allocateDirect(3 * 3 * 4);
vbb.order(ByteOrder.nativeOrder());
java.nio.FloatBuffer mFVertexBuffer = vbb.asFloatBuffer();
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);
第二个参数表示坐标值应当被解析为float类型(这样OpenGL就可以知道每个值占用几位),第三个参数可以称为“步长”,代表每个点之间有几位分割。本例中,0代表一个点挨着一个点,有时候你可能会在点的后面定义颜色,这时,你应该指出每个颜色占用的位长,以便OpenGL在解析时跳过这段长度。
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);
一开始,怎么也没弄明白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。
//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]);
}
终于完成了,累个半死。。。。