Hi, Слава

have you already took a look in to the OSG Faq, can be found here 
http://www.3drealtimesimulation.com/osg/osg_faq_1.htm
It is pretty old, but maybe there are some usefull information for you.

I've attached some part of my code, which uses OSG without the viewer.run() 
method. I know this is out of context, however maybe this would be helpfull for 
you. Take a look into ViewerTask::updateTask() method.

Cheers,
art

P.S. Please write your name with latin letters (Vjacheslav) or similar, because 
we are like to have some neutral language in the community. Спасибо за 
понимание ;)

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=8737#8737



/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "ViewerTask.h"
#include "App.h"

using namespace nrEngine;

//--------------------------------------------------------------------------
SharedPtr<ViewerTask> ViewerTask::mSingleton;

//--------------------------------------------------------------------------
ViewerTask* ViewerTask::instance()
{
    if (mSingleton == NULL)
        mSingleton.reset(new ViewerTask(App::instance()));
    return mSingleton.get();
}

//--------------------------------------------------------------------------
SharedPtr<ViewerTask> ViewerTask::shared_instance(bool release)
{
    if (mSingleton == NULL) mSingleton.reset(new ViewerTask(App::instance()));
    if (release == true) mSingleton.reset();
    
    return mSingleton;
}

#if 1
//------------------------------------------------------------------------
ScriptFunctionDec(resizeWindow, ViewerTask)
{
    // check if the parameter count is valid
    if (args.size() <= 2 && param.size() != 1){
        return ScriptResult(std::string("resizeWindow(w,h) - wrong parameter count"));
    }

    // convert the given values
    nrEngine::int32 width = 0;
    nrEngine::int32 height = 0;
    try{
        width = boost::lexical_cast<nrEngine::int32>(args[1]);
        height = boost::lexical_cast<nrEngine::int32>(args[2]);
    }catch(...){
        return ScriptResult(std::string("Given values are not valid!"));
    }
    
    // get viewer of the application
    ViewerTask* viewer = ScriptEngine::parameter_cast<ViewerTask*>(param[0]);
    osgViewer::Viewer::Windows windows;
    viewer->getWindows(windows);

    // resize window
    windows[0]->setWindowRectangle(0,0,width,height);
    viewer->mApp->mWindowWidth = width;
    viewer->mApp->mWindowHeight = height;

    return ScriptResult();
}

//------------------------------------------------------------------------
ScriptFunctionDec(setWindowTitle, ViewerTask)
{
    // check if the parameter count is valid
    if (args.size() <= 1 && param.size() != 1){
        return ScriptResult(std::string("setWindowTitle(title) - wrong parameter count"));
    }

    // combine the values
    std::string title;
    for (uint32 i=1; i < args.size(); i++)
        title += (args[i] + " ");

    // get viewer of the application
    ViewerTask* viewer = ScriptEngine::parameter_cast<ViewerTask*>(param[0]);
    osgViewer::Viewer::Windows windows;
    viewer->getWindows(windows);

    // set title
    windows[0]->setWindowName(title);
    
    return ScriptResult();
}

//------------------------------------------------------------------------
ScriptFunctionDec(openWindow, ViewerTask)
{

    // check if the parameter count is valid
    if (args.size() <= 3 && param.size() != 1){
        return ScriptResult(std::string("openWindow(w,h,full[,bpp,depth,stencil]) - wrong parameter count"));
    }

    // convert given values
    int32 w,h;
    int32 bpp = 32;
    int32 depth = 16;
    int32 stencil = 8;
    bool full = false;

    try{

        w = boost::lexical_cast<int32>(args[1]);
        h = boost::lexical_cast<int32>(args[2]);
        full = boost::lexical_cast<bool>(args[3]);
        if (args.size() > 4) bpp = boost::lexical_cast<int32>(args[4]);
        if (args.size() > 5) depth = boost::lexical_cast<int32>(args[5]);
        if (args.size() > 6) stencil = boost::lexical_cast<int32>(args[6]);
        
    }catch(...){
        return ScriptResult(std::string("Wrong parameters used!"));
    }

    // get viewer of the application
    ViewerTask* viewer = ScriptEngine::parameter_cast<ViewerTask*>(param[0]);

    osg::DisplaySettings* display = viewer->getDisplaySettings();
    if (display == NULL) display = new osg::DisplaySettings;

    // create window
    if (full == false)
    {
        unsigned int screenWidth;
        unsigned int screenHeight;
        osg::GraphicsContext::getWindowingSystemInterface()->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), screenWidth, screenHeight);
        viewer->setUpViewInWindow((screenWidth-w)/2, (screenHeight-h)/2, w,h);
    }else
    {
        display->setScreenWidth(w);
        display->setScreenHeight(h);
        viewer->setUpViewOnSingleScreen();
    }

    // setup other parameters
    if (depth)
    {
    }

    viewer->mApp->mWindowWidth = w;
    viewer->mApp->mWindowHeight = h;

    return ScriptResult();
}
#endif

//--------------------------------------------------------------------------
ViewerTask::ViewerTask(App* app) : osgViewer::Viewer(), nrEngine::ITask("ViewerTask"), 
    mApp(app)
{
    // setup threading mode
    setThreadingModel(osgViewer::Viewer::SingleThreaded);    

    std::vector<ScriptParam> param;
    param.push_back(this);
    Engine::sScriptEngine()->add("openWindow", openWindow, param);
    Engine::sScriptEngine()->add("resizeWindow", resizeWindow, param);
    Engine::sScriptEngine()->add("setWindowTitle", setWindowTitle, param);
    

}

//--------------------------------------------------------------------------
ViewerTask::~ViewerTask()
{

}

#if 0

//--------------------------------------------------------------------------
int ViewerTask::run()
{
    return 0;
}

//--------------------------------------------------------------------------
void ViewerTask::viewerInit()
{
    osgViewer::Viewer::viewerInit();
}
#endif

//--------------------------------------------------------------------------
Result ViewerTask::onAddTask()
{
    #if 0
    // setup viewer's default camera
    osg::Camera* camera = getCamera();

    // set up the background color and clear mask.
    camera->setClearColor(osg::Vec4(0.0f,0.0f,0.0f,0.0f));
    camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // set viewport
    camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);

    // tell the camera to use OpenGL frame buffer object where supported.
    camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER);
    #endif

    return OK;
}

//--------------------------------------------------------------------------
Result ViewerTask::stopTask()
{
    
    Engine::sScriptEngine()->del("openWindow");
    Engine::sScriptEngine()->del("resizeWindow");
    Engine::sScriptEngine()->del("setWindowTitle");
    
    //setDone(true);

    #if 1
    Contexts contexts;
    getContexts(contexts);

    // stop threading and close windows for every context
    for(Contexts::iterator citr = contexts.begin();
        citr != contexts.end();
        ++citr)
    {

        // get window
        osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
        if (gw)
        {
            bool wasThreading = areThreadsRunning();
            if (wasThreading) stopThreading();
            
            gw->close();
            _currentContext = NULL; 
            
            if (wasThreading) startThreading();
        }
    }


    setDone(true);
    stopThreading();
    #endif

    return OK;   
}

#if 0
//--------------------------------------------------------------------------
void ViewerTask::setMousePosition(int x, int y)
{
    float local_x = x;
    float local_y = y;

    /*const osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState(); 

    bool view_invert_y = eventState->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;

    float local_x = static_cast<double>(_camera->getGraphicsContext()->getTraits()->width) * (x - eventState->getXmin())/(eventState->getXmax()-eventState->getXmin());
    float local_y = view_invert_y ?
                static_cast<double>(_camera->getGraphicsContext()->getTraits()->height) * (1.0 - (y- eventState->getYmin())/(eventState->getYmax()-eventState->getYmin())) :
                static_cast<double>(_camera->getGraphicsContext()->getTraits()->height) * (y - eventState->getYmin())/(eventState->getYmax()-eventState->getXmin());
    */
    // change cursor of the master camera
    const osgViewer::GraphicsWindow* gw = dynamic_cast<const osgViewer::GraphicsWindow*>(getCamera()->getGraphicsContext());
    if (gw)
    {
        //getEventQueue()->mouseWarped(x,y);
        if (gw->getEventQueue()->getCurrentEventState()->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS)
        {
            local_y = gw->getTraits()->height - local_y;
        }
        //const_cast<osgViewer::GraphicsWindow*>(gw)->getEventQueue()->mouseWarped(local_x,local_y);
        const_cast<osgViewer::GraphicsWindow*>(gw)->requestWarpPointer(local_x, local_y);
    }

}
#endif

//--------------------------------------------------------------------------
Result ViewerTask::updateTask()
{
    if (_done) return OK;

    if (_firstFrame)
    {
        viewerInit();
        
        if (!isRealized())
        {
            realize();
        }
        
        _firstFrame = false;
    }
    advance(Engine::sClock()->getFrameInterval());
    
    eventTraversal();
    updateTraversal();

    // compute the time needed for rendering
    struct timeval start;
    gettimeofday(&start, NULL);
    
    renderingTraversals();

    struct timeval end;
    double elapsed;
    gettimeofday(&end, NULL);
    elapsed = end.tv_sec-start.tv_sec + (end.tv_usec/1e6 - start.tv_usec/1e6);

    Engine::sPropertyManager()->set((float)elapsed, "fRenderFrameInterval", "renderer");
    Engine::sPropertyManager()->set((float)(1.0 / elapsed), "fRenderFPS", "renderer");

    //osgViewer::Viewer::frame();
    return OK;
}

#if 1
//--------------------------------------------------------------------------
void ViewerTask::eventTraversal()
{
    if (_done) return;

    double beginEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());

    // this queue will hold all events at the current time
    osgGA::EventQueue::Events events;

    // check camera
    osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState(); 
    if (getCamera()->getViewport()) 
    {
        osg::Viewport* viewport = getCamera()->getViewport();
        eventState->setInputRange( viewport->x(), viewport->y(), viewport->x() + viewport->width(), viewport->y() + viewport->height());
    }
    else
    {
        eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
    }

    // get events from each context 
    Contexts contexts;
    getContexts(contexts);
    for(Contexts::iterator citr = contexts.begin();
        citr != contexts.end();
        ++citr)
    {
        osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
        if (gw)
        {
            gw->checkEvents();
            
            osgGA::EventQueue::Events gw_events;
            gw->getEventQueue()->takeEvents(gw_events);

            // copy event from the window to the queue
            events.insert(events.end(), gw_events.begin(), gw_events.end());
        }
    }
    

    // just 
    _eventQueue->frame( getFrameStamp()->getReferenceTime() );
    _eventQueue->takeEvents(events);
    unsigned countEvents = 0;

    // inform every handler about every event
    for(osgGA::EventQueue::Events::iterator itr = events.begin();
        itr != events.end();
        ++itr)
    {
        osgGA::GUIEventAdapter* event = itr->get();

        for(EventHandlers::iterator hitr = _eventHandlers.begin();
            hitr != _eventHandlers.end();
            ++hitr)
        {
            (*hitr)->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *this, 0, 0);
        }
        countEvents ++;

    }
    
    // setup event visitor and use it to pass events down to the scene graph
    if (_eventVisitor.valid() && getSceneData())
    {
        _eventVisitor->setFrameStamp(getFrameStamp());
        _eventVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber());

        for(osgGA::EventQueue::Events::iterator itr = events.begin();
            itr != events.end();
            ++itr)
        {
            osgGA::GUIEventAdapter* event = itr->get();

            _eventVisitor->reset();
            _eventVisitor->addEvent( event );

            getSceneData()->accept(*_eventVisitor);

            // call any camera update callbacks, but only traverse that callback, don't traverse its subgraph
            // leave that to the scene update traversal.
            osg::NodeVisitor::TraversalMode tm = _eventVisitor->getTraversalMode();
            _eventVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE);

            if (_camera.valid() && _camera->getEventCallback()) _camera->accept(*_eventVisitor);

            for(unsigned int i=0; i<getNumSlaves(); ++i)
            {
                osg::Camera* camera = getSlave(i)._camera.get();
                if (camera && camera->getEventCallback()) camera->accept(*_eventVisitor);
            }

            _eventVisitor->setTraversalMode(tm);

        }
    }

    
    // just some statistics
    if (getStats() && getStats()->collectStats("event"))
    {
        double endEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());

        // update current frames stats
        getStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal begin time", beginEventTraversal);
        getStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal end time", endEventTraversal);
        getStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal time taken", endEventTraversal-beginEventTraversal);
    }

}

//--------------------------------------------------------------------------
void ViewerTask::getUsage(osg::ApplicationUsage& usage) const
{
    for(EventHandlers::const_iterator hitr = _eventHandlers.begin();
        hitr != _eventHandlers.end();
        ++hitr)
    {
        (*hitr)->getUsage(usage);
    }
}
#endif

_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to