Android OpenGL 学习笔记 --开始篇
2010-07-09 16:41:13
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。 http://terryblog.blog.51cto.com/1764499/346996
1、什么是 OpenGL?
OpenGL 是个专业的3D程序接口,是一个功能强大,调用方便的底层3D图形库。 OpenGL 的前身是 SGI 公司为其图形工作站开的 IRIS GL。IRIS GL 是一个工业标准的3D图形软件接口,功能虽然强大但是移植性不好,于是 SGI 公司便在 IRIS GL 的基础上开发 OpenGL 。具体详细的介绍请 点击这里 。
2、OpenGL 的发展历程
OpenGL 1.0 版本,并与微软共同推出 Windows NT 版本的 OpenGL
OpenGL 1.1
OpenGL 3.2,这是一年以来 OpenGL进行的第三次重要升级。
OpenGL 现状、发展历程、 OpenGL 规范、编程入门请 点击这里 。
3、OpenGL ES 简介
引擎采用的是 OpenGL ES 。 OpenGL ES 是一套为手持和嵌入式系统设计的3D 引擎API ,由Khronos 公司维护。在PC 领域,一直有两种标准的3D API 进行竞争, OpenGL 和 DirectX 。一般主流的游戏和显卡都支持这两种渲染方式,DirectX 在Windows 平台上有很大的优势,但是 OpenGL 具有更好的跨平台性。
由于嵌入式系统和PC 相比,一般说来,CPU 、内存等都比PC 差很多,而且对能耗有着特殊的要求,许多嵌入式设备并没有浮点运算协处理器,针对嵌入式系统的以上特点,Khronos 对标准的 OpenGL 系统进行了维护和改动,以期望满足嵌入式设备对3D 绘图的要求。
4、<span times="" new="" roman'"="" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "> Android OpenGL ES 简介
系统使用 OpenGL 的标准接口来支持3D 图形功能,android 3D 图形系统也分为 java 框架和本地代码两部分。本地代码主要实现的 OpenGL 接口的库,在 Java 框架层,javax.microedition.khronos.opengles 是 java 标准的 OpenGL 包,android.opengl 包提供了 OpenGL 系统和 Android GUI 系统之间的联系。
5、Android 支持 OpenGL 列表
- 1、GL
- 2、GL 10
- 3、GL 10 EXT
- 4、GL 11
- 5、GL 11 EXT
- 6、GL 11 ExtensionPack
OpenGL
6、一步一步实现自己的 Renderer 类
OpenGL
- 1、为 Renderer 类赶回命名空间
import
android.opengl.GLSurfaceView.Renderer;
- 2、新建一个类来实现 Renderer 接口,代码如下:
public
class
ThreeDGl
implements
Renderer
{
}
- 3、如上代码所写,程序实现了 Renderer 类,则必须重写以下方法
public
void
onDrawFrame(GL10 gl)
{
}
public
void
onSurfaceChanged(GL10 gl,
int
width,
int
height)
{}
public
void
onSurfaceCreated(GL10 gl, EGLConfig config)
{}
- OpenGL 做一些初始化工作,例如:
• •
•
• //
启用阴影平滑
• gl.glShadeModel(GL10.GL_SMOOTH);
• //
黑色背景
• gl.glClearColor(
0
,
0
,
0
,
0
);
• //
设置深度缓存
• 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);
•
•
glHint 用于告诉 OpenGL 我们希望进行最好的透视修正,这会轻微地影响性能,但会使得透视图更好看。
glClearColor 设置清除屏幕时所用的颜色,色彩值的范围从 0.0f~1.0f 大小从暗到这的过程。
glShadeModel 用于启用阴影平滑度。阴影平滑通过多边形精细地混合色彩,并对外部光进行平滑。
glDepthFunc 为将深度缓存设想为屏幕后面的层,它不断地对物体进入屏幕内部的深度进行跟踪。
glEnable 启用深度测试。• OpenGL 场景大小 ,代码如下:
//
设置OpenGL场景的大小
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();
•
•
gl.glMatrixMode(GL10.GL_PROJECTION); 指明接下来的代码将影响 projection matrix (投影矩阵),投影矩阵负责为场景增加透视度。
gl.glLoadIdentity(); 此方法相当于我们手机的重置功能,它将所选择的矩阵状态恢复成原始状态,调用 glLoadIdentity(); 之后为场景设置透视图。
gl.glMatrixMode(GL10.GL_MODELVIEW); 指明任何新的变换将会影响 modelview matrix (模型观察矩阵)。
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
- 6、场景画出来了,接下来我们就要实现场景里面的内容,比如:设置它的透视图,让它有种越远的东西看起来越小的感觉,代码如下:
- 7、了解了上面两个重写方法的作用和功能之后,第三个方法 onDrawFrame 从字面上理解就知道此方法做绘制图操作的。嗯,没错。在绘图之前,需要将屏幕清除成前面所指定的颜色,清除尝试缓存并且重置场景,然后就可以绘图了, 代码如下:
//
清除屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT
|
GL10.GL_DEPTH_BUFFER_BIT);
//
重置当前的模型观察矩阵
gl.glLoadIdentity();
Renderer render =
new
ThreeDGl(
this
);
/**
Called when the activity is first created.
*/
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
GLSurfaceView gview =
new
GLSurfaceView(
this
);
gview.setRenderer(render);
setContentView(gview);
}
- 8、Renderer 类在实现了上面的三个重写之后,在程序入口中只需要调用
下面分享一段使用Renderer类绘制的三角形和四边形的代码:
OpenGL 参考代码
package com.terry;
import
java.nio.IntBuffer;
import
javax.microedition.khronos.egl.EGLConfig;
import
javax.microedition.khronos.opengles.GL10;
import
android.opengl.GLSurfaceView.Renderer;
public
class
GLRender
implements
Renderer{
float
rotateTri,rotateQuad;
int
one
=
0x10000
;
//
三角形的一个顶点
private
IntBuffer triggerBuffer
=
IntBuffer.wrap(
new
int
[]{
0
,one,
0
,
//
上顶点
-
one,
-
one,
0
,
//
左顶点
one,
-
one,
0
//
右下点
});
//
正方形的四个顶点
private
IntBuffer quateBuffer
=
IntBuffer.wrap(
new
int
[]{
one,one, 0
,
-
one,
-
one,
0
,
one, -
one,
0
,
-
one,
-
one,
0
});
private
IntBuffer colorBuffer
=
IntBuffer.wrap(
new
int
[]{
one, 0
,
0
,one,
0
,one,
0
,one,
0
,
0
,one,one
});
@Override
public
void
onDrawFrame(GL10 gl) {
//
TODO Auto-generated method stub
//
清除屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT
|
GL10.GL_DEPTH_BUFFER_BIT);
//
重置当前的模型观察矩阵
gl.glLoadIdentity();
//
左移 1.5 单位,并移入屏幕 6.0
gl.glTranslatef(
-
1.5f
,
0.0f
,
-
6.0f
);
//
设置旋转
gl.glRotatef(rotateTri,
0.0f
,
1.0f
,
0.0f
);
//
设置定点数组
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//
设置颜色数组
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glColorPointer( 4
, GL10.GL_FIXED,
0
, colorBuffer);
//
设置三角形顶点
gl.glVertexPointer(
3
, GL10.GL_FIXED,
0
, triggerBuffer);
//
绘制三角形
gl.glDrawArrays(GL10.GL_TRIANGLES,
0
,
3
);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
//
绘制三角形结束
gl.glFinish();
/**
********************
*/
/*
渲染正方形
*/
//
重置当前的模型观察矩阵
gl.glLoadIdentity();
//
左移 1.5 单位,并移入屏幕 6.0
gl.glTranslatef(
1.5f
,
0.0f
,
-
6.0f
);
//
设置当前色为蓝色
gl.glColor4f(
0.5f
,
0.5f
,
1.0f
,
1.0f
);
//
设置旋转
gl.glRotatef(rotateQuad,
1.0f
,
0.0f
,
0.0f
);
//
设置和绘制正方形
gl.glVertexPointer(
3
, GL10.GL_FIXED,
0
, quateBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0
,
4
);
//
绘制正方形结束
gl.glFinish();
//
取消顶点数组
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//
改变旋转的角度
rotateTri
+=
0.5f
;
rotateQuad -=
0.5f
;
}
@Override
public
void
onSurfaceChanged(GL10 gl,
int
width,
int
height) {
//
TODO Auto-generated method stub
float
ratio
=
(
float
) width
/
height;
//
设置OpenGL场景的大小
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
public
void
onSurfaceCreated(GL10 gl, EGLConfig config) {
//
TODO Auto-generated method stub
//
启用阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
//
黑色背景
gl.glClearColor(
0
,
0
,
0
,
0
);
//
设置深度缓存
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);
}
}
到此基本对 OpenGL 有一些了解,当然OpenGL 还有更多的东西需要我们去探索,努力吧。
本文出自 “Terry_龙” 博客,请务必保留此出处http://terryblog.blog.51cto.com/1764499/346996