OpenSceneGraph FAQ 【转】

1、地球背面的一个点,计算它在屏幕上的坐标,能得到吗? 不是被挡住了吗?

答:计算一个空间点的屏幕坐标,使用osgAPEx::GetScreenPosition函数。当空间点处于相机视空间内(不管它是否被别的物体遮挡)时,都是可以得到它对应的屏幕坐标的。

如何判断一个点是否在地球背面?可以通过计算该点处垂直地面的方向UP,与相机方向的夹角,如果夹角为锐角,则可认为该点在地球背面。计算地球上任意点的UP方向使用osgAPEx::ComputeLocalUpVector。

2、OSG中可以播放视频吗?

答:可以使用quicktime插件或ffmpeg插件在OSG中播放视频,quicktime插件的编译需要QuickTimeSDK,ffmpeg插件的编译需要ffmpeg库(www.ffmpeg.org  www.ffmpeg.com.cn  http://ffmpeg.arrozcru.org/builds/)。OSG的quicktime插件已经停止更新了,现在力推ffmpeg。

ffmpeg插件好像是从2.9版开始提供的。

利用视频播放插件可以读入avi等视频文件到OSG纹理中,并把纹理渲染在模型上,比如实现一个立体广告牌。

3、模型缩放后光照结果错误,是什么原因?

答:OpenGL的放缩矩阵会同时变换模型的法线,进而影响光照效果,因此放大时可能造成模型表面光照过强,需要打开GL_NORMALIZE。

在OSG中使用stateset->setMode( GL_NORMALIZE, osg::StateAttribute::ON );

4、OSG中如何打开双面光照

答:使用osg::LightModel渲染属性

5、OSG中可以播放GIF动画么?

答:可以,使用OSG提供的gif插件,可以读取动态GIF图片,并通过设置为模型纹理来渲染该图片。通过GIF插件读取GIF图片返回的对象派生自osg::ImageStream,因此,可以使用paly等接口控制动画播放。

GIF插件提供了轻量级的动画纹理播放方式,较quicktime等视频播放插件更适合一些简单的应用场合。

另外,OSG还提供osg::ImageSequence类,可以通过读入多个静态图片形成一个sequence,并通过ImageStream接口函数控制多张图片的连续播放。

6、什么是烘培,在OSG中怎样实现烘培?

答:烘培又叫纹理烘培,是指通过每帧预渲染一副场景到指定纹理上,实现模型贴图的动态效果。如水面倒影、镜子、倒计时牌上跳动的文字等效果的实现,都可以使用纹理烘培技术。

在OSG中实现纹理烘培是非常容易的,大致步骤如下:

创建纹理对象,设置纹理的大小、像素格式,并把纹理对象绑定到模型;

创建烘培用的相机,指定渲染顺序为PRE_RENDER,指定实现方式为FRAME_BUFFER_OBJECT,并把相机的颜色缓冲区绑定到纹理对象;

把要渲染到纹理上的场景加入相机的下级;

把相机加入场景。

具体例子可参考examples\osgprerender或demos\RTT

7、为什么我的OSG窗口看到的圆球是扁的?

答:这是因为投影矩阵的设置有问题,一般情况下应该根据视口实际的宽高比来设置投影矩阵,如视口宽、高分别为width和height,则设置相机 投影矩阵为camera->setProjectionMatrixAsPerspective(30, (double)width/height, 1.0f,10000.0f);

如果没有按实际视口宽高来设置投影矩阵,就会出现画面被压缩或拉伸的效果。

当窗口大小发生变化时,系统通过GraphicsContext对象自动响应WM_SIZE消息,对该GraphicsContext对象相关联的 所有相机(通过调用osg::Camera::setGraphicsContext将相机与GraphicsContext关联)自动更新视口和投影矩 阵,更新投影矩阵的方法为根据宽高比的改变来等比缩放投影矩阵。

可以通过osg::Camera::setProjectionResizePolicy设置相机在窗口大小发生变化时重置投影矩阵的策略,设置为FIXED则不会自动重置投影矩阵,缺省设置为HORIZONTAL。

对于HUD相机,由于其使用正交投影矩阵,不能通过上述缩放的方式修改投影矩阵(正交投影矩阵不但和宽高比有关,还和宽高值有关)。可以自己实现一个GUIEventHandler响应RESIZE事件,根据当前主视口宽高重设HUD相机的视口和投影矩阵。

8、什么是VBO,什么是DisplayList?

答:VBO和DisplayList是OpenGL提供的两种用于提高渲染效率的技术。

VBO(Vertex Buffer Object)-顶点缓冲区对象,DisplayList-显示列表。

在使用VBO时,如果修改顶点数组内容,则需要调用顶点数组的dirty()函数应用修改;使用DisplayList时,如果修改顶点数组内容,则需要调用dirtyDisplayList()来应用修改。

OSG中缺省使用显示列表而不使用VBO。

9、OSG中分页数据库线程、渲染线程和筛选线程是在什么时候退出的?

答:1.osgViewer::Viewer对象析构时会调用stopThreading同步退出渲染和筛选线程,并调用DatabasePager::cancel通知分页数据库线程退出。
       2.在收到WM_CLOSE消息时会调用stopThreading同步退渲染和筛选线程。
       3.可以在需要的时候手动调用stopThreading同步退出渲染和筛选线程。

10、OSG处理事件的时机和顺序是怎样的?

答:OSG在Viewer::eventTraversal函数中处理输入事件,eventTraversal在帧循环的更新遍历和渲染遍历之前被调用。
       eventTraversal中事件处理的顺序为:
             1.为本帧每一个事件遍历场景树,调用Node、Drawable、StateSet对象的事件处理回调处理事件。
             2.为本帧每一个事件遍历Viewer的事件处理器(GUIEventHandler)队列,调用事件处理器处理事件。
             3.为本帧每一个事件,调用Viewer的相机操作器(CameraManipulator)处理事件。

11、Switch(开关)节点的作用是什么?

答:Switch节点继承自Group节点,对应于childLis有一个boolList,为每一个子节点保存了一个开关值,当子节点开关关闭时,保证子节点不会被访问类型为Active子节点的访问器访问到。
当子节点开关关闭时,子节点不参与包围盒计算。

12、NodeMask、TraversalMask的作用是什么?

答:NodeMask(32位无符号整形)作为Node类的属性,用于限定节点是否能被指定的节点访问器访问。缺省值为0xffffffff。
TraversalMask(还有OverrideMask)作为节点访问器的属性,用于限定节点访问器能够访问哪些节点。缺省值为0xffffffff。
节点是否能被访问器访问取决于:TraversalMask & ( OverrideMask | NodeMask )

13、osg::ColorMask的作用是什么?

答:ColorMask封装了glColorMask函数的功能,用于设置对颜色缓冲区的写掩码,即设置是否对R、G、B、A位执行写入操作。
在只需要写深度缓冲或模板缓冲,而不实际绘制物体时,可以使用ColorMask并设置对RGBA的写入掩码均为false。

14、怎样布局屏幕元素(文字、图片等)

答:屏幕元素一般使用HUD的方式(即正交投影)渲染,在osg中可以定义一个正交投影的相机,把屏幕元素作为子节点添加给这个HUD相机进行渲染。元素的布局和缩放,一般有两种处理方式:
一、

按视口实际大小布局,同时跟踪输出窗口的大小变化,并按窗口实际大小更新HUD相机的投影矩阵和视口。这种方式不但要动态更新相机的投影矩阵和视口,而且
要自己编写代码根据视口大小变化动态更新屏幕元素的位置和大小,如按指定的对齐方式更新位置、按指定的尺寸比例更新大小。也可以只更新位置不更新大小,这
样得到的效果就是屏幕元素的大小不随窗口缩放。
二、
按指定的固定大小布局,同时设置HUD相机的投影矩阵为以相同宽高计算的固定值,跟踪输出窗口大小变化,按窗口实际大小更新HUD相机的视口。这种方式只
需要编写代码更新相机的视口即可,而屏幕元素的大小和位置始终按初始的固定视口大小计算,不需随窗口变化做调整。这样得到的效果就是屏幕元素的大小和布局
与窗口等比缩放。

15、setAttribute与setAttributeAndModes的异同

答:setAttribute用于设置渲染属性和属性的覆盖模式,第二个参数的有效值只有OVERRIDE和PROTECTED的组合,不影响属性状态的开关(设置ON/OFF是无效的)!
    setAttributeAndModes设置渲染属性和覆盖模式的同时,也会设置属性状态的开关。
    setAttribute用于只需设置渲染属性而不改变状态的场合,具体是否打开该状态取决于子节点的设置。

16、OSG场景筛选中有哪些优化效率的算法
答:OSG场景筛选主要用到的筛选方法有:视景体筛选、最
小像素筛选和遮挡筛选。其中视景体筛选是最基本和最常用的筛选方法,它的算法是:使用构成视景体的各个面与节点包围盒求交,如果节点在某个面以外,则剔除
掉该节点及其子节点;如果节点完全在某个面以内,则该节点的所有子节点在进行筛选计算的时候不需要再与这个面求交(子节点必然也完全在这个面以内)。鉴于
这种筛选实现,恰当使用树形结构场景图组织场景节点,能够提高筛选效率。

17、我在MFC的Static控件中使用OSG渲染,但不能响应鼠标事件是为什么?
答:这完全是MFC控件使用的问题,要使对话框中的Static控件接收鼠标消息,需要把Static控件属性的Notify设置为True。

18、OSG渲染排序是怎么做的,有哪些接口可以用来控制渲染顺序?
答:OSG通过场景拣选(cull)生成一棵由RenderStage(根节点)、RenderBin(分支节点)和RenderLeaf(渲染叶)构成的渲染树,同时生成一棵由StateGraph构成的渲染状态树,最终的渲染操作通过渲染树进行,渲染的顺序为:
 RenderStage::draw
                          |
 RenderStage::drawPreRenderStages
                          |
 RenderStage::drawInner ------------------------------------------- RenderBin::draw
                          |                                                                                          |
 RenderStage::drawPostRenderStages                                   BinNum小于0的子Bin(按BinNum升序)
                                                                                                                     |
                                                                                                 本Bin的渲染叶列表(排序的)
                                                                                                                     |
                                                                                                 本Bin下挂的所有StateGraph中的渲染叶
                                                                                                                      |
                                                                                                   其他的子Bin(按BinNum升序)

拣选过程中,通过拣选测试的Drawable对象被添加到当前StateGraph对象的渲染叶列表中,而StateGraph则被当前
RenderBin对象引用,而最终渲染时,部分渲染叶也是通过RenderBin引用的StateGraph对象找到并渲染的,其他渲染叶(对应
RenderBin的排序模式为FRONT_TO_BACK/BACK_TO_FRONT/TRAVERSAL_ORDER的)被转移到
RenderBin的渲染叶列表中排序然后渲染。

我们可以通过StateSet的BinNum和BinName设置来控制对应节点的渲染顺序。
1)BinName为"RenderBin"、"StateSortedBin"的缺省排序方式为SORT_BY_STATE(目前实现为不排序)
   BinName为"DepthSortedBin"的缺省排序方式为SORT_BACK_TO_FRONT(由远到近,用于半透物体的alpha混合)
   BinName为"TraversalOrderBin"的缺省排序方式为TRAVERSAL_ORDER(即按遍历到的先后顺序排序)。
2)BinNum小的靠前渲染
3)setNestRenderBins设置RenderBin是否允许嵌套,为true时新的RenderBin被添加为当前RenderBin的子节点,为false时新的RenderBin被添加为RenderStage(根节点)的子节点。

19、OSG对组合键是怎样映射的?
答:由于Win32 API的特点,OSG不得不将Ctrl+letter变换到了{1,..,26},也就是说,CTRL+a的getKey()为1,而CTRL+z的getKey()为26;Shift+a~z被映射到大写的‘A‘~‘Z‘。

20、为什么OSG自动为我的纹理对象创建了mipmap?
答:当纹理过滤方式min_filter设
置为基于mipmap的4种之一时,OSG将自动为非mipmap贴图纹理对象创建mipmap。min_filter的缺省值是
LINEAR_MIPMAP_LINEAR,因此如果未显式设置纹理过滤方式的话,即会启用自动创建mipmap的功能。

21、Texture::setUnRefImageDataAfterApply的作用?
答:当该值设置为true时,OSG在应用过该纹理对象后(apply),自动释放其对Image对象的引用,以减少内存占用。

22、osgDB::SharedStateManager的作用?
答:SharedStateManager
用于对系统中的StateSet、Texture对象执行共享优化,即对系统中内容相同的多个Texture对象,只保留一个实例,其他使用引用,以减少
内存、显存的占用,提高渲染效率。使用方式为,为新加载或创建的节点对象调用
osgDB::Registry()->getOrCreateSharedStateManager()->share函数。

 23、如何打开分页数据库的预编译功能?
答:需要做两件事,1)设置
osg::DisplaySettings::instance()->setCompileContextsHint(true),使
Viewer在realize时创建后台GC用于预编译操作;2)调用
osgDB::DabasePager::setDoPreCompile(true)开启预编译功能。

时间: 2024-10-22 18:18:13

OpenSceneGraph FAQ 【转】的相关文章

官方问答--微信小程序常见FAQ (17.8.21-17.8.27)

给提问的开发者的建议:提问之前先查询 文档.通过社区右上角搜索搜索已经存在的问题. 写一个简明扼要的标题,并且正文描述清楚你的问题. 提交 BUG:需要带上基础库版本号,设备信息(iOS, Android,开发工具等等),操作系统信息(系统版本),以及可以让他人重现的信息,最好能够提供重现 demo. 对于提供信息过少的问题,会直接关闭,请提供完整信息以后重新打开问题.另外,对于如何做某某功能,可否做某某功能的问题,会直接关闭. 微信小程序常见FAQ(17.8.21-17.8.27) Q:1.5

Discuz 7.2 faq.php漏洞分析

漏洞发生在页面faq.php中,源码如下: elseif($action == 'grouppermission') {ksort($gids); $groupids = array(); foreach($gids as $row) { $groupids[] = $row[0]; } $query = $db->query("SELECT * FROM {$tablepre}usergroups u LEFT JOIN {$tablepre}admingroups a ON u.gro

工作笔记20170315-------关于FAQ(Frequently Asked Questions)列表的代码

源自于:http://www.17sucai.com/pins/3288.html (1)FAQ问答列表点击展开收缩文字列表 <ul>   <li class="clearfix">   <h5><b class="UI-ask"></b>什么是享赢棋牌联盟?</h5>   <div class="foldContent">   <p>享赢棋牌联盟是杭

FAQ: Automatic Statistics Collection (文档 ID 1233203.1)

In this Document   Purpose   Questions and Answers   What kind of statistics do the Automated tasks collect   How do I revert to a previous set of statistics?   Does the automatic statistic collection jobs populate CHAIN_CNT?   11g+ Automatic Mainten

FAQ: Python中if __name__ == &#39;__main__&#39;:作用

#hello.pydef sayHello(): str="hello" print(str); if __name__ == "__main__": print ('This is main of module "hello.py"') sayHello() python作为一种脚本语言,我们用python写的各个module都可以包含以上那么一个类似c中的main函数,只不过python中的这种__main__与c中有一些区别,主要体现在:

高手问答精选:Go 语言 —— 云计算时代的 C 语言(类似于一个FAQ)

Go 语言被称为云计算时代的 C 语言,它在软件开发效率和运行效率之间做出了绝佳的权衡.这使得它既适应于互联网应用的极速开发,又能在高并发.高性能的开发场景中如鱼得水.正因如此,许多互联网公司,尤其是云计算领域的创业公司都选择 Go 语言作为其技术栈的重要组成部分.因此,对于广大的开发者而言,关注和学习 Go 语言就十分有必要了. 在高手问答第 149 期中,我们围绕 Go 进行了提问,并邀请了 @hyper0x(郝林)作为高手嘉宾. 本文整理了此次高手问答中一些精彩的问答. Go 语言使用场景

python 学习之FAQ:find 与 find_all 使用

FAQ记录 1. 错误源码 错误源码如下 def fillUnivList(_html,_ulist): soup =BeautifulSoup(_html,'html.parser') for tr in soup.find_all('tbody').children: if isinstance(tr,bs4.element.Tag): tds = tr.find_all('td') _ulist.append((tds[0].string,tds[1].string,tds[3].stri

OpenSceneGraph in ActiveX by ActiveQt

OpenSceneGraph in ActiveX by ActiveQt [email protected] Abstract. Qt’s ActiveX and COM support allows Qt for Windows developers to access and use ActiveX controls and COM objects provided by any ActiveX server in their Qt applications. Make their Qt

CQRS FAQ (翻译)

我从接触ddd到学习cqrs有6年多了, 其中也遇到了不少疑问, 也向很多的前辈牛人请教得到了很多宝贵的意见和建议. 偶尔的机会看到国外有个站点专门罗列了ddd, cqrs和事件溯源的常见问题. 其中很多也是我一路过来都曾遇到过的. 这是原站地址http://www.cqrs.nu/Faq. 在ENODE群中不少新学习cqrs的朋友都会遇到一些类似的入门问题, 作为群管理员的我也想为群里朋友做点贡献, 所以有了翻译一下CQRS FAQ的念头, 并加入一些自己的理解, 希望对大家会有所帮助. PS