iOSiOSiOS开发

OpenGL ES _ 入门_04

2016-08-31  本文已影响1819人  酷走天涯

OpenGL ES _ 入门_01
OpenGL ES _ 入门_02
OpenGL ES _ 入门_03
OpenGL ES _ 入门_04
OpenGL ES _ 入门_05
OpenGL ES _ 入门练习_01
OpenGL ES _ 入门练习_02
OpenGL ES _ 入门练习_03
OpenGL ES _ 入门练习_04
OpenGL ES _ 入门练习_05
OpenGL ES _ 入门练习_06
OpenGL ES _ 着色器 _ 介绍
OpenGL ES _ 着色器 _ 程序
OpenGL ES _ 着色器 _ 语法
OpenGL ES_着色器_纹理图像
OpenGL ES_着色器_预处理
OpenGL ES_着色器_顶点着色器详解
OpenGL ES_着色器_片断着色器详解
OpenGL ES_着色器_实战01
OpenGL ES_着色器_实战02
OpenGL ES_着色器_实战03

学习是一件开心的额事情
效果图

上篇已经提到过一些基本的概念,这里难点在于理解三维变换的组合效果,思考一个问题:从一个方向移动照相机和从相反的方向移动物体,对于观察者,看到的效果一样吗?
这个就是告诉大家,难理解的东西一定好换角度考虑问题。


glMatrixMode()
用于指定当前矩阵,可指定的模型有三种:
模型视图矩阵 GL_MODEVIEW
投影矩阵 GL_PROJECTION
纹理矩阵 GL_TEXTURE
glLoadIndentity() 将当前矩阵修改为4*4 的单位矩阵
提示:在指定模型或者视图变换之前,必须以GL_MODELVIEW 参数调用glMatrixMode()函数

接下来将最难理解的东西了,注意力集中哦!!
1.先想一下下面的场景
将位于原点的物体(0,0,0),沿着Z轴正方向移动1个单位,然后绕X轴旋转90 度
将位于原点的物体(0,0,0),绕X轴旋转90 度,然后沿着Z轴正方向移动一个单位。
很显然两者的结果不一样,这是我想说的第一点执行顺序影响变换结果。
2.先看一段代码

glMatrixModel(GL_MODELVIEW)
glLoadIndentity();
glMultMatixf(N);
glMultMatixf(M);
glMultMatixf(L);
glBegin(GL_POSITION);
glVertex3f(v);
glEnd();

经过变换后的顶点是NMLV,顶点换变得实际运算规则N(M(Lv)),顶线变换的顺序和代码顺序刚好相反,为什么呢?

答:视图和模型变换都是用44 矩阵表示的,每个后续的glMultMatrix()函数或变换函数把一个新的4*4 矩阵M雨当前模型视图矩阵相乘,产生矩阵CM,最后每个顶点v与当前矩阵模型视图矩阵相乘,这个过程意味着所调用的最后一个变换函数实际上最先应用于顶点的,也就是说,我们以相反的顺序指定了这些矩阵。

有点难理解是吧!我们举例子说明,把这点搞明白了!

需求:将一个物体沿着原点旋转,然后在沿着X轴移动
R:旋转矩阵
T:移动矩阵
我们的代码应该这样写:

glMatrixMode(GL_MODEVIEW)
glLoadIndentity();
glMultMatrixf(T); //1
glMultMatrixf(R); //2

刚才上面有提到,如果有一个很难理解的东西出现在你面前,你就要寻找其他的方法把它克服掉。
前人已经帮我们想好了一种思维方式:局部移动坐标系统

用这种思维怎么理解这个过程:
执行1 后,物体的位置变为(x,0,0) 执行2,物体的局部坐标系的坐标依然为(0,0,0) 根据局部坐标系统旋转物体后,物体的全局位置依然为(x,0,0) 只是进行了旋转。

函数介绍:
glTranslate() // 移动
glRotate() // 旋转
glScale() // 缩放

视图变换用户修改观察点的位置和方向,怎么变换呢?刚才有提到两种,改变照相机或者改变物体。视图变换一般也是有移动和旋转组合。上面提到的矩阵变换执行顺序问题,如果搞懂了,接下来说的这句话一定要记住:视图变换一定要放在调用任何模型变换的函数的前面调用,以确保首先作用的问题是模型变换,为什么呢?继续去看刚才的内容

函数: 前面介绍过了,应该没有忘记吧!

glMatrixMode()
glLoadIdentity()

为什么要进行投影变换?

答:投影变换的目的就是定义一个视景体.视景体的作用有两个,第一个,决定物体是如何映射到屏幕上的,第二个,决定实际要显示的物体范围。如物体没在视景体内,将会被裁剪掉。

一句话简单介绍:近的物体大,远的物体小

函数: glFrustumf (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar); 参数都为整数

函数:近的和远的物体一样大,和建筑图纸查不多

  glOrthof (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);

视口:就是OpenGL 内容的显示窗口,设置好它的大小,你就能显示内容了。
函数:glViewport()

注意一点:一定要将视口的大小比例和视景体的纵横比例设置相同,不然图像会被拉伸或者压缩

如果你想做多画面视频的话,需要设置多个视口,来绘制这个物体

glViewport(0,0,size/2,size)
  …
glViewport(size/2,0,size/2,size)
 glClipPlanef (GLenum plane, const GLfloat *equation); 定义裁剪平面
 glEnable(GL_CLIP_PLANE0) 启动
 glDisable(GL_CLIP_PLANE0) 禁用

解释: 视景体定义了6个裁剪平面,我们还可以自定义多达6个平面的其他裁剪平面。
equation 方式:Ax+By+Cz+D = 0;满足M-1(xeyezewe)T >= 0 的所有视觉坐标(Xeyezewz) 点位于这个平面定义的半空间中,所有不在这个半空间的点都被裁剪掉
有什么用?

如果你想讲一个球体裁剪成一个半球的话,就可以使用这个技术!

友情提示

代码可能你看不懂,因为OpenGL 是一个很深的技术,不可能看几篇博客就能掌握的,这篇内容重在讲解一些概念!理解就行,在未来一段时间,如果你对技术充满兴趣,想把它运用在IOS 的开发中,请持续关注!

代码下载地址: https://github.com/XJALYN/OpenGLES_009

上一篇下一篇

猜你喜欢

热点阅读