android OpenGL es lession2

第二课你的第一个多边形:

添加一个三角形和一个四边形。也许你认为这很简单,但你已经迈出了一大步,要知道任何在OpenGL中绘制的模型都会被分解为这两种简单的图形。

其他类不变,只更改OpenGLRenderer类。

首先,我们画一个三角形

主要是在OnDrawFrame里面画,使用的函数是

gl.glDrawArrays(GL10.GL_TRIANGLES,0,3);

或者

gl.glDrawElements(GL10.GL_TRIANGLES,3,GL10.GL_FLOAT,mIndexBuffer);

我们先使用drawArray,drawElement里面要多用一个indexBuffer。

第一步,定义个array

privatefloat[]mTriangleArray={

0f,1f,0f,

-1f,-1f,0f,

1f,-1f,0f

};

privatefloat[]mTriangleArray={0f,1f,0f,-1f,-1f,0f,1f,-1f,0f};

这里实际上是定义了三角形的三个顶点,三个数分别是x,y,z的坐标,和数学里直角坐标系相同

0f,1f,0f是上顶点

-1f,-1f,0f是左下顶点

1f,-1f,0f是右下顶点

定义个FloatBuffer,这是android画三角形必须的结构

privateFloatBuffermTriangleBuffer;

来一个函数转换array到Buffer

我们直接上一个工具类

publicclassBufferUtil{

publicstaticFloatBuffermBuffer;

publicstaticFloatBufferfloatToBuffer(float[]a){

//先初始化buffer,数组的长度*4,因为一个float占4个字节

ByteBuffermbb=ByteBuffer.allocateDirect(a.length*4);

//数组排序用nativeOrder

mbb.order(ByteOrder.nativeOrder());

mBuffer=mbb.asFloatBuffer();

mBuffer.put(a);

mBuffer.position(0);

returnmBuffer;

}

}

注意:这里有个排序的问题,是使用大端(BIG_ENDIAN)还是用小端(LITTLE_ENDIAN),

在android里面,opengl画图mustusenativeorderdirectbuffer,

否则报错为ERROR/AndroidRuntime(6897):java.lang.IllegalArgumentException:MustuseanativeorderdirectBuffer这个错误在android1.6以上会出现,在1.5上不会出现。

这里我们直接使用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,mTriangleBuffer);

//设置顶点,第一个参数是坐标的维数,这里是3维,第二个参数,表示buffer里面放的是float,第三个参数是0,是因为我们的坐标在数组中是紧凑的排列的,没有使用offset,最后的参数放的是存放顶点坐标的buffer

gl.glDrawArrays(GL10.GL_TRIANGLES,0,3);

//画数组,第一个参数表示画三角形,第二个参数是first,第三个参数是count,表示在buffer里面的坐标的开始和个数

运行,会看到一个大三角形

下面,我们来变换坐标轴,画个小三角形,原理就是把坐标轴向远拉,意思就是让镜头向后拉,这样三角形就小了。

第一步:

在OnSurfaceChanged里面加入下面几行代码

floatratio=(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(投影矩阵)。投影矩阵负责为我们的场景增加透视。glLoadIdentity()近似于重置。它将所选的矩阵状态恢复成其原始状态。调用glLoadIdentity()之后我们为场景设置透视图。

glMatrixMode(GL_MODELVIEW)指明任何新的变换将会影响modelviewmatrix(模型观察矩阵)。模型观察矩阵中存放了我们的物体讯息。最后我们重置模型观察矩阵。如果您还不能理解这些术语的含义,请别着急。在以后的教程里,我会向大家解释。只要知道如果您想获得一个精彩的透视场景的话,必须这么做。

在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)沿着X,Y和Z轴移动。根据前面的次序,下面的代码沿着X轴左移1.5个单位,Y轴不动(0.0f),最后移入屏幕6.0f个单位。注意在glTranslatef(x,y,z)中当您移动的时候,您并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置。

这时候就能画出个小三角形了。

下面,我们来画一个四边形

四边形的顶点数组为:

privatefloat[]mQuadsArray={

1f,1f,0f,//右上

-1f,1f,0f,//左上

-1f,-1f,0f,//左下

1f,-1f,0f//右下

};

//从这里可以看出,我们按照逆时针的方向画图

privateFloatBuffermQuadsBuffer;

privatefloat[]mQuadsArray={

1f,1f,0f,//右上

-1f,1f,0f,//左上

-1f,-1f,0f,//左下

1f,-1f,0f//右下};

//从这里可以看出,我们按照逆时针的方向画图

privateFloatBuffermQuadsBuffer;

在OnDrawFrame里面添加代码

gl.glLoadIdentity();

//坐标向右移1.5个单位

gl.glTranslatef(1.5f,0.0f,-6.0f);

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

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-这个参数意味着OpenGL使用三个顶点来组成图形。所以,在开始的三个顶点,将用顶点1,顶点2,顶点3来组成一个三角形。完成后,在用下一组的三个顶点来组成三角形,直到数组结束。

GL_TRIANGLE_STRIP-OpenGL的使用将最开始的两个顶点出发,然后遍历每个顶点,这些顶点将使用前2个顶点一起组成一个三角形。所以第三个点与第一个,第二个生成一个三角形。第四个点将于第二个,第三个生成三角形。

也就是说,0,1,2这三个点组成一个三角形,1,2,3这三个点也组成一个三角形。

GL_TRIANGLE_FAN-在跳过开始的2个顶点,然后遍历每个顶点,让OpenGL将这些顶点于它们前一个,以及数组的第一个顶点一起组成一个三角形。第3个点将与第二个点(前一个)和第一个点(第一个).生成一个三角形。

也就是说,同样是0,1,2,3这4个顶点。

在STRIP状态下是,0,1,2;1,2,3这2个三角形。

在FAN状态下是,0,1,2;0,2,3这2个三角形。

这次我们将使用GL_TRIANGLE_FAN,我们将在显示区域获得一个矩形。

相关推荐