关于OSG更多常见问题解答可以在下面找到。
问题
1. 一般
2. 文档
3. 网站
4. 建筑/安装
5. 功能/特性
6. 开发 - 一般
8. 问题
10. 数学,矩阵,向量,四元数
我不知道什么是OpenSceneGraph,你可以给我一个简短的描述吗?
它是一个C ++程序员的3D图形库。场景 库允许你使用图形数据结构代表一个场景中的对象,它允许你将共享一些共同属性的对象组织在一起,这样你就可以在一个地方为整个组设置通用属性。而且OpenSceneGraph可用于自动管理一些像细节层次的事情,绘制那些必要的细节,而不绘制没有必要的,这样就不会拖慢图形硬件绘制场景的速度。
Microsoft Windows(2000,XP,Vista),GNU / Linux和MacOS / X是目前支持最好的系统。 而对Solaris,IRIX,...这些系统并不支持。
OpenSceneGraph支持哪些渲染引擎(如OpenGL,DirectX等)?
OpenSceneGraph只支持通过OpenGL渲染。事实上,很多在库中的类都仅仅是OpenGL的面向对象版本。
我在哪里可以得到更多的关于OpenSceneGraph的信息?
试试这些:
看看官方主页http://www.openscenegraph.org/(此FAQ位于那里)
加入邮件列表,特别是“OSG用户”。请参见邮件列表获取更多信息。
通过引用计数进行内存管理。请参阅下面的相关问题,在“开发-常规”中。
使用设计模式,如遍历器模式(Visitor)和观察者模式(Observer)。
默认情况下,OpenSceneGraph自动管理裁剪平面,充分利用Z缓冲的精度。这意味着,任何企图手动设置远近裁剪面的值都将失败,因为该值将被覆盖。
默认情况下,OpenSceneGraph使用小特征剔除,这意味着当一个对象在当前视图中非常小时(约几个像素),它会被裁剪。
在OSG中矩阵使用左乘向量,如V'= V * M1 * M2。这是最明显的与计算机图形学的教科书中描述不同的点。
OpenSceneGraph 提供对很多3D和图像文件格式的读取支持,但是OpenSG支持的少得多
OpenSceneGraph 发展的更加积极(至少,通过OpenSG的发行数量来看),并可能有更多活跃的用户社区
OpenSG对多线程场景图的操作支持的更好,这是原始设计目标之一
OpenSG有更好的集群渲染支持,虽然使用OpenSceneGraph自己建立也并不困难
VisualStudio:OSG源码包含了一个在OSG / PlatformSpecifics / Windows目录中的文件
VIm:可以在每个头文件的开头识别模式字符串“ - * - c ++ - * - ”。启动vim。键入“:set runtimepath”以查看vim在哪里寻找脚本。您可以在任何这些目录中创建文件(例如,Linux上的〜/ .vim)。创建目录,如果它不存在,并在该目录中创建一个名为scripts.vim的文件。这里是该文件的内容:
Emacs:应该立即识别模式字符串。
Nedit:可以告诉将文件视为C ++基于它们在include目录中的位置
Dev-C ++:在工具/编辑器选项/一般有一个选项“使用语法高亮”。在下面的框中添加;; 。最后一行看起来是这样:c; cpp; h; hpp ;; 。这将使所有文件中的语法高亮无扩展名。
什么背景知识是必需的/有用的,如果我想用 OpenSceneGraph工作?
由于OSG是用C ++写的,你需要能使用该语言编程。
看OSG的一种方法是把它当作OpenGL的一个面向对象的封装。这其实是一种过于简单的观点,因为OSG做了很多而不仅仅是发送你的OpenGL命令。但是,确实有必要学习OpenGL的工作原理,以便更好的使用OpenSceneGraph。在使用OSG时,任何你之前知道的OpenGL知识将都是有价值的。很多人从刚刚开始接触OpenSceneGraph时遇到的问题际上是有关OpenGL的基本问题。
还有一些新人感兴趣的关于OSG的其他主题包括:
对于那些已经熟悉(实时)3D渲染,但不了解OSG的小伙伴,某些功能变成常见的陷阱:
OpenSceneGraph和OpenSG有什么区别?
他们是不同的场景图形库,虽然OpenSG也似乎在他们的代码中使用“OSG”前缀,这可能是有些混乱的根源。两者在目标和功能上的区别有:
OpenSG网站也提供了两者之间的比较:http://opensg.vrsource.org/trac/wiki/OSGComparison
这些书都在不断修订之中,以跟上OSG的变化。购买书籍帮助资助这方面的努力。更多OSG的书籍,不仅仅是修订,计划在未来推出。
是的,看这里 。
还没有场景描述语言的文档(目前没有)。 可以参考OSG的源代码(UseTheSourceLuke! ),特别是在源分布在src / osgPlugins / OSG目录下的文件。
对于任何有OpenGL和OSG类知识的任何人,.osg格式应该很容易理解。
本网站需要登录(见登 录)。请注意,某些页面只能由管理员进行编辑,包括主页,项目新闻和下载部分的所有页面。
可以首先创建一篇新的文章就可以添加新的一页了。这可以使用递交文章 菜单键完成。你应该遵循作者指导。
是的,但仅适用于Windows。对于Linux,你需要自己构建OSG或检查你的Linux发行版是否有OSG包。在Mac OS / X,你需要自己构建OSG。
我没有 在使用微软的Visual Studio,OpenSceneGraph是否支持其他编译器,如mingw32?
在Cygwin和Mingw的发行版中有一个版本,但是它主要由OSG用户邮件列表中用户支持。
帮帮我!VisualStudio无法加载OSG项目文件
如果输出信息为"This makefile was not generated by Developer Studio",是因为.DSP文件因为某种原因被保存为Unix风格的结尾。您可以通过多种方法解决此问题。建议包括:使用写字板打开和保存.DSP,使用cygwin的工具unix2dos,或者使用Winzip日常压缩包(检查在选项 - >配置 - >其他“TAR文件智能CR / LF转换”之后)。
编译 完成后,出现连接问题或当我运行我的OSG应用程序时出现崩溃
在Linux上,尝试“make clean”,然后选择“make”。在Windows上做清除并构建操作。此问题有时是因为API的改变或一个项目设置引起/库已被更改。做清除并重新编译即可解决问题。
链接错误也常常是因为在Visual Studio中省略库造成的。转到项目- >设置,在链接选项卡检查下每一个要使用的.dll文件,以及在“对象/库模块”下对应的.lib文件。为了链接到内核调试库,osgd.dll,osgd.lib需要被加入。这些库的搜索路径是在工具- >选项- >目录。
在Linux上,你可能需要添加一个到/etc/ld.so.conf.d/的入口,并运行ldconfig命令,或者设置LD_LIBRARY_PATH包含您安装OSG库的位置。
核心OpenSceneGraph的库提供一个osg::Camera类,它提供各种在场景中捕获图片的控制,作为观察器的一部分或作为场景视图的一部分做纹理渲染效果,如阴影,反射等。osg::Camera定义在OpenSceneGraph /include/osg/Camera。
OSG现在具有osgTerrain NodeKit用于渲染地形,并且多线程分页系统可以被单独使用,或者结合使用用于渲染大地形数据库。同伴项目VirtualPlanetBuilder可用于构建大规模缩放分页数据库,包括字节缩放整个地球地理空间数据库,并直接输出OpenSceneGraph的原生的二进制格式。
如果你想使用连续细节级别的方法见Demeter (http://www.terrainengine.com/ )和虚拟地形项目(http://www.vterrain.org/)中详细的开源方法。
你还是使用wxWidgets(http://www.wxwidgets.org/ )或者Simple Direct Media Layer(http://www.libsdl.org/)更好。两者都是开源并提供OpenGL渲染平台,使OSG可以很好的工作。
查看osgCal它集成了Cal3D与OSG,看这里http://osgcal.sourceforge.net/
文件的输入输出是通过源代码src / osgPlugins目录下的插件支持。查看Support/UserGuides/Plugins 中的可用的插件,以及他们的支持的文件格式和读/写功能。
请注意,某些插件的依赖的外部库需要安装!刚刚开始使用OSG时一个很常见的问题是,为什么一些插件(比如用于读取JPEG图像的插件)不可用。大多数时候,缺少的插件是因为在OSG的构建过程中缺少依赖信息造成的。CMake构建工具需要知道插件的依赖头文件和库的路径,如libjpeg,libtiff,GDAL等。特别是在Windows上,在文件系统中没有库的标准路径。
一些其他的文件格式可以被Virtual Terrain Project(http://www.vterrain.org/ )支持。
从OpenSceneGraph -3.0开始,我们有基于通用序列化程序的可扩展和支持向前/向后兼容性的新的本机文件格式,.osgt ascii文本文件格式,.osgx xml格式和.osgb二进制格式。新格式的可扩展性使最终用户应用程序能够为自己的类添加序列化包装器,从而能够根据自己的应用需要扩展格式。
在OpenSceneGraph -3.0之前有两个本地文件格式,.osg ASCII文件和.ive二进制文件。.osg格式具有可扩展性和灵活性,但速度较慢,而且没有.ive二进制格式紧凑。但后者由于不向前兼容并且不可扩展,所以仅适用于最终用户应用程序不需扩展的场景图形。
是的,有一个示例数据集。实际上,OSG发行版中包含的一些示例取决于它们是否安装。请参阅Downloads/SampleDatasets .
是的。参见源码中包括的osgteapot示例。
可以看一下examples/osghud/osghud.cpp。这个例子创建了一个用于查看3D场景的子图形,另一个图形与osg :: Projection&osg :: MatrixTransform节点一起设置用于在3D图像上绘制2D场景的正交视图。
将相关的节点添加到osg :: Transform(作为子节点)。这允许您通过更改变换矩阵来移动您的场景模型。看看osgreflect示例,它使用了osg :: MatrixTransform?以创建模型的镜像。
Qt 和其他GUI图形框架都有贡献可用的适配器,Gnome/GTK+是否也有提供?
看看OSGEdit的源代码(http://www.sf.net/projects/osgedit)。它包含一个GTK事件适配器(在OSGEdit应用程序源代码中实现的一个C ++类,它将事件从GTK +适配到osgGA通用事件框架)。
我要如何在 .osg 文件中插入注释?或者在 .osg文件中的注释一块内容?
由于允许扩展的.osg解析器的性质,可以通过简单地这样做在.osg文件中插入注释:
Comment {
This file is proprietary and you shoudn't be reading it.
Please close your editor now!
-Microsoft}
你也可以用它来注释掉文件的部分:
Comment {
TexGen {
UniqueID TexGen_4
DataVariance? STATIC
mode SPHERE_MAP=]
}
}
OSG使用引用计数作为其基本内存管理策略。 场景图中的所有节点类(osg :: Node的子类)和许多其他类也是从osg :: Referenced派生的,它保存一个引用计数(一个整数)。不直接使用指向osg :: ref_ptr <>中实例的指针,现在如何更新osg :: Referenced实例的引用计数,取决于有多少个osg :: ref_ptr <>的实例保存了osg :: Referenced实例。实例将长期保持活动,因为其引用计数的更改不会使计数变为零,这意味着至少有一个osg :: ref_ptr <>仍指向实例。只有当最后一个osg :: ref_ptr <>被删除时,引用计数将达到零,并且实例将被删除。
使用OSG :: ref_ptr <>的基本用法
osg::ref_ptr<osg::Group> group = new osg::Group();
// The osg::ref_ptr instance will manage the pointer to the osg::Group
来代替
osg::Group* group = new osg::Group();
有关使用ref_ptr及其详细信息的详细概述,请参阅http://andesengineering.com/OSG_ProducerArticles/RefPointers/RefPointers.html。
为什么OSG头文件没有.h或.hpp扩展名?
简短的回答是,这是标准C ++的命名头。有关更多信息,请参阅osg-users邮件列表上的这些帖子:
http://thread.gmane.org/gmane.comp.graphics.openscenegraph.user/26136
http://osgcvs.no-ip.com/osgarchiver/archives/July2003/0575.html
我可以做什么,使我的编辑器将OSG标头识别为C ++文件?
方法取决于您的编辑器和平台:
if getline(1) =~ '-*-c++-*-'
set filetype=cpp
endif
您可以使用OSG_NOTIFY_LEVEL环境变量来指定一定级别的调试信息。这里是级别,从低到高(取自include / osg / Notify):
ALWAYS
FATAL
WARN
NOTICE
INFO
DEBUG_INFO
DEBUG_FP
默认级别为NOTICE。例如将OSG_NOTIFY_LEVEL设置为INFO,将生成更多输出。
我可以获得CVS或Subversion访问,以便我可以随时更新最新的开发源?
是。OSG源可通过Subversion获得。请参阅有关如何设置SVN访问OpenSceneGraph的开发版本的文档。
我不喜欢使用C ++。有没有包装器可用于其他语言,如Lua?
是的,请参阅 Community/LanguageWrappers。注意,这些包装器都不是官方发行的一部分,因此由外部各方维护。它们在成熟度上也不同。
将更改作为整个文件以及更改的说明发送到osg提交邮件列表。不要在电子邮件发送差异或复制和粘贴摘录,这些将被简单地废除,因为它们对于审查和合并太不可靠了。有关所有详细信息,请参阅MailingLists / SubmissionsProtocol。
或者,您可以在本网站的社区部分下发布更改或提交。这尤其适用于完整的新功能,如NodeKits和插件。上传你的东西到网站后,通知osg用户或osg提交的您的条目列表。
开发 - 特定于Windows
当我尝试将模型节点保存到文件时,OSG 发生崩溃。我用的Windows,VisualStudio(2003/.NET7) 下 STL 也无法正常工作。
这是Microsoft的STL实现的一个已知问题。目前的解决方案是使用STLport(http://www.stlport.org/),并确保您有最新的service pack。如果问题仍然存在,请确保清理原始的OpenSceneGraph构建并从头开始重新编译。下一个版本的VC ++(.NET,版本7)有一个固定的STL实现,所以你就不需要STLport了。
我得到了很多这样的警告信息... Warning C4541: ‘dynamic_cast’ used on polymorphic type ‘class osg::Object’ with /GR-
您需要启用运行时类型标识。对于VisualStudio,您可以将/ GR放在项目选项中。或者在开发环境中找到此选项,单击项目菜单上的设置。然后单击C / C ++选项卡,并在类别框中单击C ++语言。有一个复选框的“启用RTTI”。
如何在.NET控件中嵌入OSG查看器?
osgViewer::Viewer* viewer = new osgViewer::Viewer();
HWND hwnd = (HWND)control->Handle.ToPointer();
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits();
traits->inheritedWindowData = new osgViewer::GraphicsWindowWin32::WindowData( hwnd );
traits->setInheritedWindowPixelFormat = true;
traits->doubleBuffer = true;
traits->windowDecoration = true;
traits->sharedContext = NULL;
traits->supportsResize = true;
RECT rect;
::GetWindowRect( hwnd, &rect );
traits->x = 0;
traits->y = 0;
traits->width = rect.right - rect.left;
traits->height = rect.bottom - rect.top;
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext( traits.get() );
viewer->getCamera()->setGraphicsContext( gc.get() );
viewer->getCamera()->setViewport( new osg::Viewport( 0, 0, traits->width, traits->height ) );
viewer->getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0f, 10000.0f);
问题
为什么在滑翔机演示 Demo中山完全是白色的,没有阴影?或者是我的纹理对象不显示纹理。
有两种可能的原因:
无法找到或未编译读取必要的图像文件格式的插件。对于hang glider演示,这是.rgb文件格式(osgdb_rgb)。在这种情况下,你需要编译rgb插件。
程序找不到它需要的数据文件(纹理)。确保您已下载演示数据文件归档并解压缩它们。确保INSTALL文件中的环境变量设置正确,因为它们告诉查看器在哪里找到数据。在写这篇文章时,他们是OSGHOME,OSGDATA和OSG_FILE_PATH。要在Windows中设置环境变量,请转到控制面板 - > 系统-> 高级->环境变量。
为什么OSG似乎忽略我设置的近/远剪裁平面?
当使用osgViewer :: Viewer(或osgUtil :: SceneView)时,基于当前的视点和可视场景重新计算近和远剪裁平面。这是通过设计来优化深度缓冲器的近/远距离,否则如果near和far被设置为不合理的小或大的值,这可能导致“z-fighting”现象。
您可以通过调用以下方式覆盖此行为:
viewe.getCamera()>setComputeNearFarMode(osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR)
有关此功能的详细示例,请查看osgthirdpersonview示例(在版本2.4中添加)。它显示包含正常场景的一个窗口和显示在第一窗口中使用的相机和剪切平面的第二窗口。通过操作第一个窗口中的视图,您可以看到第二个窗口中的剪切平面。
如果让OpenSceneGraph计算我的远近剪裁平面,如何获得计算值?
这个信息可以通过cull访问者获得(类osgUtil :: CullVisitor?)。
当使用osgUtil :: SceneView?,像这样
sceneView->getCullVisitor()->getCalculatedNearPlane();
sceneView->getCullVisitor()->getCalculatedFarPlane();
当使用osgViewer :: Viewer你可以得到它的osg :: Camera(这是一个子类osg CullVisitor?)
viewer->getCamera()
我试图在Mac OS / X下运行 OpenSceneGraph示例程序,但没有窗口出现!我该怎么办?
您需要在启动程序之前设置以下环境变量:
tcsh:
setenv DYLD_BIND_AT_LAUNCH 1
bash:
export DYLD_BIND_AT_LAUNCH=1
如果在OSX下运行OSG程序时遇到dyld“无法打开库”错误,您可能还需要将DYLD_LIBRARY_PATH环境变量设置为指向OSG库和/或插件。
嘿,这个粒子系统很酷,但是当我把它放在我的场景中看起来很奇怪。这是怎么回事?
你可能是旋转粒子系统和粒子发射器。粒子系统上面的tranform应该匹配你的世界的(绝对)坐标系,或者“包含”粒子的参考系(例如飞机或汽车)。要转换这个参考框架内的粒子系统,你应该只转换发射器,而不是粒子系统的drawables。如果在“fountain.osg”上面应用变换,实际上对发射器和粒子系统应用平移/旋转 ; 要获得正确的行为,您应该遍历场景图形,并避免将变换应用于包含ParticleSystem可绘制对象的任何地图。(答案Marco Jez)
有一个图,描述和源代码在这里:http : //faculty.nps.edu/jasullivan/osgTutorials/osgParticleHelper.htm
我有一个问题使用PrimitiveSet来表示单个点 或我的几何似乎消失,因为它变得非常遥远。这是怎么回事?
默认情况下,OSG使用小特征剔除来剔出占用小于预定屏幕大小的对象。这对于具有许多细节的模型是有价值的特征,当从远处观察时,这些细节对模型的视觉质量没有贡献。你可以通过改变观察者osg :: Camera上的cullingMode来完全禁用小功能剔除:
osg::CullStack::CullingMode cullingMode = viewer.getCamera()->getCullingMode();
cullingMode &= ~(osg::CullStack::SMALL_FEATURE_CULLING);
viewer.getCamera()->setCullingMode( cullingMode );
您还可以控制用于剔除小特征的屏幕空间大小
viewer.getCamera()->setSmallFeatureCullingPixelSize( minimumSize );
当我在 osg :: MatrixTransform中应用一个缩放因子时,我的模型显示被洗掉或变暗。这是怎么回事?
模型的法线可能与其顶点一起缩放。要保持法线归一化,请在适当的状态集上设置OpenGL属性GL_RESCALE_NORMALS:
stateSet->setMode( GL_RESCALE_NORMAL, osg::StateAttribute::ON );
我可以在现有渲染器中使用OSG吗?
这需要一些工作,但完全可以在预先存在的渲染系统中使用OSG。
首先,你应该知道的中心对象是osgViewer :: Viewer和osgViewer :: GraphicsWindowEmbedded。这两个类将管理OSG特定的显示任务。osgviewerSDL和osgviewerGLUT示例说明了如何使用Viewer和GraphicsWindowEmbedded?。
这两个对象的设置将如下所示:
viewer.getCamera()->setComputeNearFarMode( osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR );
viewer.setSceneData( rootNode );
注意,只需将rootNode替换为OSG模型的实际根节点即可。
注意:对setComputeNearFarMode的调用非常重要。如果不这样做,OSG将在渲染其对象时使用不同的近和远平面,并且它们在深度缓冲区中将具有与场景的其余部分不同的值。这可能导致非常奇怪的效果。
如果要使用与渲染器其余部分正在使用的照明不同的照明,则可能需要调用:
viewer.setLightingMode( osg::View::SKY_LIGHT );
要么
viewer.setLightingMode( osg::View::HEADLIGHT );
这基本上是为了安装。
现在你只需要调用!Viewer用于渲染,这需要一些额外的工作。
首先,建议在调用其他OpenGL代码之前调用glPushAttribs(GL_ALL_ATTRIB_BITS)和glPushMatrix为每个模型视图,投影和纹理矩阵,然后调用相应的弹出窗口,并对OSG执行相同的操作。这防止OSG和您的其他OpenGL代码相互干扰。例如:
glPushAttrib=]( GL_ALL_ATTRIB_BITS );
glMatrixMode=](GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
your code here...
glMatrixMode(GL_TEXTURE);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopAttrib();
下一个重要的事情是使用!Viewer是你需要告诉它关于您现有的视口和投影和modelview矩阵。这样做的代码如下所示:
GLint viewParams[4];
glGetIntegerv( GL_VIEWPORT, viewParams );
viewer.getCamera()->setViewport(viewParams[0], viewParams[1], viewParams[2], viewParams[3]);
GLdouble glMat[16];
glGetDoublev( GL_PROJECTION_MATRIX, glMat );
viewer.setProjectionMatrix( osg::Matrix(glMat) );
glGetDoublev( GL_MODELVIEW_MATRIX, glMat );
viewer.setViewMatrix( osg::Matrix(glMat) );
最后,您需要对!Viewer对象进行实际调用:
viewer.frame();
如果你做到这一切,你应该能够在你现有的渲染系统中成功使用OSG,从而获得OSG的许多优点,而不必削减现有的系统。
我从osg :: Drawable派生一个类,但它的drawImplementation()方法只被调用一次。
尝试禁用此类的显示列表。
drawable->setUseDisplayList( false );
否则,将创建一次显示列表,在下次绘制drawable被调用,而不调用您的drawImplementation。
如何获取加载的Node或3D模型的BoundingBox?
获取一个轴对齐osg :: BoundingBox为一个图
osg::ComputeBoundsVisitor cbv;
osg::BoundingBox &bb(cbv.getBoundingBox());
pNode->accept(cbv);
// access as bb._min.x(), etc
出于性能方面的OSG为所有内部节点存储OSG :: BoundingSphere,以及为可绘制的叶节点存储OSG ::BoundingBox。
如果你想使用一个节点的BoundingBox,你可以通过做一些事情将BoundingSphere转换为BoundingBox:
BoundingBox bb;
bb.expandBy(node->getBound());
当使用多个查看器和/或多个渲染窗口时,我得到奇怪的结果,我的纹理不能正确显示。
注意,对于基于osgViewer的查看器是原生支持多个渲染窗口,所以应该没有问题发生,但是,如果用户使用自己定义的例如低级别的osgUtil :: SceneView?问题就可能出现,其余条目适用于此类型的使用。
每个渲染窗口都有自己的OpenGL上下文,它与所有其他上下文分开。由于OSG不知道如何设置您的窗口环境,因此您需要确保每个osg :: State对象都绑定到一个唯一的OpenGL上下文。要做到这一点,你应该:
对于每个窗口,获取相关的对象
对于每个SceneView对象,获取关联的
在每个状态上调用State :: setContextID(),传递一个唯一的数字来标识该上下文。
使用SceneView?的代码:
// this will automatically create the osg::State amoung other operations
sceneview0->setDefaults();
// now set the ID to 0 (this is the default, just set here for clarity
sceneview0->getState()->setContextID(0);
sceneview1->setDefaults();
sceneview1->getState()->setContextID(1);
注意:上下文ID用作自动增长的向量中的索引,因此请避免设置大数字。从0开始计数,然后每次递增1。
我有两个或更多的视图共享一个场景图,但我想限制场景图的一部分在一个或多个视图中显示,我怎么做?
视图中绘制的内容取决于Cull Traversal的结果。每个视图将有一个独特的osgViewer :: View和每个osgViewer :: Viewer将有一个唯一的剔除遍历掩码。您可以在每个视图(或sceneView的cullSettings)上设置遍历掩码,它将对每个视图遍历的节点应用(按位AND)在每个节点上,那么,你可以设置一个CullMask对应于您希望在显示子图的视图。
像这样:
lefView->setCullMask( 0x1);
rightView->setCullMask( 0x2 );
leftNode->setNodeMask(0x1);
rightNode->setNodeMask(0x2);
(维基编辑注意:参考osgProducer :: Viewer)
当使用osgProducer :: Viewer时,方便功能被设置为允许为OsgCameraGroup中的所有摄像机和SceneHandler(包括SceneView)全局设置属性。这包括CullVisitors的遍历掩码,默认情况下它们都将设置为0xFFFFFFFF。在将遍历掩码设置为唯一的[= CullVisitors?=],你需要使它们免受全局设置的干扰(CullSettings应用于CullVisitors在遍历):
osgProducer::Viewer::SceneHandlerList shl = viewer.getSceneHandlerList();
osgProducer::Viewer::SceneHandlerList::iterator p;
unsigned int n = 0;
for( p = shl.begin(); p != shl.end(); p++ )
{
int inheritanceMask = (*p)->getSceneView()->getInheritanceMask();
inheritanceMask &= ~(osg::CullSettings::CULL_MASK);
(*p)->getSceneView()->setInheritanceMask( inheritanceMask );
(*p)->getSceneView()->setCullMask( 1<<(n));
n++;
}
如何捕获屏幕快照?
对于当前的OSG,看看osgscreencapture示例程序。实质上,你只需要附加一个相机后绘制回调。这里有一个非常简单的例子:
struct CaptureCB : public osg::Camera::DrawCallback
{
CaptureCB( int w, int h )
: w_( w ), h_( h )
{}
virtual void operator()( osg::RenderInfo& ri ) const
{
std::string fName( "screen.png" ) );
osg::ref_ptr<osg::Image> image = new osg::Image;
image->readPixels( 0, 0, w_, h_, GL_RGBA, GL_UNSIGNED_BYTE );
osgDB::writeImageFile( *image, fName );
}
int w_, h_;
};
为什么我的帧速率下降,当 渲染点到一个FBO / pbuffer?
短回答:将PointSprite属性的坐标原点模式更改为LOWER_LEFT:
osg::PointSprite *ps = new osg::PointSprite;
ps->setCoordOriginMode(osg::PointSprite::LOWER_LEFT);
长答案:阅读nVidia OpenGL 2.0支持文档中的Point Sprites部分。它规定如下:
在渲染到像素缓冲区(通常称为pbuffer)或帧缓冲区对象(通常称为FBO)时,将GL_POINT_SPRITE_COORD_ORIGIN状态设置为GL_LOWER_LEFT设置,以进行完全硬件加速渲染。使用GL_UPPER_LEFT与pbuffer和FBO渲染将强制点在CPU上转换。
为什么我的几何渲染不透明,而我有透明的颜色和/或材料附加到它?
您需要通过在几何体的状态集(或父节点的状态集)上设置GL_BLEND模式来激活OpenGL混合。
stateSet->setMode( GL_BLEND, osg::StateAttribute::ON );
或者在.osg文件中:
file geom.osg
Geometry {
[...]
StateSet {
GL_BLEND ON
}
PrimitiveSets 1
{
[..]
我写了一个场景包含一个粒子系统 在.ive文件,但一些节点/ drawables似乎丢失
(维基编辑注意:这是否仍然有效2.4?)
.ive文件中当前不支持osgParticle nodekit中的一些节点和drawables。作为解决方法,您可以保存到.osg文件。
旧版本的 OpenSceneGraph
在编译期间我得到关于Producer / *的错误:没有这样的文件或目录。为什么? - 发生与日常builds和0.9.4-2官方。
首先构建并安装OpenProducer。
我可以在没有Producer的情况下使用OSG,和/或已经创建的MFC或WxWindow窗口?
即使您正在创建自己的窗口,也可以使用带或不带Producer的OSG。有关在通用窗口环境中使用OSG的示例,请参阅osgsimple示例。OSG本身是窗口系统不可知的,所以设置窗口和OpenGL图形上下文将取决于你的应用程序。osgsimple使用Producer,但是以一种方式为您提供使用您自己的窗口系统的骨架。
或者,您也可以在自己的窗口环境中使用Producer,方法是将每个Camera的RenderSurface设置为您创建的窗口。像这样:
osgProducer::Viewer viewer;
viewer.getCamera(0)->getRenderSurface()->setWindow( myWindow );
变量“myWindow”是X11窗口或win32 HWND。
有关更多详细信息,请参阅http://osgcvs.no-ip.org/osgarchiver/archives/November2004/1019.html。
如何在运行时更改Producer图标?
在Microsoft Windows和Visual Studio 7.x中:
首先向您的解决方案添加一个图标(项目/添加资源/图标)。
在viewer-> realize()之后执行以下操作:
Producer::Window wnd = viewer->getCamera(0)->getRenderSurface()->getWindow();
HICON h1 = LoadIcon(GetModuleHandle(0), "YOUR_ICON");
DWORD dw = SetClassLongPtr(wnd, GCL_HICON, (LONG_PTR)h1);
字符串“YOUR_ICON”应引用资源文件(.rc)中的图标名称。
数学,矩阵,向量,四元数
(维基编辑注意:也描述了Z-up约定)
OSG中的矩阵,向量和四元数类是什么乘法顺序?
OSG使用后乘法顺序。例如,如果要创建一个首先在所有轴上缩放50%的矩阵,然后围绕X轴旋转90度,最后在X方向上平移2个单位,您将使用
osg::Matrix M = osg::Matrix::scale(0.5, 0.5, 0.5)
* osg::Matrix::rotate(osg::inDegrees(90), osg::X_AXIS)
* osg::Matrix::translate(2, 0, 0));
// Use matrix M with, for example, an osg::MatrixTransform to transform its child nodes
osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform(M);
要改变一个顶点v用矩阵M可以使用v * M。
注意角度以弧度传递。您可以使用以下之一将度数转换为弧度
osg::inDegrees(angle_in_degrees);
osg::DegreesToRadians(angle_in_degrees);
从弧度到度的转换可以使用osg :: inRadians()或osg :: RadiansToDegrees()。
我有其他的问题在这里没有回答...
检查矩阵和四元数常见问题,请访问http://www.j3d.org/matrix_faq/
浏览次数:21009 次