初识openGL---openGL学习笔记(一)
2016-02-24 17:04
337 查看
openGL:
openGL是用C语言实现的,而我们作为安卓开发者,严格来讲,我们使用的是es,也就是openGL es,原因无非就像数据库一样,安卓上使用的数据库永远不可能是Mysql之类的,因为终端讲究轻量。
接下来我们来创建第一个openGL项目:
首先我们来了解一下GLSurfaceView这个类,这个类相当于是在屏幕上的一个模板,如下图。
![](https://img-blog.csdn.net/20160224171433588?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
所以,创建一个类继承[b]GLSurfaceView之后,我们就可以new出GLSurfaceView类的对象,调用GLSurfaceView类的对象的setRenderer()方法,就可以对GLSurfaceView进行渲染,而我们的主要工作是,如何进行渲染。[/b]
那么就要自定义一个渲染器:new一个类实现Renderer,需重写三个方法:onSurfaceCreated,onSurfaceChanged和onDrawFrame。
显而易见,onSurfaceCreated和onSurfaceChanged都是在做初始化工作,关键的是onDrawFrame方法:
需要注意的是,[b]onSurfaceChanged中设置的平截头体,所谓平截头体就是一个类似棱锥的区域,如下图:[/b]
![](https://img-blog.csdn.net/20160224173913994?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
最左边的眼睛通过中间墙上的孔,可以看得见与孔相同比例的空间,那么墙上的孔到墙后景物中间的四棱锥,就是一个平截头体。墙上的孔叫近平面,后方景物叫远平面。因为光是直射的,所以,我们只要指定好近平面的比例,以及图中两段红线的比例,那么就能确定远平面,继而确定平截头体。
[b]确定了平截头体之后,就要关注onDrawFrame方法,类似于拍照的过程,我确定了要拍什么之后,还是要确定拍照时候要确定相机的位置,相机的朝向,相机的反正。这个三个属性就对应了程序中的GLU.gluLookAt()方法。详细参数见代码注释。[/b]
[b]通过这几步之后,还是不能拍照,因为我们还有一些参数没有设置,比如绘图颜色。上例程序中是画了一个三角形,那么还需指定三角形的三点坐标等等,具体细节代码中注释的很详细,不再赘述。[/b]
[b]上例代码运行效果图:
![](https://img-blog.csdn.net/20160224175937152?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
[/b]
openGL是用C语言实现的,而我们作为安卓开发者,严格来讲,我们使用的是es,也就是openGL es,原因无非就像数据库一样,安卓上使用的数据库永远不可能是Mysql之类的,因为终端讲究轻量。
接下来我们来创建第一个openGL项目:
首先我们来了解一下GLSurfaceView这个类,这个类相当于是在屏幕上的一个模板,如下图。
所以,创建一个类继承[b]GLSurfaceView之后,我们就可以new出GLSurfaceView类的对象,调用GLSurfaceView类的对象的setRenderer()方法,就可以对GLSurfaceView进行渲染,而我们的主要工作是,如何进行渲染。[/b]
class MyGLSurfaceView extends GLSurfaceView{ public MyGLSurfaceView(Context context) { super(context); } public MyGLSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); } }
那么就要自定义一个渲染器:new一个类实现Renderer,需重写三个方法:onSurfaceCreated,onSurfaceChanged和onDrawFrame。
//自定义渲染器 class MyRenderer implements GLSurfaceView.Renderer{ //表层创建时调用 @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { //设置清屏色 gl.glClearColor(0, 0, 0, 1); //启用顶点缓冲区 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); } //当表层size改变时调用 @Override public void onSurfaceChanged(GL10 gl, int width, int height) { //设置视口,输出画面的区域。 gl.glViewport(0,0,width,height); //宽高比 float ratio = (float)width/(float)height; //矩阵模式,投影矩阵,openGL基于状态机。 gl.glMatrixMode( GL10.GL_PROJECTION ); //加载单位矩阵 gl.glLoadIdentity(); //设置平截头体 gl.glFrustumf(-1f,1f,-ratio,ratio,3,7); //-1f,1f为平截头体左右大小比,-ratio,ratio为平截头体底面和顶面,3,7为近平面和原平面距离 } //绘图调用 @Override public void onDrawFrame(GL10 gl) { //清除颜色缓冲区。 gl.glClear(GL10.GL_COLOR_BUFFER_BIT); //模型视图矩阵。 gl.glMatrixMode( GL10.GL_MODELVIEW ); //加载单位矩阵。 gl.glLoadIdentity(); //0,0,5:放置眼球的坐标。 //0,0,0:眼球观察的中心点坐标。 //0,1,0:指定眼球向上的向量。 GLU.gluLookAt(gl,0,0,5,0,0,0,0,1,0); /** * 画三角形 */ //三角形顶点坐标 float [] coords = { 0f,0.5f,0f, -0.5f,-0.5f,0f, 0.5f,-0.5f,0f }; //分配字节缓存空间,存放顶点坐标数据。 ByteBuffer ibb = ByteBuffer.allocateDirect(coords.length * 4); //设置顺序(本地顺序)。 ibb.order(ByteOrder.nativeOrder()); //放置顶点数组。 FloatBuffer fbb = ibb.asFloatBuffer(); fbb.put(coords); //定位指针位置,从该位置开始读取顶点数据。 ibb.position(0); //设置绘图颜色:红色。 gl.glColor4f(1f,0,0,1f); //3→三维点,使用三个坐标表示一个点。 //每个点的数据类型。 //0→跨度。 //ibb指定缓冲区。 gl.glVertexPointer(3,GL10.GL_FLOAT,0,ibb); //画数组 gl.glDrawArrays(GL10.GL_TRIANGLES,0,3); } }
显而易见,onSurfaceCreated和onSurfaceChanged都是在做初始化工作,关键的是onDrawFrame方法:
需要注意的是,[b]onSurfaceChanged中设置的平截头体,所谓平截头体就是一个类似棱锥的区域,如下图:[/b]
最左边的眼睛通过中间墙上的孔,可以看得见与孔相同比例的空间,那么墙上的孔到墙后景物中间的四棱锥,就是一个平截头体。墙上的孔叫近平面,后方景物叫远平面。因为光是直射的,所以,我们只要指定好近平面的比例,以及图中两段红线的比例,那么就能确定远平面,继而确定平截头体。
[b]确定了平截头体之后,就要关注onDrawFrame方法,类似于拍照的过程,我确定了要拍什么之后,还是要确定拍照时候要确定相机的位置,相机的朝向,相机的反正。这个三个属性就对应了程序中的GLU.gluLookAt()方法。详细参数见代码注释。[/b]
[b]通过这几步之后,还是不能拍照,因为我们还有一些参数没有设置,比如绘图颜色。上例程序中是画了一个三角形,那么还需指定三角形的三点坐标等等,具体细节代码中注释的很详细,不再赘述。[/b]
[b]上例代码运行效果图:
[/b]
相关文章推荐
- 解决Vista系统OpenGL驱动问题的方法整理
- Delphi下OpenGL2d绘图之画四边形的方法
- Delphi下OpenGL2d绘图之画点的方法
- Delphi下OpenGL2d绘图之初始化流程详解
- Delphi使用OpenGL2d绘图之画图片Bmp的方法
- 通过OpenGL ES混合模式缩放视频缓冲区来适应显示尺寸
- VC运用OPENGL加载BMP纹理图的实现方法汇总
- java实现OpenGL ES纹理映射的方法
- java基于OpenGL ES实现渲染实例
- OpenGL坐标系介绍
- 【翻译】安卓opengl ES教程之四——添加颜色
- linux下opengl的安装(with qt)
- OpenGL超级宝典笔记——显示列表
- OpenGL超级宝典笔记——顶点数组
- OpenGL生成轮廓
- OpenGL超级宝典笔记——性能比较
- OpenGL超级宝典笔记——顶点缓冲区对象
- OpenGL超级宝典笔记——选择
- OpenGL超级宝典笔记——反馈
- OpenGL超级宝典笔记——遮挡查询