转自:http://blog.csdn.net/lainegates/article/details/7646839mysql
一、地球背面的一个点,计算它在屏幕上的坐标,能获得吗? 不是被挡住了吗?算法
答:计算一个空间点的屏幕坐标,使用osgAPEx::GetScreenPosition函数。当空间点处于相机视空间内(无论它是否被别的物体遮挡)时,都是能够获得它对应的屏幕坐标的。sql
如何判断一个点是否在地球背面?能够经过计算该点处垂直地面的方向UP,与相机方向的夹角,若是夹角为锐角,则可认为该点在地球背面。计算地球上任意点的UP方向使用osgAPEx::ComputeLocalUpVector。数据库
二、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版开始提供的。ide
利用视频播放插件能够读入avi等视频文件到OSG纹理中,并把纹理渲染在模型上,好比实现一个立体广告牌。函数
三、模型缩放后光照结果错误,是什么缘由?布局
答:OpenGL的放缩矩阵会同时变换模型的法线,进而影响光照效果,所以放大时可能形成模型表面光照过强,须要打开GL_NORMALIZE。测试
在OSG中使用stateset->setMode( GL_NORMALIZE, osg::StateAttribute::ON );
四、OSG中如何打开双面光照
答:使用osg::LightModel渲染属性
五、OSG中能够播放GIF动画么?
答:能够,使用OSG提供的gif插件,能够读取动态GIF图片,并经过设置为模型纹理来渲染该图片。经过GIF插件读取GIF图片返回的对象派生自osg::ImageStream,所以,可使用paly等接口控制动画播放。
GIF插件提供了轻量级的动画纹理播放方式,较quicktime等视频播放插件更适合一些简单的应用场合。
另外,OSG还提供osg::ImageSequence类,能够经过读入多个静态图片造成一个sequence,并经过ImageStream接口函数控制多张图片的连续播放。
六、什么是烘培,在OSG中怎样实现烘培?
答:烘培又叫纹理烘培,是指经过每帧预渲染一副场景到指定纹理上,实现模型贴图的动态效果。如水面倒影、镜子、倒计时牌上跳动的文字等效果的实现,均可以使用纹理烘培技术。
在OSG中实现纹理烘培是很是容易的,大体步骤以下:
建立纹理对象,设置纹理的大小、像素格式,并把纹理对象绑定到模型;
建立烘培用的相机,指定渲染顺序为PRE_RENDER,指定实现方式为FRAME_BUFFER_OBJECT,并把相机的颜色缓冲区绑定到纹理对象;
把要渲染到纹理上的场景加入相机的下级;
把相机加入场景。
具体例子可参考examples\osgprerender或demos\RTT
七、为何个人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相机的视口和投影矩阵。
八、什么是VBO,什么是DisplayList?
答:VBO和DisplayList是OpenGL提供的两种用于提升渲染效率的技术。
VBO(Vertex Buffer Object)-顶点缓冲区对象,DisplayList-显示列表。
在使用VBO时,若是修改顶点数组内容,则须要调用顶点数组的dirty()函数应用修改;使用DisplayList时,若是修改顶点数组内容,则须要调用dirtyDisplayList()来应用修改。
OSG中缺省使用显示列表而不使用VBO。
九、OSG中分页数据库线程、渲染线程和筛选线程是在何时退出的?
答:1.osgViewer::Viewer对象析构时会调用stopThreading同步退出渲染和筛选线程,并调用DatabasePager::cancel通知分页数据库线程退出。
2.在收到WM_CLOSE消息时会调用stopThreading同步退渲染和筛选线程。
3.能够在须要的时候手动调用stopThreading同步退出渲染和筛选线程。
十、OSG处理事件的时机和顺序是怎样的?
答:OSG在Viewer::eventTraversal函数中处理输入事件,eventTraversal在帧循环的更新遍历和渲染遍历以前被调用。
eventTraversal中事件处理的顺序为:
1.为本帧每个事件遍历场景树,调用Node、Drawable、StateSet对象的事件处理回调处理事件。
2.为本帧每个事件遍历Viewer的事件处理器(GUIEventHandler)队列,调用事件处理器处理事件。
3.为本帧每个事件,调用Viewer的相机操做器(CameraManipulator)处理事件。
十一、Switch(开关)节点的做用是什么?
答:Switch节点继承自Group节点,对应于childLis有一个boolList,为每个子节点保存了一个开关值,当子节点开关关闭时,保证子节点不会被访问类型为Active子节点的访问器访问到。
当子节点开关关闭时,子节点不参与包围盒计算。
十二、NodeMask、TraversalMask的做用是什么?
答:NodeMask(32位无符号整形)做为Node类的属性,用于限定节点是否能被指定的节点访问器访问。缺省值为0xffffffff。
TraversalMask(还有OverrideMask)做为节点访问器的属性,用于限定节点访问器可以访问哪些节点。缺省值为0xffffffff。
节点是否能被访问器访问取决于:TraversalMask & ( OverrideMask | NodeMask )
1三、osg::ColorMask的做用是什么?
答:ColorMask封装了glColorMask函数的功能,用于设置对颜色缓冲区的写掩码,即设置是否对R、G、B、A位执行写入操做。
在只须要写深度缓冲或模板缓冲,而不实际绘制物体时,可使用ColorMask并设置对RGBA的写入掩码均为false。
1四、怎样布局屏幕元素(文字、图片等)
答:屏幕元素通常使用HUD的方式(即正交投影)渲染,在osg中能够定义一个正交投影的相机,把屏幕元素做为子节点添加给这个HUD相机进行渲染。元素的布局和缩放,通常有两种处理方式:
1、 按视口实际大小布局,同时跟踪输出窗口的大小变化,并按窗口实际大小更新HUD相机的投影矩阵和视口。这种方式不但要动态更新相机的投影矩阵和视口,并且要本身编写代码根据视口大小变化动态更新屏幕元素的位置和大小,如按指定的对齐方式更新位置、按指定的尺寸比例更新大小。也能够只更新位置不更新大小,这样获得的效果就是屏幕元素的大小不随窗口缩放。
2、 按指定的固定大小布局,同时设置HUD相机的投影矩阵为以相同宽高计算的固定值,跟踪输出窗口大小变化,按窗口实际大小更新HUD相机的视口。这种方式只须要编写代码更新相机的视口便可,而屏幕元素的大小和位置始终按初始的固定视口大小计算,不需随窗口变化作调整。这样获得的效果就是屏幕元素的大小和布局与窗口等比缩放。
1五、setAttribute与setAttributeAndModes的异同
答:setAttribute用于设置渲染属性和属性的覆盖模式,第二个参数的有效值只有OVERRIDE和PROTECTED的组合,不影响属性状态的开关(设置ON/OFF是无效的)!
setAttributeAndModes设置渲染属性和覆盖模式的同时,也会设置属性状态的开关。
setAttribute用于只需设置渲染属性而不改变状态的场合,具体是否打开该状态取决于子节点的设置。
1六、OSG场景筛选中有哪些优化效率的算法
答:OSG场景筛选主要用到的筛选方法有:视景体筛选、最小像素筛选和遮挡筛选。其中视景体筛选是最基本和最经常使用的筛选方法,它的算法是:使用构成视景体的各个面与节点包围盒求交,若是节点在某个面之外,则剔除掉该节点及其子节点;若是节点彻底在某个面之内,则该节点的全部子节点在进行筛选计算的时候不须要再与这个面求交(子节点必然也彻底在这个面之内)。鉴于这种筛选实现,恰当使用树形结构场景图组织场景节点,可以提升筛选效率。
1七、我在MFC的Static控件中使用OSG渲染,但不能响应鼠标事件是为何?
答:这彻底是MFC控件使用的问题,要使对话框中的Static控件接收鼠标消息,须要把Static控件属性的Notify设置为True。
1八、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(根节点)的子节点。
1九、OSG对组合键是怎样映射的?答:因为Win32 API的特色,OSG不得不将Ctrl+letter变换到了{1,..,26},也就是说,CTRL+a的getKey()为1,而CTRL+z的getKey()为26;Shift+a~z被映射到大写的'A'~'Z'。