美文网首页
OSG3.7.0+VS2017编译

OSG3.7.0+VS2017编译

作者: downdemo | 来源:发表于2019-02-13 10:17 被阅读0次

    编译OSG3.7.0

    1. 编译过程参考Compiling with Visual Studio,需要的安装包可在osgChinaOSG官网获取。以下是此次编译过程中所用的工具版本及其下载地址:
    1. 新建E:\OSG3.7.0,下载上述前三个压缩包并解压到此目录
    所需要的源码包
    1. E:\OSG3.7.0\OpenSceneGraph-master新建一个build文件夹用于存放编译内容
    在OSG源码包目录下新建build文件夹
    1. 安装cmake-3.13.3-win64-x64.msi,安装完成后重启电脑,否则Configure时可能出现error in configuration process project files may be invalid的错误
    cmake安装后的程序位置
    1. 打开CMake (cmake-gui),将E:\OSG3.7.0\OpenSceneGraph-master\CMakeLists.txt拖到CMake (cmake-gui)中(或者手动输入路径),并将构建路径改为新建的E:\OSG3.7.0\OpenSceneGraph-master\build
    在cmake中设置如图的路径
    1. 点击Configure,为了生成64位版本,选择Visual Studio 15 2017 Win64并点击Finish。注意,若此处选择Visual Studio 15 2017则将生成32位版本
    此时即可点击Finish
    1. 等待大概二十秒完成Configure,将出现一批红色选项
    Configure完成
    1. Configure完成后修改如下几个选项,可用Search功能快速找到对应选项
    • ACTUAL_3RDPARTY_DIRE:/OSG3.7.0/3rdParty_x64
    • BUILD_OSG_EXAMPLES:打勾
    • CMAKE_INSTALL_PREFIXE:/OSG3.7.0/OpenSceneGraph-master/build
    用Search快速找到选项
    1. 第二次点击Configure,界面选项仍为红色
    2. 第三次点击Configure,完成后界面将没有红色选项
    第三次点击Configure后
    1. 点击Generate,Generate完成后将在E:\OSG3.7.0\OpenSceneGraph-master\build中生成工程文件,此时即可关闭cmake-gui
    生成新的工程文件
    1. 用VS2017打开E:\OSG3.7.0\OpenSceneGraph-master\build\OpenSceneGraph.sln,等待加载完成。CMake构建的解决方案一般包含三个工程:ALL_BUILDINSTALLZERO_CHECK
    • 只要编译ALL_BUILD就将构建整个工程,相当于makefile的功能
    • 编译INSTALL会将生成的dll和exe文件安装到CMAKE_INSTALL_DIR
    • ZERO_CHECK会监视CMakeLists.txt,只要后者发生改变就会通知编译器重构工程
    1. 打开生成 - 批生成(快捷键Alt+B+T),勾选ALL_BUILD项目的Debug|x64Release|x64配置,点击生成开始编译。若E:\OSG3.7.0\OpenSceneGraph-master\build\lib中有文件生成则说明编译过程顺利进行,大概2.5小时后完成编译,提示========== 生成: 成功 542 个,失败 0 个,最新 0 个,跳过 0 个 ==========
    批生成选项 编译中 ALL_BUILD编译完成
    1. ALL_BUILD项目编译完成后,再勾选INSTALL项目的Debug|x64Release|x64配置,点击生成开始编译
    批生成选项勾选INSTALL
    1. 此步会将所需要的文件复制到E:\OSG3.7.0\OpenSceneGraph-master\buildcmakeincludesharelib中,share中是样例程序。此步一分钟即可完成,提示========== 生成: 成功 2 个,失败 0 个,最新 542 个,跳过 0 个 ==========,编译完成后,编译信息将保存在E:\OSG3.7.0\OpenSceneGraph-master\build\install_manifest.txt
    INSTALL编译完成 install_manifest.txt INSTALL操作过的文件夹

    转移数据

    1. 编译完成后的文件有大概12G,而实际只需要用到其中一部分:
    • 新建C:\OSG文件夹
    • E:\OSG3.7.0\OpenSceneGraph-master\buildbinincludelib复制到C:\OSG
    • E:\OSG3.7.0\OpenSceneGraph-Data拷贝到C:\OSG,并改名为data
    C:\OSG
    1. 添加如下环境变量,并重启电脑以使环境变量生效
    • OSG_ROOTC:\OSG;
    • OSG_BIN_PATH%OSG_ROOT%\bin;
    • OSG_INCLUDE_PATH%OSG_ROOT%\include;
    • OSG_LIB_PATH%OSG_ROOT%\lib;
    • OSG_FILE_PATH%OSG_ROOT%\data;
    • PATH%OSG_BIN_PATH%;
    1. 打开CMD执行以下命令,以检查是否配置成功
    • osgversion // 显示版本号
    • osglogo // 出现三维的logo
    • osgviewer cow.osg // 出现三维的牛
    osgviewer cow.osg

    VS环境测试

    1. 打开VS并新建一个空项目,将Debug调试器设置为x64
    Debug设置为x64
    1. 右键项目打开属性,展开配置属性
    • VC++ 目录 - 包含目录C/C++ - 常规 - 附加包含目录中添加$(OSG_INCLUDE_PATH);
    • VC++ 目录 - 库目录链接器 - 常规 - 附加库目录中添加$(OSG_LIB_PATH);
    • C/C++ - 预处理器 - 预处理器定义设置为WIN32;_WIN32;NDEBUG;
    • 链接器 - 输入 - 附加依赖项设置为(名称以d结尾代表debug版本,以下文件在C:\OSG\lib中都能找到。kernel32.lib开始是VS2017默认设置的库,只需要添加kernel32.lib之前的lib即可)osgWidgetd.lib;osgVolumed.lib;osgUId.lib;osgTerraind.lib;osgSimd.lib;osgShadowd.lib;osgPresentationd.lib;osgParticled.lib;osgManipulatord.lib;osgFXd.lib;osgAnimationd.lib;OpenThreadsd.lib;osgd.lib;osgDBd.lib;osgUtild.lib;osgGAd.lib;osgViewerd.lib;osgTextd.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
    每个lib都有一个debug版本(后缀带d)和release版本
    1. 添加如下源码运行,运行会先弹出一个空的控制台窗口然后显示之前出现过的那头牛
    #include <osgViewer/Viewer>
    #include <osgDB/ReadFile>
    int main( int argc, char **argv ) 
    {
        osgViewer::Viewer viewer;
        viewer.setSceneData( osgDB::readNodeFile( "cow.osg" ) );
        return viewer.run();
    }
    
    1. 样例源码是学习的主要方式,源码在E:\OSG3.7.0\OpenSceneGraph-master\examples中,如examples\osganimate\osganimate.cpp是两架飞机在一个平面上盘旋飞行的源码

    osgQt编译

    • 注意:这里使用的是Qt5.10.1版本,进行下列配置出现问题可能是因为版本不同,如使用Qt5.11.0提示qt5_use_modules命令找不到,原因是Qt5.11.0移除了这个宏。另外的问题可能来源于环境变量,务必检查环境变量的配置,特别是Qt本身的两个环境变量
      • QT5_DIRC:\Qt\Qt5.10.1\5.10.1\msvc2017_64;
      • PATH%QT5_DIR%\bin;
    1. 完成OSG的编译与环境变量的配置后,为了能在Qt界面中嵌入osg模型,还需要编译osgQt,可在此处下载
    2. 将下载的osgQt-master.zip移动到E:\OSG3.7.0并解压,并同样新建一个E:\OSG3.7.0\osgQt-master\build文件夹用于存储编译后的文件
    3. 打开CMakeLists.txt,找到如下两行(130-131行)
    FIND_PACKAGE(OpenSceneGraph 3.0.0 REQUIRED osgDB osgGA osgUtil osgText osgViewer osgWidget)
    SET(OPENSCENEGRAPH_SOVERSION 145)
    
    1. 修改对应的版本号为3.7.0,160
    FIND_PACKAGE(OpenSceneGraph 3.7.0 REQUIRED osgDB osgGA osgUtil osgText osgViewer osgWidget)
    SET(OPENSCENEGRAPH_SOVERSION 160)
    
    1. 打开CMake (cmake-gui),将E:\OSG3.7.0\osgQt-master\CMakeLists.txt拖进去,并把构建目录改为之前新建的build
    2. 点击Configure,选择Visual Studio 15 2017 Win64,点击Finish,等待几秒后Configuring done
    3. 修改值
    • BUILD_OSG_EXAMPLES:打勾
    • CMAKE_INSTALL_PREFIXE:\OSG\osgQt-master\build
    • OSG和Qt的设置项会根据环境变量自动检测路径
      Qt5Core_DIRC:/Qt/Qt5.10.1/5.10.1/msvc2017_64/lib/cmake/Qt5Core
      Qt5Gui_DIRC:/Qt/Qt5.10.1/5.10.1/msvc2017_64/lib/cmake/Qt5Gui
      Qt5Network_DIRC:/Qt/Qt5.10.1/5.10.1/msvc2017_64/lib/cmake/Qt5Network
      Qt5OpenGL_DIRC:/Qt/Qt5.10.1/5.10.1/msvc2017_64/lib/cmake/Qt5OpenGL
      Qt5WebKitWidgets_DIRC:/Qt/Qt5.10.1/5.10.1/msvc2017_64/lib/cmake/Qt5WebKitWidgets
      Qt5WebKit_DIRC:/Qt/Qt5.10.1/5.10.1/msvc2017_64/lib/cmake/Qt5WebKit
      Qt5Widgets_DIRC:/Qt/Qt5.10.1/5.10.1/msvc2017_64/lib/cmake/Qt5Widgets
      Qt5_DIRC:/Qt/Qt5.10.1/5.10.1/msvc2017_64/lib/cmake/Qt5
      配置Qt的msvc2017_64的路径
    1. 再次点击Configure,窗口中的红色全变为白色
    2. 点击Generate,生成工程。E:\OSG3.7.0\osgQt-master\build中将出现生成的osgQt工程,此时可关闭CMake (cmake-gui)
    3. VS2017打开osgQt.sln
    4. 打开生成 - 批生成(快捷键Alt+B+T),勾选ALL_BUILD项目的Debug|x64Release|x64配置,点击生成开始编译。若E:\OSG3.7.0\osgQt-master\build\lib中有文件生成则说明编译过程顺利进行,此步花费一分钟即可完成
    5. ALL_BUILD项目编译完成后,再勾选INSTALL项目的Debug|x64Release|x64配置,点击生成开始编译
    6. INSTALL编译完成后,在E:\OSG3.7.0\osgQt-master\share\OpenSceneGraph\bin中将有四个可运行的样例程序
    7. osgqfont-qt5.exeosgqfont-qt5d.exe的运行结果是弹出一个窗口,然后显示出字体界面
    8. osgviewerQt5.exeosgviewerQt5d.exe的运行结果是弹出一个窗口,然后显示两个窗口界面,左边一个大窗口中有四个区域,分别显示四个模型,右边一个小窗口,显示一辆卡车模型

    osgQt环境配置及测试

    1. 转移数据:
    • E:\OSG3.7.0\osgQt-master\build\bin的所有内容拷贝到C:\OSG\bin
    • E:\OSG3.7.0\osgQt-master\build\osgQt拷贝到C:\OSG\include
    • E:\OSG3.7.0\osgQt-master\build\lib\pkgconfig\openscenegraph-osgQt5.pc拷贝到C:\OSG\lib\pkgconfig
    • E:\OSG3.7.0\osgQt-master\build\libosgQt5.exp、osgQt5.lib、osgQt5d.exp、osgQt5d.lib拷贝到C:\OSG\lib
    osgQt的库文件
    1. 打开VS,新建Qt GUI Application
    新建Qt界面程序
    1. 必须在向导中勾选OpenGL,否则后续会出现无法打开包括文件: “QGLWidget”: No such file or directory的错误,原因是后续使用的osgQt/GraphicsWindowQt中有#include <QGLWidget>
    勾选OpenGL osgQt/GraphicsWindowQt
    1. 项目创建完成,右键项目打开属性-配置属性
    • VC++ 目录 - 包含目录C/C++ - 常规 - 附加包含目录中添加$(OSG_INCLUDE_PATH);
    • VC++ 目录 - 库目录链接器 - 常规 - 附加库目录中添加$(OSG_LIB_PATH);
    • 链接器 - 输入 - 附加依赖项设置为(这里比之前多了osgQt5d.lib,qtmaind.lib开始是Qt5项目默认设置的库,只需要添加qtmaind.lib之前的lib即可)
      osgQt5d.lib;osgWidgetd.lib;osgVolumed.lib;osgUId.lib;osgTerraind.lib;osgSimd.lib;osgShadowd.lib;osgPresentationd.lib;osgParticled.lib;osgManipulatord.lib;osgFXd.lib;osgAnimationd.lib;OpenThreadsd.lib;osgd.lib;osgDBd.lib;osgUtild.lib;osgGAd.lib;osgViewerd.lib;osgTextd.lib;qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5OpenGLd.lib;opengl32.lib;glu32.lib;Qt5Widgetsd.lib;%(AdditionalDependencies)
    1. 以样例代码作为测试。样例代码在最初解压的 E:\OSG3.7.0\osgQt-master\examples中,其中osgqfontosgviewerQt分别对应之前运行的两个程序。以第二个程序为例,打开E:\OSG3.7.0\osgQt-master\examples\osgviewerQt\osgviewerQt.cpp
    osgviewerQt.cpp
    1. 将其内容复制到Qt项目的main.cpp
    // source file "main.cpp"
    #include <QTimer>
    #include <QApplication>
    #include <QGridLayout>
    
    #include <osgViewer/CompositeViewer>
    #include <osgViewer/ViewerEventHandlers>
    
    #include <osgGA/MultiTouchTrackballManipulator>
    
    #include <osgDB/ReadFile>
    
    #include <osgQt/GraphicsWindowQt>
    
    #include <iostream>
    
    class ViewerWidget : public QWidget, public osgViewer::CompositeViewer
    {
    public:
        ViewerWidget(QWidget* parent = 0, Qt::WindowFlags f = 0, osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::CompositeViewer::SingleThreaded) : QWidget(parent, f)
        {
            setThreadingModel(threadingModel);
    
            // disable the default setting of viewer.done() by pressing Escape.
            setKeyEventSetsDone(0);
    
            QWidget* widget1 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile("cow.osgt"));
            QWidget* widget2 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile("glider.osgt"));
            QWidget* widget3 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile("axes.osgt"));
            QWidget* widget4 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile("fountain.osgt"));
            QWidget* popupWidget = addViewWidget(createGraphicsWindow(900, 100, 320, 240, "Popup window", true), osgDB::readRefNodeFile("dumptruck.osgt"));
            popupWidget->show();
    
            QGridLayout* grid = new QGridLayout;
            grid->addWidget(widget1, 0, 0);
            grid->addWidget(widget2, 0, 1);
            grid->addWidget(widget3, 1, 0);
            grid->addWidget(widget4, 1, 1);
            setLayout(grid);
    
            connect(&_timer, SIGNAL(timeout()), this, SLOT(update()));
            _timer.start(10);
        }
    
        QWidget* addViewWidget(osgQt::GraphicsWindowQt* gw, osg::ref_ptr<osg::Node> scene)
        {
            osgViewer::View* view = new osgViewer::View;
            addView(view);
    
            osg::Camera* camera = view->getCamera();
            camera->setGraphicsContext(gw);
    
            const osg::GraphicsContext::Traits* traits = gw->getTraits();
    
            camera->setClearColor(osg::Vec4(0.2, 0.2, 0.6, 1.0));
            camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
    
            // set the draw and read buffers up for a double buffered window with rendering going to back buffer
            camera->setDrawBuffer(GL_BACK);
            camera->setReadBuffer(GL_BACK);
    
            camera->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width) / static_cast<double>(traits->height), 1.0f, 10000.0f);
    
            view->setSceneData(scene);
            view->addEventHandler(new osgViewer::StatsHandler);
            view->setCameraManipulator(new osgGA::MultiTouchTrackballManipulator);
            gw->setTouchEventsEnabled(true);
            return gw->getGLWidget();
        }
    
        osgQt::GraphicsWindowQt* createGraphicsWindow(int x, int y, int w, int h, const std::string& name = "", bool windowDecoration = false)
        {
            osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
            osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
            traits->windowName = name;
            traits->windowDecoration = windowDecoration;
            traits->x = x;
            traits->y = y;
            traits->width = w;
            traits->height = h;
            traits->doubleBuffer = true;
            traits->alpha = ds->getMinimumNumAlphaBits();
            traits->stencil = ds->getMinimumNumStencilBits();
            traits->sampleBuffers = ds->getMultiSamples();
            traits->samples = ds->getNumMultiSamples();
    
            return new osgQt::GraphicsWindowQt(traits.get());
        }
    
        virtual void paintEvent(QPaintEvent* /*event*/)
        {
            frame();
        }
    
    protected:
    
        QTimer _timer;
    };
    
    int main(int argc, char** argv)
    {
        osg::ArgumentParser arguments(&argc, argv);
    
    #if QT_VERSION >= 0x050000
        // Qt5 is currently crashing and reporting "Cannot make QOpenGLContext current in a different thread" when the viewer is run multi-threaded, this is regression from Qt4
        osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::ViewerBase::SingleThreaded;
    #else
        osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::ViewerBase::CullDrawThreadPerContext;
    #endif
    
        while (arguments.read("--SingleThreaded")) threadingModel = osgViewer::ViewerBase::SingleThreaded;
        while (arguments.read("--CullDrawThreadPerContext")) threadingModel = osgViewer::ViewerBase::CullDrawThreadPerContext;
        while (arguments.read("--DrawThreadPerContext")) threadingModel = osgViewer::ViewerBase::DrawThreadPerContext;
        while (arguments.read("--CullThreadPerCameraDrawThreadPerContext")) threadingModel = osgViewer::ViewerBase::CullThreadPerCameraDrawThreadPerContext;
    
    #if QT_VERSION >= 0x040800
        // Required for multithreaded QGLWidget on Linux/X11, see http://blog.qt.io/blog/2011/06/03/threaded-opengl-in-4-8/
        if (threadingModel != osgViewer::ViewerBase::SingleThreaded)
            QApplication::setAttribute(Qt::AA_X11InitThreads);
    #endif
    
        QApplication app(argc, argv);
        ViewerWidget* viewWidget = new ViewerWidget(0, Qt::Widget, threadingModel);
        viewWidget->setGeometry(100, 100, 800, 600);
        viewWidget->show();
        return app.exec();
    }
    
    1. 运行不再弹出黑窗口,而是直接显示之前osgviewerQt5d.exe的两个窗口
    运行结果

    相关文章

      网友评论

          本文标题:OSG3.7.0+VS2017编译

          本文链接:https://www.haomeiwen.com/subject/coxceqtx.html