前面有讲到过变换函数时,需要确定自己的矩阵,上一节讲的是模型视图矩阵,这一节就来讲一讲投影矩阵。
注意:在调用本节描述的任意变换函数之前,都不要忘记首先调用下面的函数:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
这样做的目的是为了使后面调用的变换函数是作用与投影矩阵,而不是模型变换矩阵。
1.透视投影
透视投影,物体距离观察点越远,在最终图像中看上去就越小。这就好比照相机照相原理,物体距离照相机越远,在相机成像时,形成的影像就越小。
glFrunstum()用于计算一个用于实现透视投影的矩阵,它与当前的投影矩阵(一般为单位矩阵)相乘。如附图所示,视景体用于剪裁那些位于它之外的物体,平截头体的4个侧面底面和顶面对应于视景体的6个剪裁平面。位于这些平面之外的物体(或物体一部分)将被裁掉。
注:投影矩阵的目的就是为了定义一个视景体。视景体有两个用途:1,决定一个物体如何映射到屏幕上;2.定义哪些物体被剪裁到图像之外。
void glFrustum(GLdouble left,GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far ); 创建一个表示透视视图平截头体的矩阵,并把它与当前矩阵相乘。平截头体的视景体是由这个函数的参数定义的:
(left, bottom , -near)和(right, top, -near)分别指定了近侧剪裁平面左上角和右下角的(x, y, z)坐标。
near 和 far分别表示从观察点到近侧和远侧剪裁平面的距离,它们的值应是正的。
gluPerspective()函数也是创建一个视景体,与调用上面glFrunstum()产生的视景体相同。但是这个函数并不是指定近侧剪裁平面的连个角,而是指定y方向上视野的角度和纵横比(x/y)。
注:gluPerspective()仅限于创建沿视线方向同时对称于x轴和y轴的平截头体,就是平时我们需要的这种。
void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near , GLdouble far); 创建一个表示对称透视试图平截头体的矩阵,并把它与当前矩阵相乘。 fovy是yz平面上视野的角度,它的值必须在[0.0, 180.0]之间。 aspect是这个平截头体的纵横比,也就是它的宽度除以高度。 near和far值分别是观察点与近侧才见平面及远侧剪裁平面的距离(z轴负方向)均为正值。
举例:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(22, w/h, 1 , 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
2. 正投影
在正投影下,视景体是一个平行的长方体,两端大小并没有不同,也就是物体与观察点之间的距离不影响观察者看到的物体大小,它以它实际的形态存在。正投影之后,保持它们的实际大小以及它们之间的角度是至关重要的。
glOrtho()函数创建一个正交平行的视景体。如没有其它变换,投影的方向与z轴平行,观察点的方向朝向z轴的负方向(没有其它变换时,所有的投影方向均如此)。
void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far); 创建一个表示正交平行视景体的矩阵,并把它与当前矩阵相乘。 (left, bottom, -near) 和(right, top, -near)是近侧裁剪平面上的点,分别映射到视口的左下角和右上角。 (left, bottom, -far) 和(right, top, -far)是远侧裁剪平面上的点,分别映射到视口窗口的左下角和有伤口。 near和far可以是正值或负值,甚至可以设置为0.但是near和far不应该取相同的值。
二维图像投影到二维屏幕上时,提供了另一个函数完成。此时场景中的物体所有z坐标都假定位于-1.0~1.0之间。所有z坐标都是0.
void gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top); 创建一个表示把二维坐标投影到屏幕上的矩阵,并把当前矩阵与它相乘。 剪裁局域为矩阵,它的左下角坐标为(left, bottom) ,右上角坐标为(right, top)。
当场景中物体的顶掉通过模型视图矩阵和投影矩阵变换后,位于视景体之外的所有图元都将裁减掉。6个裁剪面就是定义视景体6个侧面的平面。还可以指定其它裁剪平面,使它们位于我们所需要的地方。
昨天开始认真的看coredata的用法,今天终于明白的其中的道理了,还有具体的流程。决定要重新写一遍,这样自己才能真正的掌握
1. 其实coredata就是个数据库,只是苹果把它封装起来了,开始我再看范例的时候觉得很难,看不懂,但是昨天看过具体流程和每个步骤的含义的时候,我就觉得茅厕顿开,豁然开朗了。
2. 就是用它的增删改查四个功能,对吧,不就是这个吗,没什么难的,认真的去学习,了解就好了,当然我只是很浅的运用,如果要深层次的去研究的话,我想还是非常难的,需要花更多的时间去研究。
3. 在coredata中好像是没有表的概念,我不太清楚,反正没有看到建表,只看到有一个一个的entity,然后给entity设置一个名字,查的时候就根据名字来查,查后取出的就是所有entity的一个数组,(可以排序的),如果要加入其他的entity只要重新创建一个NSEntityDescription的对象,然后【request 色图Entity:entity】就行了。
4. 首先需要得到delegate中的managedObjectContext的对象(就是来得到被储存内容的文件管理器,对数据作直接操作),然后再创建一个NSFetchRequest的对象(描述了你要在数据上执行的搜索。包括了要取得的类型信息,数据必须满足的条件以及结果应如何排序)
5. 增:得到delegate的managedObjectContext对象,然后调用NSEntityDescription的insertNewObject的方法,就会返回一个entity的实例,然后对entity进行操作给entity重新赋值,最后调用delegate的saveContext的方法就行了
6. 查:获得managedObjectContext的对象,然后调用executeFetchRequest的方法把创建的request的对像传过去就得到了指定名字的数据的数组(也可以指定查询的条件)
7. 改:在获取entity的时候直接改就行了,最后再调一次delegate的saveContext的方法就行了
8. 删:获取entity的实例,然后直接调用delegate中的deleteObject的方法吧entity传过去就删除了,最后还要saveContext。
9. 这就是最简单的增删改查 ,当然还有更复杂的,慢慢研究,我喜欢数据库。
LayoutParams params = recordProgress.getWindow().getAttributes(); params.y = 100; params.gravity = Gravity.TOP; recordProgress.getWindow().setAttributes(params);