- 浏览: 191722 次
- 性别:
- 来自: 无锡
文章分类
最新评论
-
luoqianjiang:
很好,谢谢
一些iOS高效开源类库 -
sgjsdf5944:
没看明白。。。。。。。。。。
UIWebView打开doc、pdf文件 -
593864589:
mac 上不支持呢?
cocos2d 粒子设计器 -
寻墨小楼:
多谢了...正在弄这个。
mysql for mac 安装和基本操作 -
yueliancao:
楼主如何联系啊 我的MAC系统 #LoadModule php ...
mac OS x中配置apache + php + mysql
现在你已经知道OpenGL是怎样绘图的了,让我们回头谈谈一个很重要的概念:OpenGL视口(viewport)。 许多人对3D编程还很陌生,那些使用过像Maya, Blender, 或 Lightwave之类3D图形程序的人都试图在OpenGL虚拟世界中找到“摄像机”。但OpenGL并不存在这样的东西。它所有的是在3D空间中定义可见的物体。虚拟世界是没有边界的,但计算机不可能处理无限的空间,所以OpenGL需要我们定义一个可以被观察者看到的空间。 如果我们从大部分3D程序具有的摄像机对象的角度出发来考虑,视口端点的中心就是摄像机。也就是观察者站的位置。它是一个观察虚拟世界的虚拟窗口。观察者可见的空间有一定限制。她看不见她身后的东西。她也看不见视角之外的东西。而且她还不能看见太远的东西。可以认为视口是通过“观察者可见”参数所确定的形状。很简单,对吗? 不幸的是,并非如此。要解释原因,我们首先需要讨论的是在OpenGL ES中具有的两种不同的视口类型:正交和透视。
正交和透视为更好地理解,我们先看看铁路轨道,好吗?要正常工作,铁路的两条铁轨之间必须具有固定的距离。其固定的距离是由铁轨根据承载什么样的火车而决定。重要的是铁轨(以及火车的轮子)必须具有相同的距离。如果不是这样,火车根本不可能运行。 如果我们从上方观察铁轨,这个事实很明显。 但是如果你站在铁轨上向下观察会怎么样。不要说“你会被火车撞”,我假设你会足够聪明,会在没有火车开动时进行观察。 是的,铁轨看上去越远与靠近。感谢二年级美术老师,可能你已经知道这就是所谓透视(perspective)。 OpenGL可以设定的视口中的一种就是使用透视。当你这样设置视口时,物体会随着移远而越来越小,视线会在物体移离观察者时最终交汇。这是对真实视觉的模拟;人们就是以这种方式观察世界的。 另一种看设置的视口称为正交(orthogonal) 视口。这种类型的视口,视线永远不会交汇而且物体不会改变其大小。没有透视效果。对于CAD程序以及其他各种目的是十分方便的,但因为它不像人们眼睛观察的方式所以看上去是不真实的,通常也不是你所希望的。 对于正交视口,你看将摄像机置于铁轨上,但这些铁轨永远不会交汇。它们将随着远离你的视线而继续保持等距。即使你定义了一个无限大的视口(OpenGL ES并不支持),这些线仍保持等距。 正交视口的优点是容易定义。因为线永不交汇,你只需定义一个像箱子一样的3D空间,像这样: 设置正交视口在使用glViewport()函数定义视口前,你可以通过glOrthof()通知OpenGL ES你希望使用正交视口。下面是一个简单的例子: CGRect rect = view.bounds;
glOrthof(-1.0, // Left
1.0, // Right
-1.0 / (rect.size.width / rect.size.height), // Bottom
1.0 / (rect.size.width / rect.size.height), // Top
0.01, // Near
10000.0); // Far
glViewport(0, 0, rect.size.width, rect.size.height);
这不难理解。首先我们获取视窗的尺寸。然后设定视口空间的宽度为两个单位,沿x轴从 -1.0 到 +1.0。很容易吧。 接着怎样设定底部和顶部?我们希望我们定义空间的X和Y坐标的宽高比与视窗的宽高比(也就是iPhone全屏时的宽高比)一样。由于iPhone的宽度与高度不同,我们需要确保视口的x和y坐标不同,但遵循一样的比例。 之后,我们定义了 near(远)和 far(近) 范围来描述观察的深度。 near 参数说明了视口开始的位置。如果我们站在原点处,视口就位于我们的面前,所以习惯上使用 .01 或 .001 作为正交视口的起点。这使得视口处于原点“前方”一点点。far 可以根据你程序的需要来设定。如果你程序中的物体永远不会远过20个单位,那么你不需要将 far设置为20,000 个单位。具体的数字随程序的不同而不同。 调用 glOrthof()之后,我们使用视窗矩形来调用 glViewport()。 这是比较简单的情况。 设置透视视口另一种情况就不那么简单,这里是原因。如果物体随着远离观察者而变小,那么它和你定义的可见空间的形状有什么关系。随着视线越来越远,你可以看到更广阔的世界,所以如果你使用透视,那么你定义的空间将不是一个立方体。是的,当使用透视时可见空间的形状称为锥台(frustum)。 是的,我知道,奇怪的名字。但却是真实的。我们的锥台看上去像这样: 请注意当我们离视口越来越远时(换句话说,当z值减小时),观察体的x和y坐标都会越来越大。 要设置透视视口,我们不使用 glOrthof(),我们使用一个不同的函数 glFrustumf()。此函数使用同样的六个参数。很容易理解,但我们应该怎样确定传递给 glFrustumf()的参数? near 和 far 容易理解。你可以同样方式理解它们。near 使用类似 .001的数值,然后根据不同程序的需要确定far 值。 但是 left, right, bottom, 和 top 呢? 为设置这些值,我们需要一点点数学计算。要计算锥台,我们首先要理解视野(field of vision)的概念,它是由两个角度定义的。让我们这样做:伸出双臂手掌合拢伸向前方。你的手臂现在指向你自己锥台的z轴,对吗?好,现在慢慢分开你的双臂。由于在你双臂展开时肩膀保持不动,你定义了一个逐渐增大的角度。这就是用于定义观察锥台的两个角度之一。它定义了视野的宽度。另一个角度的定义原理一样,只是这次你向上下展开你的双臂。如果你的双手间距只有三英寸,那么x角度将非常小。 这称为窄视野。 如果你双手分开两英尺,视野的宽度变得很大。 这就是所谓 宽视角(广角)。 如果用摄影术语描述,你可将视野当作虚拟相机的虚拟光圈的焦距。窄视野很像摄远镜头,它造就了一个缓慢增长的长锥台。宽视角就像广角镜,它造就了一个增长很快的锥台。 我们选择一个中间值,例如45°。 使用这个值,我们怎样计算我们的观察锥台?我们先看下两个角度中的一个。想象一下,从顶部看锥台是什么样子。下面是示意图: 从上向下看,它就像一个砍掉一个点的三角形。但对我们而言,它已经足够接近一个三角形。你还记得三角课上的正切吗?正切函数定义为直角对边与相邻边的比率。 但是,我们没有直角,是吗? 实际上,我们有两个直角… 如果我们沿z轴向下画一条直线的话: 中心虚线就是两个直角的“相邻边”。所以,锥台远端宽度的一半就是视野角度正切的一半。如果我们将此值乘以 near值,就可以得到 right值。right值取反就是 left。 我们希望视野具有与屏幕一样的长宽比,所以按照 glOrthof()中相同的方法(将 right 乘以屏幕的长宽比)来计算top 和 bottom 值。代码如下: CGRect rect = view.bounds;
GLfloat size = .01 * tanf(DEGREES_TO_RADIANS(45.0) / 2.0);
glFrustumf(-size, // Left
size, // Right
-size / (rect.size.width / rect.size.height), // Bottom
size / (rect.size.width / rect.size.height), // Top
.01, // Near
1000.0); // Far
让我们运用到程序中。我修改了上篇文章中最终的 drawView:方法,我们将沿z轴向下显示了三十个二十面体。下面是新的 drawView: 方法: - (void)drawView:(GLView*)view; {
static GLfloat rot = 0.0;
static const Vertex3D vertices[]= {
{0, -0.525731, 0.850651}, // vertices[0]
{0.850651, 0, 0.525731}, // vertices[1]
{0.850651, 0, -0.525731}, // vertices[2]
{-0.850651, 0, -0.525731}, // vertices[3]
{-0.850651, 0, 0.525731}, // vertices[4]
{-0.525731, 0.850651, 0}, // vertices[5]
{0.525731, 0.850651, 0}, // vertices[6]
{0.525731, -0.850651, 0}, // vertices[7]
{-0.525731, -0.850651, 0}, // vertices[8]
{0, -0.525731, -0.850651}, // vertices[9]
{0, 0.525731, -0.850651}, // vertices[10]
{0, 0.525731, 0.850651} // vertices[11]
};
static const Color3D colors[] = {
{1.0, 0.0, 0.0, 1.0},
{1.0, 0.5, 0.0, 1.0},
{1.0, 1.0, 0.0, 1.0},
{0.5, 1.0, 0.0, 1.0},
{0.0, 1.0, 0.0, 1.0},
{0.0, 1.0, 0.5, 1.0},
{0.0, 1.0, 1.0, 1.0},
{0.0, 0.5, 1.0, 1.0},
{0.0, 0.0, 1.0, 1.0},
{0.5, 0.0, 1.0, 1.0},
{1.0, 0.0, 1.0, 1.0},
{1.0, 0.0, 0.5, 1.0}
};
static const GLubyte icosahedronFaces[] = {
1, 2, 6,
1, 7, 2,
3, 4, 5,
4, 3, 8,
6, 5, 11,
5, 6, 10,
9, 10, 2,
10, 9, 3,
7, 8, 9,
8, 7, 0,
11, 0, 1,
0, 11, 4,
6, 2, 10,
1, 6, 11,
3, 5, 10,
5, 4, 11,
2, 7, 9,
7, 1, 0,
3, 9, 8,
4, 8, 0,
};
glLoadIdentity();
glClearColor(0.7, 0.7, 0.7, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glColorPointer(4, GL_FLOAT, 0, colors);
for (int i = 1; i <= 30; i++)
{
glLoadIdentity();
glTranslatef(0.0f,-1.5,-3.0f * (GLfloat)i);
glRotatef(rot, 1.0, 1.0, 1.0);
glDrawElements(GL_TRIANGLES, 60, GL_UNSIGNED_BYTE, icosahedronFaces);
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
static NSTimeInterval lastDrawTime;
if (lastDrawTime)
{
NSTimeInterval timeSinceLastDraw = [NSDate timeIntervalSinceReferenceDate] - lastDrawTime;
rot+=50 * timeSinceLastDraw;
}
lastDrawTime = [NSDate timeIntervalSinceReferenceDate];
}
如果你把上述代码加入OpenGL Xcode项目模板 项目中(它使用glFrustumf()设置了一个具有45°视野的透视视口),你将看到下面图形: 很好。随着几何体远离你,它们会变得越来越小,正像火车铁轨一样。 如果你只是将 glFrustumf()改为 glOrthof(),看上去就完全不同了: 没有透视,第一个二十面体后面的二十九个二十面体完全被第一个挡住了。因为没有透视,后面的各几何体的形状完全取决于其前方的物体。 好了,这是一个很沉闷的主题,事实上你现在可以完全忘却三角课学的知识了。只要复制基于视野角度计算锥台的两行代码就好,而且你可能再也不需要记住它的原理了。 继续下一次激动人心的冒险旅程…下一篇文章,我们将为二十面体增加光效,使它看上去更真实。 |
发表评论
-
OpenGL ES2.0 – Iphone开发指引
2012-01-13 20:03 1048原文链接地址:http://www.raywenderlich ... -
OpenGL ES2.0 Iphone开发指引:part2 纹理贴图
2012-01-13 20:04 1269原文链接地址:htt ... -
OpenGL ES for iPhone: Drawing a Circle - Part III
2012-01-13 20:05 938原文地址:http://vormplus.be/b ... -
OpenGL ES for iPhone: Drawing a Circle - Part II
2012-01-13 20:12 1033原文地址:http://vormplus.be/b ... -
OpenGL ES for iPhone: Drawing a Circle - Part I
2012-01-18 12:19 1000原文地址:http://vormplus.be/blog ... -
OpenGL ES 从零开始系列9(完结):四元数
2012-01-18 12:20 2033在进入下一篇关于骨骼动画的文章之前,让我们先花点时间来了解一个 ... -
OpenGL ES 从零开始系列9a:动画基础和关键帧动画
2012-01-18 12:21 1978最初这篇教程我并 ... -
OpenGL ES 从零开始系列08:交叉存取顶点数据
2012-01-18 12:22 1127Technote 2230提出了很多用OpenGL ES来提升 ... -
从零开始学习OpenGL ES之四补遗 – setupView重写
2012-01-18 12:22 944我在从零开始学习OpenGL ES之四 – 光效 ... -
从零开始学习OpenGL ES之七 – 变换和矩阵
2012-01-29 16:03 1743今天的主题是我 ... -
从零开始学习OpenGL ES之六 – 纹理及纹理映射
2012-01-29 16:03 1478在OpenGL ES中另一种为 ... -
从零开始学习OpenGL ES之五 – 材质
2012-01-29 16:04 1695在 上一篇文章,我们讨论了光效的设定以及光效的各种属性 ... -
从零开始学习OpenGL ES之四 – 光效
2012-01-06 00:05 1340继续我们的iPhone OpenGL ES之旅,我们将 ... -
从零开始学习OpenGL ES之一 – 基本概念
2012-01-02 22:28 1086我曾写过一些文章介绍iPhone OpenGL ES编 ...
相关推荐
从零开始学习OpenGL_ES 网页文件
本文将从零开始,详细介绍如何学习OpenGL ES,以及如何利用提供的模板进行快速入门。 首先,我们要理解OpenGL ES的基础概念。OpenGL ES 提供了一个跨平台的编程接口,用于创建2D和3D图形。它包含了一系列函数调用,...
本教程将从零开始,带你深入理解OpenGL ES项目的构建和运行,帮助你开启图形编程之旅。 在"Empty.OpenGL.ES.Application.zip"这个压缩包中,你可能会找到以下核心文件和目录,它们是构成一个基本OpenGL ES应用的...
iphone上学习opengles的必备资料,完全零基础开始学习
这是我个人学习OpenGL的一个笔记。之前对这里的相关知识也是完全了解吧,可以说是从零开始。
OpenGLES 3.0从零开始,绘制点、线、三角形、立方体,相机实时预览等等实践学习 android平台opengles3.0实践学习 android平台下OpenGLES3.0从零开始 android平台下OpenGLES3.0绘制纯色背景 android平台下OpenGLES3.0...
OpenGL ES(Open Graphics ...总结而言,学习OpenGL ES从零开始需要掌握其核心概念、数据类型、坐标系统以及对3D图形的处理。在移动和嵌入式平台的应用开发中,这些知识点是构建流畅、高效3D图形应用程序的基础。
泰然论坛翻译的 OpenGL ES 从零开始系列 文章源码,由于是很早之前的,原连接失效了。 找了很久才找到的,是目前最齐全的。总共7个DEMO, 涵盖了总共9章的内容
本教程将深入探讨OpenGLES中的一个关键概念——透视投影变换,这是实现真实感图形的重要步骤。透视投影变换能够模拟人眼观察物体时的远近感,使画面具有深度,从而为用户带来更加逼真的视觉体验。 透视投影变换的...
OpenGL ES Tutorial for Android – Part I – Setting up the view OpenGL ES Tutorial for Android – Part II – Building a polygon OpenGL ES Tutorial for Android – Part III – Transformations OpenGL ES ...
在这个主题中,我们主要关注如何在Android平台上使用OpenGL ES绘制一个透明的三维/空间坐标系。这个过程涉及到几个关键的概念和技术。 首先,我们要理解OpenGL ES中的坐标系。OpenGL ES采用右手坐标系,其中X轴正...
学习iphone openGL_ES从这里开始!这是一本关于iphone openGL_ES的入门书,从最基本的开始讲起,只要你看了,那么就能掌握openGL_ES的内容。这真是一本好书,我的openGL_ES就是从这里开始的。(中文版)
1. "从零开始学习OpenGL+ES"系列:讲解OpenGL ES的基本概念和编程基础。 2. "opengl-es画图步骤":详细介绍OpenGL ES绘制图形的完整流程。 3. "实验6——图形绘制与OpenGL_ES":提供实际的编程练习,加深理论知识的...
在实际开发中,通常会使用如`libGLESv2-debug`库来获取更多调试信息,或者使用第三方库如`glide`、`vulkan`等来简化OpenGL ES的使用。同时,掌握良好的图形学基础知识,如几何、投影、光照等,将有助于深入理解和...
在这个“OpenGL ES 学习demo”中,我们可以看到一系列的示例代码和项目,用于帮助初学者理解并实践基本的OpenGL ES绘图操作。 首先,让我们来探讨一下OpenGL ES的基础概念: 1. **坐标系统**:OpenGL ES 使用右手...