OSG与CEGUI结合

来源:互联网 发布:中金待遇 知乎 编辑:程序博客网 时间:2024/06/05 02:16

首先我的系统中软件版本如下
Visual Studio 2005 SP1
OSG 2.3.7
CEGUI0.6.0-vc8

首先是osgcegui.cpp按照“yucnet”的介绍 稍作修改,另外 我觉得每次在命令行输入sheme、lookandfeel、font等参数比较麻烦 所以干脆在程序中写死了,具体的见代码。程序中使用的TaharezLook.scheme等都是在cegui的官方网站中下载的。
osgcegui.rar (2.6 KB)



VS2005的设置如下
附件包含目录:"C:/CEGUI/CEGUI-SDK-0.6.0-vc8/include"
附件链接库目录:"C:/CEGUI/CEGUI-SDK-0.6.0-vc8/lib"
库依赖:OpenThreadsd.lib osgd.lib osgDBd.lib osgUtild.lib osgGAd.lib osgViewerd.lib osgTextd.lib glew32.lib glu32.lib opengl32.lib CEGUIBase_d.lib OpenGLGUIRenderer_d.lib
程序输出目录、工作目录:C:/OSG/bin
程序命令行参数 cow.osg
特别注意:把CEGUI的dll所在的目录添加到环境变量path,或者干脆拷贝到osgcegui.exe所在的C:/OSG/bin目录。另外,本程序所使用的数据文件也要拷贝到这个目录。
TaharezLook.scheme
TaharezLook.looknfeel
TaharezLook.imageset
TaharezLook.tga
simhei-12.font
simhei.ttf
Demo8.layout
注:CEGUI可以设置setResourceGroupDirectory,在CEGUI中调试可以,但是在osgCEGUI中设置了之后没有效果,找不到对应目录下的sheme、looknfeel、font等文件,无奈之后把上述文件统统拷贝到osgcegui所在的目录了。程序使用相对路径。
也就是说由于本程序的设置,如下几个文件是需要在一起的。
 



目前还不是很好,抛砖引玉吧。注意osg和cegui的版本。

如何运行?
可以再VS2005中设置命令行参数为cow.osg然后直接调试运行,或者在cmd切换到c:/osg/bin,也就是osgcegui所在的目录,然后执行osgcegui cow.osg即可。
运行效果如下:
 

 

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This application is open source and may be redistributed and/or modified  
 * freely and without restriction, both in commericial and non commericial applications,
 * as long as this copyright notice is maintained.
 *
 * This application is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osgViewer/Viewer>
#include <osg/CoordinateSystemNode>
#include <osgGA/GUIEventAdapter>

#include <CEGUISystem.h>
#include <RendererModules/OpenGLGUIRenderer/openglrenderer.h>
#include <CEGUIScriptModule.h>
#include <CEGUIFontManager.h>
#include <CEGUISchemeManager.h>
#include <CEGUIWindowManager.h>
#include <CEGUIExceptions.h>
#include <CEGUIImagesetManager.h>
#include <CEGUIFontManager.h>

#include <iostream>

class CEGUIDrawable : public osg::Drawable
{
public:

    CEGUIDrawable();

    /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
    CEGUIDrawable(const CEGUIDrawable& drawable,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
        Drawable(drawable,copyop) {}
   
    META_Object(osg,CEGUIDrawable);
   
    void loadScheme(const std::string& scheme);
    void loadFont(const std::string& font);
    void loadLayout(const std::string& layout);

    void drawImplementation(osg::RenderInfo& renderInfo) const;

protected:   

    virtual ~CEGUIDrawable();

    unsigned int _activeContextID;

};


struct CEGUIEventCallback : public osgGA::GUIEventHandler
{
    CEGUIEventCallback() {}
   
    /** do customized Event code. */
    virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object* obj, osg::NodeVisitor* nv)
    {
        osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(nv);
        CEGUIDrawable* cd = dynamic_cast<CEGUIDrawable*>(obj);
       
        if (!ev || !cd) return false;
       
        switch(ea.getEventType())
        {
            case(osgGA::GUIEventAdapter::DRAG):
            case(osgGA::GUIEventAdapter::MOVE):
                CEGUI::System::getSingleton().injectMousePosition(ea.getX(),ea.getY());
                return true;
            case(osgGA::GUIEventAdapter::PUSH):
            {
                CEGUI::System::getSingleton().injectMousePosition(ea.getX(), ea.getY());

                if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)  // left
                  CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);

                else if (ea.getButton() == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)  // middle
                  CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::MiddleButton);

                else if (ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)  // right
                  CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::RightButton);
     
                return true;
            }
            case(osgGA::GUIEventAdapter::RELEASE):
            {
                CEGUI::System::getSingleton().injectMousePosition(ea.getX(), ea.getY());

                if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)  // left
                  CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton);

                else if (ea.getButton() == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)  // middle
                  CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::MiddleButton);

                else if (ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)  // right
                  CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::RightButton);
     
                return true;
            }
            case(osgGA::GUIEventAdapter::DOUBLECLICK):
            {
                // do we need to do something special here to handle double click???  Will just assume button down for now.
                CEGUI::System::getSingleton().injectMousePosition(ea.getX(), ea.getY());

                if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)  // left
                  CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);

                else if (ea.getButton() == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)  // middle
                  CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::MiddleButton);

                else if (ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)  // right
                  CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::RightButton);

                return true;
            }
            case(osgGA::GUIEventAdapter::KEYDOWN):
                CEGUI::System::getSingleton().injectKeyDown( static_cast<CEGUI::uint>(ea.getKey()) );
                CEGUI::System::getSingleton().injectChar( static_cast<CEGUI::utf32>( ea.getKey() ) );
                return true;
            case(osgGA::GUIEventAdapter::KEYUP):
                CEGUI::System::getSingleton().injectKeyUp( static_cast<CEGUI::uint>(ea.getKey()) );
                return true;
            default:
                break;
        }

        return false;
    }
};

CEGUIDrawable::CEGUIDrawable()
{
    setSupportsDisplayList(false);

    setEventCallback(new CEGUIEventCallback());

    new CEGUI::System( new CEGUI::OpenGLRenderer(0)); 

     _activeContextID = 0;
}

CEGUIDrawable::~CEGUIDrawable()
{
    // delete CEGUI??
}

void CEGUIDrawable::loadScheme(const std::string& scheme)
{
    try
    {
  CEGUI::SchemeManager::getSingleton().loadScheme("TaharezLook.scheme");
  CEGUI::ImagesetManager::getSingleton().getImageset("TaharezLook");
    }
    catch (CEGUI::Exception e)
    {
        std::cout<<"CEGUIDrawable::loadScheme Error: "<<e.getMessage()<<std::endl;
    }
}

void CEGUIDrawable::loadFont(const std::string& font)
{
    try
    {
  if(CEGUI::FontManager::getSingleton().isFontPresent("SimHei-12"))
   CEGUI::FontManager::getSingleton().getFont("SimHei-12");
  else
   CEGUI::FontManager::getSingleton().createFont("SimHei-12.font");
        //CEGUI::FontManager::getSingleton().createFont(font.c_str());
    }
    catch (CEGUI::Exception e)
    {
        std::cout<<"CEGUIDrawable::loadFont Error: "<<e.getMessage()<<std::endl;
    }
}

void CEGUIDrawable::loadLayout(const std::string& layout)
{
    try
    {
        CEGUI::Window* myRoot = CEGUI::WindowManager::getSingleton().loadWindowLayout("Demo8.layout");
        CEGUI::System::getSingleton().setGUISheet(myRoot);
    }
    catch (CEGUI::Exception e)
    {
        std::cout<<"CEGUIDrawable::loadLayout error: "<<e.getMessage()<<std::endl;
    }

}

void CEGUIDrawable::drawImplementation(osg::RenderInfo& renderInfo) const
{
    osg::State& state = *renderInfo.getState();

    if (state.getContextID()!=_activeContextID) return;

    glPushAttrib(GL_ALL_ATTRIB_BITS);

    state.disableAllVertexArrays();

    CEGUI::System::getSingleton().renderGUI();

    glPopAttrib();
   
    state.checkGLErrors("CEGUIDrawable::drawImplementation");
}

int main( int argc, char **argv )
{
    // use an ArgumentParser object to manage the program arguments.
    osg::ArgumentParser arguments(&argc,argv);
   

    // construct the viewer.
    osgViewer::Viewer viewer;

 viewer.realize();      

 viewer.getCamera()->getGraphicsContext()->makeCurrent();

    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
    osg::ref_ptr<CEGUIDrawable> cd = new CEGUIDrawable();
    geode->addDrawable(cd.get());
   
    cd->loadScheme("");
    cd->loadFont("");
    cd->loadLayout("");
   
    osg::Timer_t start_tick = osg::Timer::instance()->tick();

    // read the scene from the list of file specified command line args.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);

    // if no model has been successfully loaded report failure.
    if (!loadedModel)
    {
        std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
        return 1;
    }

    osg::ref_ptr<osg::Group> group = new osg::Group;
    group->addChild(loadedModel.get());
   
    group->addChild(geode.get());


    // any option left unread are converted into errors to write out later.
    arguments.reportRemainingOptionsAsUnrecognized();

    // report any errors if they have occurred when parsing the program arguments.
    if (arguments.errors())
    {
        arguments.writeErrorMessages(std::cout);
    }

    osg::Timer_t end_tick = osg::Timer::instance()->tick();

    std::cout << "Time to load = "<<osg::Timer::instance()->delta_s(start_tick,end_tick)<<std::endl;


    // optimize the scene graph, remove redundant nodes and state etc.
    osgUtil::Optimizer optimizer;
    optimizer.optimize(loadedModel.get());

    // pass the loaded scene graph to the viewer.
    viewer.setSceneData(group.get());

    // run the viewer
    return viewer.run();
}