最近学习android openGl,由于从未接触过openGL,遇到一些问题。现将问题以及关于这些问题的一些看法写出来,用于以后复习和纠正。
学习地址:Android OpenGL ES 开发教程 从入门到精通
关于onDrawFrame(GL10 gl)方法
从方法名字可以看出该法主要用于绘图,然而在实际使用中发现该方法在程序中是被反复调用的,查看GLSurfaceView源码会发现,在setRenderer时会新建一个thread线程,在run方法里有个双重检查加锁的死循环。
绘图
void glVertexPointer(GLint size,
GLenum type,
GLsizei stride,
Buffer pointer)用于传入的顶点数据
之后可通过以下两个方法绘制一个空间几何图形
使用glDrawArrays函数 使用VetexBuffer 来绘制,顶点的顺序由vertexBuffer中的顺序指定。
使用glDrawElements 可以重新定义顶点的顺序,顶点的顺序由indices Buffer 指定。
比如画一个平面的正方形可以先通过
private float[] vertices={
-1.0f,1f,0f,
-1f,-1f,0f,
1f,-1f,0f,
1f,1f,0f
};
声明一个顶点数组,4个点依顺序由x,y,z坐标轴表示,再将这个数组转化为floatbuffer;
然后可以选择用glDrawElements 绘图,使用该方法绘图还需要一个buffer用于指定顺序,同样声明一个数组
private short[] indices={0,1,2,0,2,3};
在openGl中面指三角形所以由两三角形组成正方形所以0,1,2和0,2,3分别组成一个三角形(0,1,2,3都是指的顶点即第几个顶点)
关于旋转和平移动画
在openGl中对图像的动画操作其实是不断的改变其坐标轴的位置来实现的,坐标轴位置改变那么相应的图像位置也就改变了。
平移是通过x,y,z来确定一个矢量,按矢量方向将坐标轴向该方向平移
旋转时以矢量方向为轴以参数angle为角度旋转,angle为正时逆时针,为负时顺时针 gl.glRotatef(angle, 0f, 0f, 1f)和 gl.glRotatef(-angle, 0f, 0f, -1f);的效果相同的但是本质是不同的一个以正方向做逆时针旋转,一个以负方向做顺时针旋转。
平移和旋转的组合
两者顺序不同造成的结果是截然不同的;
glPushMatrix()和glPopMatrix()方法
glPushMatrix()方法用于将当前坐标轴的状态放到栈顶而glPopMatrix()就是把栈顶的坐标轴状态取出来
比如说我们要做一个类似于地球太阳月亮的天体模型但要求地球要围绕太阳自转的反方向旋转
首先在中央坐标轴时用push放到栈顶然后对画出太阳并让他自转之后用pop取出中央坐标轴那么现在所处坐标轴便是最初的坐标轴而不会随着太阳自转如果不这样做那么设置太阳自转后整个坐标轴也在自转那么要想反方向旋转是不能做到的
实战案例:图像a自转,图像b围绕a自转反方向旋转,图像c围绕b旋转并自转
下面贴出ondrawframe中部分代码
gl.glPushMatrix();
gl.glRotatef(angle, 0f, 0f, 1f);
mSquare.draw(gl);//自定义类用于画图像
gl.glPopMatrix();
gl.glPushMatrix();
gl.glRotatef(-angle, 0f, 0f, 1f);
gl.glTranslatef(2, 0, 0);
mSquare.draw(gl);
gl.glPushMatrix();
gl.glRotatef(-angle,0,0,1);
gl.glTranslatef(2,0,0);
gl.glRotatef(-angle*10,0,0,1);
mSquare.draw(gl);
gl.glPopMatrix();
gl.glPopMatrix();
angle++;//全局变量用于控制旋转