OSG学习记录一
前言
最近一直在自学OSG相关方面的知识,所以根据最近学习的内容记录一下学习过程中一些容易出错的问题和自己的理解。
编译OSG
网上一大堆,可以参考网上的博客进行编译,但是在进行CMake配置时还是走了不少弯路,以至于编了3遍才编出一个完整的OSG,主要有以下注意部分:
CMake配置
ACTUAL_3RDPARTY_DIR配置
ACTUAL_3RDPARTY_DIR这个配置项很多博客都说填写“E:/GitHub/OpenSceneGraph/3rdParty”,其实这样编出来的OSG是有问题的,这样配置第三方库会导致OSG中缺少图片模块,OSG无法进行图片的相关操作,这是因为OSG在编译时无法找到和图像相关的lib文件,例如jpeg.lib jpegd.lib freetype2311MT.lib等,所以我们需要将第三方库目录配置为“E:/GitHub/OpenSceneGraph/3rdParty/x86”或“E:/GitHub/OpenSceneGraph/3rdParty/x64”无法找到bc6h.lib bc7.lib nvimage.lib nvcore.lib nvmath.lib mvthread.lib
在CMakegui中点击“Configure”时可能会在log中提示无法bc6h.lib bc7.lib nvimage.lib nvcore.lib nvmath.lib mvthread.lib这几个LIB,所以我们在编译OSG之前则需要编译出这几个lib,并放入到“E:/GitHub/OpenSceneGraph/3rdParty/x86/lib”中,这几个Lib是从github上找的源代码,地址是castano/nvidia-texture-tools使用CMake配置出VS的项目后将nvtt重新编译,编译后可能存在错误,但是已经编译出bc6h.lib bc7.lib nvimage.lib nvcore.lib nvmath.lib mvthread.lib这几个lib了,此时将这些文件拷贝到“E:/GitHub/OpenSceneGraph/3rdParty/x86”中,重新点击“Configure”进行配置在CMake中配置OSGQt编译
首先找到OSG根目录中CMakeLists.txt文件,在文件中添加如下代码:
SET(DESIRED_QT_VERSION “5.4.2” CACHE STRING “”)
SET(CMAKE_PREFIX_PATH “C:/Qt/Qt5.4.2/5.4/msvc2010_opengl” CACHE PATH “”)
然后通过CMake重新“Configure”,在CMake中找到“BUILD_PENTHREADS_WITH_QT”千万不要勾选,否则在编译完OSG后,使用OSGQt例子可能导致崩溃。
如果编译过程中碰到其他文件可能就需要自己找问题了,后面就是编译OSG等待4、5个小时编完了。
在Qt中嵌入OSG
走到这一步,则说明以上关于CMake配置以及OSG的编译已经完成了。
在Qt中嵌入OSG其实有两种方式,一种就是利用刚才编译的osgQt模块中“GraphicsWindowQt”进行编写,代码如下:
#include <QtGui/QApplication>
#include <osgViewer/Viewer>
#include <osgGA/TrackballManipulator>
#include <osgQt/GraphicsWindowQt>
#include <osg/ShapeDrawable>
#include <osg/MatrixTransform>
#include <osgManipulator/TabBoxDragger>
#include <osgGA/StateSetManipulator>
#include <osgViewer/ViewerEventHandlers>
#include <osgDB/ReadFile>
int main( int argc, char** argv )
{
QApplication app(argc, argv);
osgQt::initQtWindowingSystem();
osg::Group* sceneroot = new osg::Group;
sceneroot->addChild(osgDB::readNodeFile("cow.osg"));
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
viewer->addEventHandler( new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()) );
viewer->addEventHandler(new osgViewer::StatsHandler);
viewer->setSceneData( sceneroot );
viewer->setCameraManipulator( new osgGA::TrackballManipulator );
osgQt::setViewer( viewer.get() );
osgQt::GLWidget* glw = new osgQt::GLWidget;
osgQt::GraphicsWindowQt* graphicswin = new osgQt::GraphicsWindowQt(glw);
viewer->getCamera()->setViewport( new osg::Viewport(0, 0, glw->width(), glw->height() ) );
viewer->getCamera()->setGraphicsContext( graphicswin );
glw->show();
return app.exec();
}
这是网上找的代码懒得写了,主要是osgQt::GLWidget* glw = new osgQt::GLWidget;
osgQt::GraphicsWindowQt* graphicswin = new osgQt::GraphicsWindowQt(glw);这两行,读者也可以看OSG提供的例子代码osgViewerQt中的代码进行学习。
通过阅读和调试osgQt::GLWidget代码可知,osgQt::GLWidget就是将Qt中QGLWidget重新包装了一下,而osgQt::GraphicsWindowQt是继承于osgViewer::GraphicsWindow,将osgQt::GLWidget当做参数传入osgQt::GraphicsWindowQt中,通过osgQt::GLWidget中的width、heigh以及其他参数构建osg::GraphicsContext::Traits。
如果没有编译osgQt模块的话也是可以将osg嵌入到Qt中的,其实就是将osgQt::GLWidget自己实现,利用QGLWidget将OSG嵌入到Qt中,以下推荐一个兄弟的博客讲的比较清楚kestiny博客,其实也就相当于自己实现了一个osgQt::GLWidget
代码
关于Qt中嵌入OSG代码我都传入到我的GitHub上了,需要可以查看(https://github.com/Timo-China/OSGQtDemo)[https://github.com/Timo-China/OSGQtDemo]