实例介绍
入门书籍 最长的一帧 王锐(array)
从变量的名称可以猜测出 的功能,它用于储存该视景器的事件队列。 代衣事件的类是 ,它可以用于衣达各种类型的鼠标、键盘、触压 笔和窗口事件。在用户程序中,我们往往通过继承 类,并重与 凶数的方法,获取实时的鼠标键盘输入,并进而实现相应的用户代码(参见 ) 除了保存一个 的链表之外,还提供了一系列对链表及其 元素的操作函数,这其中, 函数的作用是分配和返回一个新的 事件的指针。 随后,这个新事件的类型被指定为 事件,即每帧都会触发的一个事件。 那么, 呢?没错,它就是视景器中所用的场景漫游器的实例。通常 我们都会使用 来设置这个变量的内容,例如轨迹球漫游器 )可以使用鼠标拖动来观察场景,而驾驶溲游器( 则使用类似于汽车鸳驶的效果来实现场景的漫游。 上面的代码将新创建的 事件和 对象本身传递给 的 函数,不同的漫游器(如 )会重写各自的函 数,实现自己所需的初始化工作。如果读者希望自己编写一个场景的漫游器,那么覆写并使 用 就可以灵活地初始化自定义漫游器的功能了,它的调用时 札就在这里。 那么,回到 冈数……很好,这次似乎没有更多的内容了。没想到一个短短的 凶数竞然包含了那么多的信息,看来草率地阅读还貞是使不得。 解读成果 悬疑列表: 无 第二日 当前位置 第行, 函数是我们十分熟悉的另一个函数,从问世以来,我们就习惯于在 进入仿真循环之前调用它(现在的会自动调用这个函数,如果我们忘记的话),以完成 窗口和场景的“设置”工作。那么,什么叫做“设置”,这句简单的场景设置又包含了多少 内容呢?艰辛的旅程就此开始吧。 首先是一行 ,其内容无非是设置类变量 指向 的内容为。至于这个“带有焦点的摄像机”是什么意思,我们似乎明白,似乎又不明 白,就先放入一个“悬疑列表”( )中好了。 下面遇到的函数就比较重要了,因为我们将会在很多地方遇到它 变量 是一个保存了 指针的向量组,而 函数的作用是获取所有的图形上下文,并保存到这个向量组中来。 对于需要将嵌合到各式各样的系统(如 等)的朋友来 说, 类是经常要打交道的对象之一。一种常用的嵌入方式也许是这样实 现的 这个过程虽然比较繁杂,但是顺序还是十分清楚的:首先设置嵌入窗口的特性(), 例如 位置,宽度和扃度,以及父窗∏的句柄( ;然后根据特性 的设置创建一个新的图形设备上下文( ),将其赋予玚景所用的摄像机。而 我们在 函数中所要获取的,也许就包括这样一个用户建立的 设 备 当前位置: 第行 在这个函数之中,首先判断场景的主摄像机 是否包含了一个有效的 设备,然后再遍历所有的从摄像机 (一个视景器可以包含一个主摄像 纵和多个从摄像机),将所有找到的 图形上下文设备记录下来。 随后,将这些 的指针追加到传入参数( 向量组)中,并使用 执行了一步排序的工作,所谓的排序是按照这样的原则米进行的: 屏幕数量较少的 设备排列靠前: 窗口坐标较小的设备排列靠前; 窗∏坐标较小的设各排列靠前 如果希望观察自己的稈序中所有的图形设备上下文,不妨使用这个函数来收集一下。简 单的情形下,我们的程序中只有一个主摄像机,也就只有一个 设备,它表 达了一个全屏幕的图形窗口;而 这个例」程序可以创建六个从摄像机,因此可以 得到六个图形上下文设备,且各个图形窗口的坐标各不相同,这也正是这个例子想要表 达的。 可是,主摄像机的 呢?为什么 中不是七个 设备呢?答案很简单,主摄像机没有创建图形上下文,因此也就得不到设备的指针。为了理 解这个现象的原因,我们不妨先回到 函数中。 当前位置 第行 有一个显而易见的事实是:当程序还没有进入仿真循环,且对于 还 没有任何的操作之时,系统是不会存在任何图形上下文的;创建一个新的 对象 也不会为其自动分配图形上下文。但是,图形上下文 却是场景显小的唯一 平台,系统有必要在开始渲染之前完成其创建工作 假设用户已经在进入仿真循环之前,自行创建了新的 摄像机对象,为其分配了 自定义的 设备,并将 对象传递给视景器,就像 和 例子,以及我们在编写与系统嵌合的仿真程序时常做的那样。此时,系统已 经不必为图形上下文的创建作任何多余的L作,因为用广不需要更多的窗∏来显示自己的场 景了。所以就算主摄像机 还没有分配 ,只要系统中已经存在图形上 下文,即可以开始执行仿真程序了 但是,如果 没有得到任何图形上下文的话,就说明仿真系统还没有合适的 显示平台,此时就需要尝试创建一个缺省的 设备,并再次执行 如果还是没能得到任何图形上下文的话,那么就不得不退出程序了。 创建缺省 设备的方法有以下几种 读取 环境变量的内容:如果用户在这个环境变量中定义了一个 文件路径的话,那么系统会尝试用 函数读入这个文件,使用插件 进行解析;如果成功的话,则调用 乐数,使用配置信息设置当前的 视景器。这些工作在 数中实现 读取 环境变量的内容:如果用户以“”的格式在其中定义了 窗口的左上角坐标(,)和尺寸(,)的话(注意要以空格为分隔符),系统会芸试使 函数来创建设各。 、读取 环境变量的内容:如果用户在其中定义了所用屏幕的数量的话, 系统会尝试用 函数,为每一个显示屏创建一个全 屏幕的图形窗口;如果同时运设置了 ,那么这两个坏境变量都可以起到作 用,此时将调用 函数。 如果上述环境变量都没有设置的话(事实上这也是最常见的情况),那么系统将调用 函数,尝试创建一个全屏显示的图形设各 那么,下文就从这几种图形设备建立的方法开始。至于后面的路,果然遥遥无期呢。 解读成果: 悬疑列表 类变量 的意义是什么? 第三日 当前位置: 第行 这个函数有五个传入参数:窗口左上角丛标 宽度 高度 ,以及屏幕 数 。它的作用顾名思义是根据给定的窗冂参数来创建个图形设各 首先函数将尝试获取 的指针,这个类在的窗口显示中扮演了 重要的地位:它保存了目前用到的,与图形显示,尤其是立体显示有关的所有信息 主要包括 显示器类型,默认为 (监视器),此外还支持 (威力墙), (虚拟实境中心)和 (头盆 显示器)。 :立体显示模式,默认为 (互补色),此外还支持 (四方体缓冲) (水平分割), (垂 直分割), (左眼用), (右眼用), (水 交错), 垂直交错), 棋盘式交错,用于 显示器)。 :双眼的物理距离,默认为。 :屏幕的实际宽度和高度,分别默认改置为 和 目前它们影响的仅仅是视图采用透视投影时的宽高比 人眼到屏幕的距离,默认为 默认为 (左眼渲染左 视凵),也可设为 (左眼渲染右视凵)。 :左视口和右视口之间的距离(像素数),默认为。 :默认为 (左眼渲染顶视 ∏),也可设为 (左眼渲染底视冂) 顶视口和底视口之间的距离(像素数),默认为。 默认为,用于屏幕分割之后对其宽高比进行补 :用户程序中最多可用的 (图形设备上下 文)数目,默认为个。 多重采样的子像素样本数,默认为。如果显示卡支持的话,打开 多重采样可以大幅改善反走样( )的效果。 此外还有很多可以设置的类变量,如 (模板缓存的最小位 数)等,其默认设置均在 函数中完成,其中有些变量可能还 没有作用。要注意的是, 的作用仪仪是保存所有可能在系统显示中用到的数 据,这个类本身并不会据此改变任何系统设置和渲染方式。 值得称道的是, 可以很方便地从系统环境变量或者命令行参数中获取用 户对显示设备的设置,详细的调用方法可以参阅 和 两个函数的内容,十分通俗易懂。 如果希望在用户程序中更改 中的显示设置,请务必在执行视景器的 函数之前,当然也就是仿真循环开始之前。这一点也是要切记的。 不知不觉中,似乎完全跑题了,那么我们还是先设法回到主题上来… 当前位置: 第行 代码解读的工作完全没有进展,看米需要加快进度了。获取系统显示设备的设置参数之 后,下面我们要开始创建新的 设备了,回忆“第二日”的内容中所介绍的 与窗口嵌合的流程,第一步是新建一个显示设备特性实例 设置图形窗口的特性值。注意这里用到了一个函数 的工作仅仅是尝试检査系统环境变量 ,并调用 函数,将其中的内容按照“ ”的格式解析为系统的主机名称( ),显 示数(在 下必须为)和屏幕数(或者其它数字) 根据立体显示模式的不同,窗∏特性中的模板位数等参量也会有所区分。 下一步,创建新的 :并将其设置给视景器的主摄像机: 千万不要简单地使用来创建新的 指针,因为相比起来, 还完成了这样一些工作: 获取窗口系统接口,即 的实例; 、执行 函数,如果用户没有设置屏幕数,则 自动设置为缺省值; 返可 的值 看似一切顺利,但是稍一深究就会发现,这里面存在了一个重要但是不好理解的问题: 可是一个纯虚函数,它怎么可能返回新建 立的图形设备上下文呢?事实上,这个看似简单的 结构体也是另 有玄机的,注意这个函数: 它的作用是指定操作平台所使用的视窗接口,也就是在特定的系统平台上创建图 形窗凵的时候,将会使用到哪些本地函数。当然, 系统要使用 而 系统要使用 系统则使用 切有关视窗接口的工作都是由 和 这三个类及其协作类来完成;而指定使用哪个窗∏系统接∏ 的关键,就在于源文件 中定义的结构体 了,仔细研读一下这个结构体和刚才所述的 凶数的关系,还有注意那个紧跟着结构体的全局变量 行),相信您一定会人呼巧妙的。 什么 中也有这个结构体?那么请仔绀检查 自动 生成的 工程,看看有没有包含这个多余的文件(对于 系统来说) 这也许就是使用 来实现跨平台编译的好处之一了。 至于 数是如何使用 来实 现图形设备的创建的,鉴于本文并不想追赶《资本论》的宏伟规模,就不再深究了,读者不 妨自行刨根问底。 回来吧,回来吧。还是让我们回到 函数中来 这个函数剩下的内容并不是很多,也不难理解,主要的工作有: 调用 记录新建立的窗冂设备的大小, 因而这个设备上产生的键盘和鼠标事件可以以此为依据。 设置主摄像机 的透视投影参数,并设置新的 视凵 、执行 和执行 函数,这实质上 相当于在渲染的过程中执行 和 从而自动设置此摄像机想要绘制 和读取的缓存。 就这样。不过这回真是一次又一次地离题万里……希望我们还是从中得到了一些收获和 启迪的,对吗? 解读成果 悬疑列表 类变量 的意义是什么? 第四日 当前位置: 第行, 和 函数的实现流程与上一日介绍 的用 区别不是很大。值得注意的是, 函数中调 函数取得了与平台相关的视窗接口类 (其中的原理请参看上一日的文字),并进而使用 函数取得了当前系统的显示屏幕数 事实上,如果我们需要在自己的程序中获取屏幕分辨率,或者设置屏幕刷新率的话,也 可以使用同样的方法,调用 和 等相关函数即可。具体的实现方法可以参见 的源代码 函数可以自行判断屏幕的数量,并且使用多个从摄像札来对 应多个屏幕的显示(或者使用主摄像机 来对应单一屏幕)。此外它还针对小平分割 显示( )的情况,对摄像机的左右眼设置自动做了处理,有兴趣的读 者不妨仔绀研究 最后,本函数还执行了一个重要的工作,即 这其中 包括以下几项上作 对于场景漫游器 ,执行其 函数和 函数,也就是设 置漫游器对应于场景图形根节点,并回到其原点位置。不过在我们使用 数时也会自动执行同样的操作。 将场景图形赋予主摄像机 ,同时设置它对应的渲染器( )的相关函 数。这里的渲染器起到了什么作用?还是先放到悬疑列表中吧,不过依照我们的解读速度 这个问题可能会悬疑很久 同样将场景图形赋予所冇的从摄像机,并设置乍个从摄像机的渲染器。 终」可以回到 数的正轨了,还记得下一步要做什么吧?对,在尝试设置了缺 省的 设备之后,我们需要再次使用 来获取设备,如果还是不成 功的话,则不得不退出运行了(连图形窗∏都健立不起来,还玩什么) 当前位置: 第行, 现在我们遍历所得的所有 设备(通常情沈卜,其实只有一个而已)。对 于每个 指针,依次执行 一头雾水,但是决不能轻言放弃。仔细研究一下吧,首先是 数,实际上也就是 函数。 是纯虚函数吗?没错,回想一下第三日的内容,当我们尝试使用 来创建一个图形设备上下文时,系统返回的实际上是这个函数的值: 而正如我们历经千辛万芹所分析的那样, 所指向的是平台相关的接口类,也 就是 的接∏,也就是 中对应类的实例。换句话说,此 函数返回的值,也应当是派生自 的具体类的实例! 正确,对」 用户来说,这个凶数返回的恰恰是 的实例, 而前文的 网数,正是 晕头转向了……那么,用一张图也许能解决一点问题吧: oSg:: Camera Camera c set Graphics Context Windowing SystemInterface .: create Graphics Context oSg: Graphics Context osg Viewer: Graphics window Win32 osg: Graphics Context: osg Viewer: Graphics Window XII Windowing SystemInterface osg Viewer: Graphics Window Carbon Win3 2Windo System XllWindowingSystemInterface OS.CArbon WindowingSystemInt 、视景器 的主从摄像机均需要使用 设置对应的图形设备上 下文,实际上也就是对应的显示窗凵 的创建由平台相关的抽象接口类 负责, 对于 平台而言,这个类是由 类 具体实现的,它创建的显示窗冂设备即 的实例 进一步深究的话,如果窗口特性()中开启了 选项,则将尝试创 建 设备,以实现离屏渲染( ),纹理烘焙 )等工作;否则只建立通常的 窗口 真是令人兴奋!没错 和 函数也是用相同的方法来实现多态性的,而它们的上作也就是 开发者使用函数 成的工作,将渲染上下文对应到正确的窗口绘制句柄上。 如果您还想要深究具体的实现方法的话,就好好地阅读 中的 相关内容吧,不过我们的旅程要继续了。 等等,刚才那段程序里面, 是仆么,它又执行了什么?嗯,简单说来, 这个变量是通过 来设置的,其主要作用是在执行 数时,顺使完成用户指定的一些工作。您自凵的工作内容可以通过继承 类 并重载 操作符来添加。 这个妙趣横生的例子(一个傻娃娃接玩具的小游戏) 中就使用了 ,主要的作用是为场景中的 几何对象立即编译显示 列表( )。有兴趣的话不妨细细把玩一下。 解读成果: 悬疑列表: 类变量 的意义是什么?渲染器( )类起到什么作用? 第五日 当前位置: 第行, 下面我们再次遍历所有 设备,对于每个 指针,判断 它是否为 对象,并执行 函数 阅读 米(即 的具体实现者)的同名函数可以发现, 这个函数不过是负责把鼠标焦点转到当前窗口上而已。 一步工作的代码如下: 首先调用 数,启动内部定时器并开始计时 随后, 数的工作是找到当前视景器和所有 设备的 事件队列 并设定它们的启动时刻为当前时间。 行是调用 函数……设置线程,对于向以多线程渲染 而闻名的而言,这一定是个值得深究的话题。 当前位置: 第行 的视景器包括四种线程模型,可以使用 进行设置,不同的线程 模型在仿真循环运行时将表现岀不冋的渲染效率和线程控制特性。通常而言,这凹种线程的 特性如下 单线程模型。不会创建任何新线程来完成场景的筛选和渲染,因 而也不会对渲染效率的提高有仟何助益。它适合仟何配置下使用 将为每一个图形设各上下文( )创建 个图形线程,以实现并行的渲染工作。如果有多个的话,那么系统将尝试把线程分 别放在不同的上运行,不过每一帧结束前都会强制同步所有的线程 :这线程模型同样会为每个 创建线程,并分配 到不同的上。十分值得注意的是,这种模式会在当前帧的所有线程完成工作之前,开 始下一帧 【实例截图】
【核心代码】
标签:
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论