暂时还未涉及3D,但这篇文章是经验之谈。以后用的到,原文地址: http://blog.sina.com.cn/s/blog_61ef49250100r41x.html
喝了两杯茶,没睡意,于是就整理了今晚的笔记,权作理顺头绪。
1.glClear --清除先前缓存中的值
函数声明:
void glClear(GLbitfield mask)
参数:
mask
按位运算符 OR 来指示要清除的缓存。参数的值可以是 GL_COLOR_BUFFER_BIT/ GL_DEPTH_BUFFER_BIT/GL_STENCIL_BUFFER_BIT
描述:
glClear是将位平面面积设置为通过调用glClearColor/glClearDepth和glClearStencil选择的 值,从而达到 忽略alpha function/blend funcion/logical operation/stenciling/ texture mapping和depth-buffering所产生的效果。
参数值的意义如下:
GL_COLOR_BUFFER_BIT:颜色缓存
GL_DEPTH_BUFFER_BIT:深度缓存
GL_STENCIL_BUFFER_BIT:模型缓存
提示:
如果一个缓存没有呈现出来,glClear将对该缓存任何影响
Errors:
如果参数是上述三个已定义参数之外的,该函数将产生一个GL_INVALID_VALUE的值
2.glLoadIdentity --用指定的矩阵代替当前矩阵
函数声明:
void glLoadIdentity(void)
描述:
glLoadIdentity用于将当前矩阵替代为一指定矩阵,其实是将当前点移到了屏幕中心,这在语义上和调 用glLoadMatrix载入一个单位矩阵
(1000010000100001)
是一样的,但是在某些情况下,glLoadIdentity效率会更高。
3.着色
OpenGL Es使用的颜色模型为RGBA(Red,Green,Blue,Alpha)。前三个分别表示红绿蓝三种 颜色的值,第 四个数表示透明度,数值范围0~1,0时为全透明,1时为不透明。
着色有两种方式:Flat coloring和Smooth coloring
Flat coloring(单调着色)
图形使用Flat coloring方式着色时,只需要在OpenGL Es进行渲染时告诉它用哪种颜色即可, 这时图形只是涂上一种固定的颜色。虽然容易使用,但是必须记住一点,当选择一个颜色,告诉 OpenGL Es使用该颜色对图形进行着色时,都会用该颜色进行着色,直到你告诉OpenGL ES 要使 用其他颜色着色。也就是说,只要一次性设置好我们需要的颜色,以后所绘制的东西都会用该颜色 着色,即使是完全采用纹理贴图的时候,仍可以调节纹理的色调,除非你告诉OpenGL Es要改变颜 色。
要告诉OpenGL Es使用哪种颜色工作,你可以用下面这个函数:
public abstract void glColor4f(float red,float green,float blue,float alpha);
各参数默认值为:red=1;green=1;blue=1;alpha=1;也就是白色。这样说明为什么在不设置颜色 时,我们绘制的图形是白色的。
我们在draw 函数中这样使用glColor4f:
public void draw(GL10 gl){
gl.glColor4f(0.5f,0.5f,1.0f,1.0f); //即将当前色设为0x8080FFFF
}
接着创建一个图形,比如正方形,然后就在渲染器Renderer的onDrawFrame函数中调用 draw函数,即可画出以该颜色着色的图形。
Smooth coloring(平滑着色)
Smooth coloring 要求你对图形的每个顶点设置颜色,然后OpenGL Es会将相邻点的颜色混合 在一起,创建出绚丽的颜色。
我们以画锥形为例,首先创建一个包含锥形各顶点的数组:
publicclassTriangle {
......
//锥形顶点坐标
float[] vertex = {
0f,1f,0f,
-1f,-1f,0f,
1f,-1f,1f,
0f,1f,0f,
1f,-1f,1f,
1f,-1f,-1f,
0f,1f,0f,
1f,-1f,-1f,
-1f,-1f,-1f,
0f,1f,0f,
-1f,-1f,-1f,
-1f,-1f,1f
};
......
注意:画图前要先了解OpenGL Es中的坐标系。当调用glLoadIdentity()后,我们就将原点移到 了屏幕的中心,左右方向为X轴,上下方向为Y轴,里外方向为Z轴。屏幕中心坐标为 (0.0f,0.0f,0.0f)。中心左边的坐标值为负值,右边为正值;移向屏幕顶端为正值,移向屏幕底 部为负值;移入屏幕深处为负值,移出屏幕为正值。
现在我们再创建一个包含各顶点颜色的数组:
//锥形各顶点颜色
float[] colors = {
1f, 0f, 0f, 1f, // 0xFF0000FF vertex 0 red
0f, 1f, 0f, 1f, // 0x00FF00FF vertex 1 green
0f, 0f, 1f, 1f, // 0x0000FFFF vertex 2 blue
1f, 0f, 1f, 1f, // 0xFF00FFFF vertex 3 magenta
1f, 0f, 0f, 1f, // 0xFF0000FF vertex 0 red
0f, 1f, 0f, 1f, // 0x00FF00FF vertex 1 green
0f, 0f, 1f, 1f, // 0x0000FFFF vertex 2 blue
1f, 0f, 1f, 1f, // 0xFF00FFFF vertex 3 magenta
1f, 0f, 0f, 1f, // 0xFF0000FF vertex 0 red
0f, 1f, 0f, 1f, // 0x00FF00FF vertex 1 green
0f, 0f, 1f, 1f, // 0x0000FFFF vertex 2 blue
1f, 0f, 1f, 1f, // 0xFF00FFFF vertex 3 magenta
1f, 0f, 0f, 1f, // 0xFF0000FF vertex 0 red
0f, 1f, 0f, 1f, // 0x00FF00FF vertex 1 green
0f, 0f, 1f, 1f, // 0x0000FFFF vertex 2 blue
1f, 0f, 1f, 1f, // 0xFF00FFFF vertex 3 magenta
};
注意:这里的颜色取值为0...1,分别对应于十进制的1到255,或者是十六进制的#00到 #FF。所以最好能在后面写下十六进制数,这样在以后的阅读中就能很快知道采用了哪种颜色。
创建后我们需要将其载入缓冲区中:
publicTriangle() {
//顶点坐标数组
ByteBuffer vBuffer = ByteBuffer.allocateDirect(vertex.length*4);
vBuffer.order(ByteOrder.nativeOrder());
triangleBuffer= vBuffer.asFloatBuffer();
triangleBuffer.put(vertex);
triangleBuffer.position(0);
//缓冲区大小,字节类型,Float有4个Byte
ByteBuffer cBuffer = ByteBuffer.allocateDirect(colors.length*4);
//分配字节顺序与java虚拟机所在的硬件相同的缓冲区
//本机代码库通常使用此类缓冲区时更有效
cBuffer.order(ByteOrder.nativeOrder());
//创建vBuffer缓冲区的视图,作为float缓冲区
colorBuffer= cBuffer.asFloatBuffer();
//将数组放入缓冲区中
colorBuffer.put(colors);
//设置缓冲区中指针的位置
colorBuffer.position(0);
}
当然,我们需要先声明变量colorBuffer和triangleBuffer:
privateFloatBuffer triangleBuffer;
privateFloatBuffer colorBuffer;
在draw函数中,我们就可以添加绘制锥形的代码了:
publicvoiddraw(GL10 gl) {
//告诉opengl以顺时针顺序按坐标显示该物体
gl.glFrontFace(GL10.GL_CCW);
//允许设置定点
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//开启颜色渲染功能
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
//设置三角形颜色
gl.glColorPointer(4, GL10.GL_FLOAT,0,colorBuffer);
//设置三角形顶点
gl.glVertexPointer(3, GL10.GL_FLOAT,0,triangleBuffer);
//绘制三角形
for(inti=0;i<4;i++){
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,i*3,3);
}
//关闭颜色设置
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
//取消定点设置
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
最后在GLRender类中实例化Triangle并在onDrawFrame方法中添加绘制代码即可。
创建Triangle对象:
publicGLRender(){
triangle= newTriangle();
}
添加绘制代码:
@Override
publicvoidonDrawFrame(GL10 gl) {
// TODOAuto-generated method stub
//清除屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
//重置当前的模型观察矩阵
gl.glLoadIdentity();
//移入屏幕6.0个单位
gl.glTranslatef(0.0f, 0.0f, -6.0f);
//绘制三角形
triangle.draw(gl);
}
要运行起来还得重载Renderer的两个方法:onSurfaceChanged和onSurfaceCreated
@Override
publicvoidonSurfaceChanged(GL10 gl, intwidth, intheight) {
// TODOAuto-generated method stub
floatratio = (float)width/height;
if(height==0) {
height = 1;
}
//设置Open场景大小
gl.glViewport(0, 0, width, height);
//设置投影矩阵
gl.glMatrixMode(GL10.GL_PROJECTION);
//重置投影矩阵
gl.glLoadIdentity();
//设置视口的大小
gl.glFrustumf(-ratio,ratio,-1, 1, 1, 10);
//选择模型观察矩阵
gl.glMatrixMode(GL10.GL_MODELVIEW);
//重置模型观察矩阵
gl.glLoadIdentity();
}
@Override
publicvoidonSurfaceCreated(GL10 gl, EGLConfig config) {
// TODOAuto-generated method stub
//黑色背景
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//启动阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
//设置深度缓存
gl.glClearDepthf(1.0f);
//启动深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);
//所做深度测试的类型,小于或等于预设深度值时通过测试
gl.glDepthFunc(GL10.GL_LEQUAL);
//告诉系统对透视进行修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
}
这样我们就绘制出一个五彩缤纷的锥形了。(*^__^*)