1:
AndroidManifest.xml中设置<uses-sdkandroid:minSdkVersion="3" />
2:
AndroidOpenGL
第二课
在第一个教程的基础上,我们添加了一个三角形和一个四边形。也许你认为这很简单,但你已经迈出了一大步,要知道任何在OpenGL中绘制的模型都会被分解为这两种简单的图形。
读完了这一课,你会学到如何在空间放置模型,并且会知道深度缓存的概念。
其他类不变,只更改OpenGLRenderer类。
首先,我们画一个三角形
主要是在OnDrawFrame里面画,使用的函数是
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
或者
gl.glDrawElements(GL10.GL_TRIANGLES,3,GL10.GL_FLOAT,mIndexBuffer);
我们先使用drawArray,drawElement里面要多用一个indexBuffer。
第一步,定义个array
- private
float[] mTriangleArray = { -
0f,1f,0f, -
-1f,-1f,0f, -
1f,-1f,0f -
};
- package
com.xinli; -
- import
java.nio.ByteBuffer; - import
java.nio.ByteOrder; - import
java.nio.FloatBuffer; -
- public
class BufferUtil { -
public static FloatBuffer mBuffer; -
public static FloatBuffer floatToBuffer(float[] a){ -
//先初始化buffer,数组的长度*4,因为一个float占4个字节 -
ByteBuffer mbb = ByteBuffer.allocateDirect(a.length*4); -
//数组排序用nativeOrder -
mbb.order(ByteOrder.nativeOrder()); -
mBuffer = mbb.asFloatBuffer(); -
mBuffer.put(a); -
mBuffer.position(0); -
return mBuffer; -
} - }
注意:这里有个排序的问题,是使用大端(BIG_ENDIAN)还是用小端(LITTLE_ENDIAN),在android里面,opengl画图must use native order directbuffer,否则报错为ERROR/AndroidRuntime(6897):java.lang.IllegalArgumentException
这里我们直接使用allocateDirect和nativeOrder,就能满足android的要求
第二步:
在SurfaceCreate里面构建这个Buffer
mTriangleBuffer =BufferUtil.floatToBuffer(mTriangleArray);
第三步:
在OndrawFrame里面画三角形
gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
//三角形的颜色为红色,透明度为不透明
gl.glVertexPointer(3, GL10.GL_FLOAT,0,
//设置顶点,第一个参数是坐标的维数,这里是3维,第二个参数,表示buffer里面放的是float,第三个参数是0,是因为我们的坐标在数组中是紧凑的排列的,没有使用offset,最后的参数放的是存放顶点坐标的buffer
gl.glDrawArrays(GL10.GL_TRIANGLES, 0,3);
//画数组,第一个参数表示画三角形,第二个参数是first,第三个参数是count,表示在buffer里面的坐标的开始和个数
运行,会看到一个大三角形
下面,我们来变换坐标轴,画个小三角形,原理就是把坐标轴向远拉,意思就是让镜头向后拉,这样三角形就小了。
第一步:
在OnSurfaceCreate里面加入下面几行代码
- float
ratio = (float) width / height; -
gl.glMatrixMode(GL10.GL_PROJECTION); -
gl.glLoadIdentity(); -
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
这几行为透视图设置屏幕。意味着越远的东西看起来越小。这么做创建了一个现实外观的场景。此处透视按照基于窗口宽度和高度的45度视角来计算。0.1f,100.0f是我们在场景中所能绘制深度的起点和终点。
gl.glMatrixMode(GL10.GL_PROJECTION);指明接下来的两行代码将影响projectionmatrix(投影矩阵)。投影矩阵负责为我们的场景增加透视。
glMatrixMode(GL_MODELVIEW)指明任何新的变换将会影响
在OndrawFrame里面增加代码如下:
- gl.glMatrixMode(GL10.GL_MODELVIEW);
- gl.glLoadIdentity();
-
- gl.glTranslatef(-1.5f,
0.0f, -6.0f);
当您调用glLoadIdentity()之后,您实际上将当前点移到了屏幕中心,X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外。OpenGL屏幕中心的坐标值是X和Y轴上的0.0f点。中心左面的坐标值是负值,右面是正值。移向屏幕顶端是正值,移向屏幕底端是负值。移入屏幕深处是负值,移出屏幕则是正值。
glTranslatef(x, y, z)沿着
这时候就能画出个小三角形了。
下面,我们来画一个四边形
四边形的顶点数组为:
- private
float[] mQuadsArray = { -
1f,1f,0f, //右上 -
-1f,1f,0f, //左上 -
-1f,-1f,0f, //左下 -
1f,-1f,0f //右下 -
}; - //从这里可以看出,我们按照逆时针的方向画图
- private
FloatBuffer mQuadsBuffer;
在OnDrawFrame里面添加代码
gl.glLoadIdentity();
//坐标向右移1.5个单位
gl.glTranslatef(1.5f, 0.0f, -6.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT,0,
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0,4);
//画四边形
第一个参数是绘图模式,而且你现在看到两种可能的OpenGL绘图方式。
它们是:
GL_POINTS
GL_LINES
GL_LINE_LOOP
GL_LINE_STRIP
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN
我们还没有讨论点或线,所以我只介绍最后的三个
GL_TRIANGLES -
GL_TRIANGLE_STRIP - OpenGL的使用将最开始的两个顶点出发,然后遍历每个顶点,这些顶点将使用前2个顶点一起组成一个三角形。所以第三个点与第一个,第二个生成一个三角形。第四个点将于第二个,第三个生成三角形。
也就是说,0,1,2这三个点组成一个三角形,1,2,3这三个点也组成一个三角形。
GL_TRIANGLE_FAN -
也就是说,同样是0,1,2,3这4个顶点。
在STRIP状态下是,0,1,2;1,2,3这2个三角形。
在FAN状态下是,0,1,2;0,2,3这2个三角形。
这次我们将使用