Example #1
0
WINGDIAPI BOOL WINAPI wglMakeCurrent(HDC hdc, DHGLRC hglrc)
{
    if (!gCurrentContextSet)
    {
        gCurrentContext = gContexts.end();
        gCurrentContextSet = true;
    }

    if (!hdc || !hglrc)
    {
        gCurrentContext = gContexts.end();
        return 1;
    }

    int rc = (int)hglrc;

    if (gContexts.find(rc) == gCurrentContext)
    {
        return 1;
    }

    gCurrentContext = gContexts.find(rc);

    auto &xCtxt = gContexts[rc];
    OGL::State *pState = xCtxt.pState;

    HWND hWnd = WindowFromDC(hdc);
    RECT rect;
    GetClientRect(hWnd, &rect);

    int width = rect.right - rect.left;
    int height = rect.bottom - rect.top;

    SetOGL(pState);
    OGL::GetDDProcTable().pfnBindContext(OGL::GetDDHandle(), NULL, hWnd, NULL, width, height);

    // according to spec, only set current viewport to draw buffer dimensions if the context hasn't
    // been initialized
    if (!xCtxt.initialized)
    {
        pState->mViewport.x = 0;
        pState->mViewport.y = 0;
        pState->mViewport.width = width;
        pState->mViewport.height = height;
        pState->mScissor.x = 0;
        pState->mScissor.y = 0;
        pState->mScissor.width = width;
        pState->mScissor.height = height;
        xCtxt.initialized = true;
    }
    return 1;
}
Example #2
0
Viewer::~Viewer()
{
    //OSG_NOTICE<<"Viewer::~Viewer()"<<std::endl;

    Threads threads;
    getAllThreads(threads);

    OSG_INFO<<"Viewer::~Viewer():: start destructor getThreads = "<<threads.size()<<std::endl;

    stopThreading();

    if (_scene.valid() && _scene->getDatabasePager())
    {
        _scene->getDatabasePager()->cancel();
        _scene->setDatabasePager(0);
    }

    Contexts contexts;
    getContexts(contexts);

    // clear out all the previously assigned operations
    for(Contexts::iterator citr = contexts.begin();
        citr != contexts.end();
        ++citr)
    {
        (*citr)->close();
    }

    //OSG_NOTICE<<"finish Viewer::~Viewer()"<<std::endl;

    getAllThreads(threads);

    OSG_INFO<<"Viewer::~Viewer() end destructor getThreads = "<<threads.size()<<std::endl;
}
void CompositeViewer::setStartTick(osg::Timer_t tick)
{
    _startTick = tick;

    for(RefViews::iterator vitr = _views.begin();
            vitr != _views.end();
            ++vitr)
    {
        (*vitr)->setStartTick(tick);
    }

    Contexts contexts;
    getContexts(contexts,false);

    for(Contexts::iterator citr = contexts.begin();
            citr != contexts.end();
            ++citr)
    {
        osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
        if (gw)
        {
            gw->getEventQueue()->setStartTick(_startTick);
        }
    }
}
CompositeViewer::~CompositeViewer()
{
    OSG_INFO<<"CompositeViewer::~CompositeViewer()"<<std::endl;

    stopThreading();

    Scenes scenes;
    getScenes(scenes);

    for(Scenes::iterator sitr = scenes.begin();
            sitr != scenes.end();
            ++sitr)
    {
        Scene* scene = *sitr;
        if (scene->getDatabasePager())
        {
            scene->getDatabasePager()->cancel();
            scene->setDatabasePager(0);
        }
    }

    Contexts contexts;
    getContexts(contexts);

    // clear out all the previously assigned operations
    for(Contexts::iterator citr = contexts.begin();
            citr != contexts.end();
            ++citr)
    {
        (*citr)->close();
    }

    OSG_INFO<<"finished CompositeViewer::~CompositeViewer()"<<std::endl;
}
void CompositeViewer::getOperationThreads(OperationThreads& threads, bool onlyActive)
{
    threads.clear();

    Contexts contexts;
    getContexts(contexts);
    for(Contexts::iterator gcitr = contexts.begin();
            gcitr != contexts.end();
            ++gcitr)
    {
        osg::GraphicsContext* gc = *gcitr;
        if (gc->getGraphicsThread() &&
                (!onlyActive || gc->getGraphicsThread()->isRunning()) )
        {
            threads.push_back(gc->getGraphicsThread());
        }
    }

    Cameras cameras;
    getCameras(cameras);
    for(Cameras::iterator citr = cameras.begin();
            citr != cameras.end();
            ++citr)
    {
        osg::Camera* camera = *citr;
        if (camera->getCameraThread() &&
                (!onlyActive || camera->getCameraThread()->isRunning()) )
        {
            threads.push_back(camera->getCameraThread());
        }
    }

}
Example #6
0
WINGDIAPI HGLRC WINAPI wglGetCurrentContext(VOID)
{
    if (!gCurrentContextSet)
    {
        gCurrentContext = gContexts.end();
        gCurrentContextSet = true;
    }

    if (gCurrentContext == gContexts.end())
    {
        return NULL;
    }
    else
    {
        return reinterpret_cast<HGLRC>(gCurrentContext->first);
    }
}
Example #7
0
WINGDIAPI HDC WINAPI wglGetCurrentDC(VOID)
{
    if (!gCurrentContextSet)
    {
        gCurrentContext = gContexts.end();
        gCurrentContextSet = true;
    }

    if (gCurrentContext == gContexts.end())
    {
        return NULL;
    }
    else
    {
        return gCurrentContext->second.hdc;
    }
}
Example #8
0
Display *glXGetCurrentDisplay()
{
    if (currentContext == contexts.end())
    {
        return NULL;
    }
    auto &xCtxt = currentContext->second;
    return xCtxt.pDisplay;
}
void CompositeViewer::addView(osgViewer::View* view)
{
    if (!view) return;

    bool alreadyRealized = isRealized();

    bool threadsWereRunning = _threadsRunning;
    if (threadsWereRunning) stopThreading();

    _views.push_back(view);

    view->_viewerBase = this;

    if (view->getSceneData())
    {
        // make sure that existing scene graph objects are allocated with thread safe ref/unref
        if (getThreadingModel()!=ViewerBase::SingleThreaded)
        {
            view->getSceneData()->setThreadSafeRefUnref(true);
        }

        // update the scene graph so that it has enough GL object buffer memory for the graphics contexts that will be using it.
        view->getSceneData()->resizeGLObjectBuffers(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts());
    }

    view->setFrameStamp(_frameStamp.get());

    if (alreadyRealized)
    {
        Contexts contexts;
        if (view->getCamera()->getGraphicsContext())
        {
            contexts.push_back(view->getCamera()->getGraphicsContext());
        }
        for(unsigned int i=0; i<view->getNumSlaves(); ++i)
        {
            if (view->getSlave(i)._camera->getGraphicsContext())
            {
                contexts.push_back(view->getSlave(i)._camera->getGraphicsContext());
            }
        }

        for(Contexts::iterator itr = contexts.begin();
                itr != contexts.end();
                ++itr)
        {
            if (!((*itr)->isRealized()))
            {
                (*itr)->realize();
            }
        }

    }

    if (threadsWereRunning) startThreading();
}
Example #10
0
void ExecutableOpHolder::execute( const Contexts &contexts ) const
{
	for ( Contexts::const_iterator cit = contexts.begin(); cit != contexts.end(); cit++ )
	{
		// \todo Implement a way to get the CompoundObject for a given context without modifying the Op's parameter
		// and passing it explicitly in the operate call. Than multi-thread this loop.
		Context::Scope scope( *cit );
		constPointerCast<CompoundParameterHandler>( parameterHandler() )->setParameterValue();
		constPointerCast<Op>( getOp() )->operate();
	}
}
Example #11
0
void ViewerBase::getWindows(Windows& windows, bool onlyValid)
{
    windows.clear();

    Contexts contexts;
    getContexts(contexts, onlyValid);

    for(Contexts::iterator itr = contexts.begin();
        itr != contexts.end();
        ++itr)
    {
        osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*itr);
        if (gw) windows.push_back(gw);
    }
}
Example #12
0
void glXDestroyContext(Display *pDisplay, GLXContext ctx)
{
    auto *pState = reinterpret_cast<OGL::State *>(ctx);

    if (contexts.find(pState) == currentContext)
    {
        currentContext = contexts.end();
    }

    contexts.erase(pState);

    OGL::Destroy(*pState);
    pState->~State();

    _aligned_free(pState);
}
Example #13
0
void ExecutableRender::execute( const Contexts &contexts ) const
{
	const ScenePlug *scene = inPlug()->getInput<ScenePlug>();
	if( !scene )
	{
		throw IECore::Exception( "No input scene" );
	}

	/// \todo This doesn't belong here. It'll be the responsibility of the Despatchers
	/// to save the script if necessary, and to save it to an alternate location than
	/// the current one.
	scriptNode()->save();

	for( Contexts::const_iterator it = contexts.begin(), eIt = contexts.end(); it != eIt; it++ )
	{
		Context::Scope scopedContext( it->get() );
		ConstCompoundObjectPtr globals = scene->globalsPlug()->getValue();

		createDisplayDirectories( globals );

		IECore::RendererPtr renderer = createRenderer();		
		outputOptions( globals, renderer );
		outputCamera( scene, globals, renderer );
		{
			WorldBlock world( renderer );

			outputLights( scene, globals, renderer ); 
			outputWorldProcedural( scene, renderer );
		}
		
		std::string systemCommand = command();
		if( systemCommand.size() )
		{
			const ApplicationRoot *applicationRoot = scene->ancestor<ApplicationRoot>();
			if( applicationRoot && applicationRoot->getName() == "gui" )
			{
				/// \todo We need this weird background execution behaviour because we
				/// don't want to block the ui while rendering, but really the LocalDespatcher
				/// should be responsible for launching a separate process to do the execution
				/// from anyway.
				systemCommand += "&";
			}
			
			system( systemCommand.c_str() );
		}
	}
}
bool CompositeViewer::isRealized() const
{
    Contexts contexts;
    const_cast<CompositeViewer*>(this)->getContexts(contexts);

    unsigned int numRealizedWindows = 0;

    // clear out all the previously assigned operations
    for(Contexts::iterator citr = contexts.begin();
            citr != contexts.end();
            ++citr)
    {
        if ((*citr)->isRealized()) ++numRealizedWindows;
    }

    return numRealizedWindows > 0;
}
Example #15
0
Viewer::~Viewer()
{
    //OSG_NOTICE<<"Viewer::~Viewer()"<<std::endl;

    Threads threads;
    getAllThreads(threads);

    OSG_INFO<<"Viewer::~Viewer():: start destructor getThreads = "<<threads.size()<<std::endl;

    stopThreading();

    if (_scene.valid() && _scene->getDatabasePager())
    {
        _scene->getDatabasePager()->cancel();
        _scene->setDatabasePager(0);
    }

    Contexts contexts;
    getContexts(contexts);

    // clear out all the previously assigned operations
    for(Contexts::iterator citr = contexts.begin();
        citr != contexts.end();
        ++citr)
    {
        osg::GraphicsContext* gc = *citr;

        // Run destroy operation on each context before closing it
        if (_cleanUpOperation.valid() && gc->valid())
        {
            gc->makeCurrent();

            (*_cleanUpOperation)(gc);

            gc->releaseContext();
        }

        gc->close();
    }

    //OSG_NOTICE<<"finish Viewer::~Viewer()"<<std::endl;

    getAllThreads(threads);

    OSG_INFO<<"Viewer::~Viewer() end destructor getThreads = "<<threads.size()<<std::endl;
}
Example #16
0
void Viewer::setStartTick(osg::Timer_t tick)
{
    View::setStartTick(tick);

    Contexts contexts;
    getContexts(contexts,false);

    getEventQueue()->setStartTick(_startTick);
    for(Contexts::iterator citr = contexts.begin();
        citr != contexts.end();
        ++citr)
    {
        osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
        if (gw)
        {
            gw->getEventQueue()->setStartTick(_startTick);
        }
    }
}
Example #17
0
void CompositeViewer::addView(osgViewer::View* view)
{
    bool alreadyRealized = isRealized();

    bool threadsWereRuinning = _threadsRunning;
    if (threadsWereRuinning) stopThreading();

    _views.push_back(view);

    view->_viewerBase = this;

    view->setFrameStamp(_frameStamp.get());

    if (alreadyRealized)
    {
        Contexts contexts;
        if (view->getCamera()->getGraphicsContext())
        {
            contexts.push_back(view->getCamera()->getGraphicsContext());
        }
        for(unsigned int i=0; i<view->getNumSlaves(); ++i)
        {
            if (view->getSlave(i)._camera->getGraphicsContext())
            {
                contexts.push_back(view->getSlave(i)._camera->getGraphicsContext());
            }
        }

        for(Contexts::iterator itr = contexts.begin();
                itr != contexts.end();
                ++itr)
        {
            if (!((*itr)->isRealized()))
            {
                (*itr)->realize();
            }
        }

    }

    if (threadsWereRuinning) startThreading();
}
Example #18
0
void CompositeViewer::renderingTraversals( bool needMakeCurrentInThisThread )
{
    Contexts contexts;
    getContexts( contexts );

    bool doneMakeCurrentInThisThread = false;

    for( Contexts::iterator itr = contexts.begin( );
            itr != contexts.end( ); ++itr )
    {
        if(( *itr )->valid( ))
        {
            if( needMakeCurrentInThisThread )
            {
                doneMakeCurrentInThisThread = true;
                makeCurrent( *itr );
            }
            ( *itr )->runOperations( );
        }
    }

    if( doneMakeCurrentInThisThread )
        releaseContext( );
}
Example #19
0
///\todo: It seems that if a JPG is written with RGBA channels the output is wrong but it should be supported. Find out why and fix it.
/// There is a test case in ImageWriterTest which checks the output of the jpg writer against an incorrect image and it will fail if it is equal to the writer output.
void ImageWriter::execute( const Contexts &contexts ) const
{
	if( !inPlug()->getInput<ImagePlug>() )
	{
		throw IECore::Exception( "No input image." );
	}

	// Loop over the execution contexts...
	for( Contexts::const_iterator it = contexts.begin(), eIt = contexts.end(); it != eIt; it++ )
	{
		Context::Scope scopedContext( it->get() );
		
		std::string fileName = fileNamePlug()->getValue();
		fileName = (*it)->substitute( fileName );
		
		boost::shared_ptr< ImageOutput > out( ImageOutput::create( fileName.c_str() ) );
		if ( !out )
		{
			throw IECore::Exception( boost::str( boost::format( "Invalid filename: %s" ) % fileName ) );
		}
		
		// Grab the intersection of the channels from the "channels" plug and the image input to see which channels we are to write out.
		IECore::ConstStringVectorDataPtr channelNamesData = inPlug()->channelNamesPlug()->getValue();
		std::vector<std::string> maskChannels = channelNamesData->readable();
		channelsPlug()->maskChannels( maskChannels );
		const int nChannels = maskChannels.size();
		
		// Get the image channel data.
		IECore::ImagePrimitivePtr imagePtr( inPlug()->image() );
		
		// Get the image's display window.
		const Imath::Box2i displayWindow( imagePtr->getDisplayWindow() );
		const int displayWindowWidth = displayWindow.size().x+1;
		const int displayWindowHeight = displayWindow.size().y+1;

		// Get the image's data window and if it then set a flag.
		bool imageIsBlack = false;
		Imath::Box2i dataWindow( imagePtr->getDataWindow() );
		if ( inPlug()->dataWindowPlug()->getValue().isEmpty() )
		{
			dataWindow = displayWindow;
			imageIsBlack = true;
		}

		int dataWindowWidth = dataWindow.size().x+1;
		int dataWindowHeight = dataWindow.size().y+1;
	
		// Create the image header. 
		ImageSpec spec( dataWindowWidth, dataWindowHeight, nChannels, TypeDesc::FLOAT );

		// Add the channel names to the header whilst getting pointers to the channel data. 
		std::vector<const float*> channelPtrs;
		spec.channelnames.clear();
		for ( std::vector<std::string>::iterator channelIt( maskChannels.begin() ); channelIt != maskChannels.end(); channelIt++ )
		{
			spec.channelnames.push_back( *channelIt );
			IECore::FloatVectorDataPtr dataPtr = imagePtr->getChannel<float>( *channelIt );
			channelPtrs.push_back( &(dataPtr->readable()[0]) );

			// OIIO has a special attribute for the Alpha and Z channels. If we find some, we should tag them...
			if ( *channelIt == "A" )
			{
				spec.alpha_channel = channelIt-maskChannels.begin();
			} else if ( *channelIt == "Z" )
			{
				spec.z_channel = channelIt-maskChannels.begin();
			}
		}
		
		// Specify the display window.
		spec.full_x = displayWindow.min.x;
		spec.full_y = displayWindow.min.y;
		spec.full_width = displayWindowWidth;
		spec.full_height = displayWindowHeight;
		spec.x = dataWindow.min.x;
		spec.y = dataWindow.min.y;
	
		if ( !out->open( fileName, spec ) )
		{
			throw IECore::Exception( boost::str( boost::format( "Could not open \"%s\", error = %s" ) % fileName % out->geterror() ) );
		}

		// Only allow tiled output if our file format supports it.	
		int writeMode = writeModePlug()->getValue() & out->supports( "tile" );
	
		if ( writeMode == Scanline )
		{
			// Create a buffer for the scanline.
			float scanline[ nChannels*dataWindowWidth ];
			
			if ( imageIsBlack )
			{
				memset( scanline, 0, sizeof(float) * nChannels*dataWindowWidth );

				for ( int y = spec.y; y < spec.y + dataWindowHeight; ++y )
				{
					if ( !out->write_scanline( y, 0, TypeDesc::FLOAT, &scanline[0] ) )
					{
						throw IECore::Exception( boost::str( boost::format( "Could not write scanline to \"%s\", error = %s" ) % fileName % out->geterror() ) );
					}
				}
			}
			else
			{
				// Interleave the channel data and write it by scanline to the file.	
				for ( int y = spec.y; y < spec.y + dataWindowHeight; ++y )
				{
					for ( std::vector<const float *>::iterator channelDataIt( channelPtrs.begin() ); channelDataIt != channelPtrs.end(); channelDataIt++ )
					{
						float *outPtr = &scanline[0] + (channelDataIt - channelPtrs.begin()); // The pointer that we are writing to.
						// The row that we are reading from is flipped (in the Y) as we use a different image space internally to OpenEXR and OpenImageIO.
						const float *inRowPtr = (*channelDataIt) + ( y - spec.y ) * dataWindowWidth;
						const int inc = channelPtrs.size();
						for ( int x = 0; x < dataWindowWidth; ++x, outPtr += inc )
						{
							*outPtr = *inRowPtr++;
						}
					}

					if ( !out->write_scanline( y, 0, TypeDesc::FLOAT, &scanline[0] ) )
					{
						throw IECore::Exception( boost::str( boost::format( "Could not write scanline to \"%s\", error = %s" ) % fileName % out->geterror() ) );
					}
				}
			}
		}
		// Tiled output
		else
		{
			// Create a buffer for the tile.
			const int tileSize = ImagePlug::tileSize();
			float tile[ nChannels*tileSize*tileSize ];

			if ( imageIsBlack )
			{
				memset( tile, 0,  sizeof(float) * nChannels*tileSize*tileSize );
				for ( int tileY = 0; tileY < dataWindowHeight; tileY += tileSize )
				{
					for ( int tileX = 0; tileX < dataWindowWidth; tileX += tileSize )
					{
						if ( !out->write_tile( tileX+dataWindow.min.x, tileY+spec.y, 0, TypeDesc::FLOAT, &tile[0] ) )
						{
							throw IECore::Exception( boost::str( boost::format( "Could not write tile to \"%s\", error = %s" ) % fileName % out->geterror() ) );
						}
					}
				}
			}
			else
			{
				// Interleave the channel data and write it to the file tile-by-tile.
				for ( int tileY = 0; tileY < dataWindowHeight; tileY += tileSize )
				{
					for ( int tileX = 0; tileX < dataWindowWidth; tileX += tileSize )
					{
						float *outPtr = &tile[0];	

						const int r = std::min( tileSize+tileX, dataWindowWidth );
						const int t = std::min( tileSize+tileY, dataWindowHeight );

						for ( int y = 0; y < t; ++y )
						{
							for ( std::vector<const float *>::iterator channelDataIt( channelPtrs.begin() ); channelDataIt != channelPtrs.end(); channelDataIt++ )
							{
								const int inc = channelPtrs.size();
								const float *inRowPtr = (*channelDataIt) + ( tileY + t - y - 1 ) * dataWindowWidth;
								for ( int x = 0; x < r; ++x, outPtr += inc )
								{
									*outPtr = *inRowPtr+(tileX+x);
								}
							}
						}

						if ( !out->write_tile( tileX+dataWindow.min.x, tileY+spec.y, 0, TypeDesc::FLOAT, &tile[0] ) )
						{
							throw IECore::Exception( boost::str( boost::format( "Could not write tile to \"%s\", error = %s" ) % fileName % out->geterror() ) );
						}
					}
				}
			}

		}

		out->close();
	}
}
Example #20
0
};

struct SWRContext
{
    Display *pDisplay;
    XVisualInfo *pVisInfo;
    GLXContext shareList;
    int direct;
    GLXDrawable drawable;
    bool initialized;
};

typedef std::map<OGL::State *, SWRContext> Contexts;

static Contexts contexts;
static Contexts::iterator currentContext = contexts.end();
static Visual gXVisual =
    {
      NULL,       // ext_data
      0xFF,       // visualid
      TrueColor,  // c_class
      0x00FF0000, // red mask
      0x0000FF00, // green mask
      0x000000FF, // blue mask
      8,          // bits_per_rgb,
      256,        // colormap
    };

static XVisualInfo gXVisInfo =
    {
      &gXVisual,  // visual
Example #21
0
Bool glXMakeContextCurrent(Display *pDisplay, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
{
    // unbind current context if NULL ctx passed in
    if (ctx == NULL)
    {
        currentContext = contexts.end();
        return 1;
    }

    auto *pState = reinterpret_cast<OGL::State *>(ctx);
    if (contexts.find(pState) == currentContext)
    {
        return 1;
    }

    auto &xCtxt = contexts[pState];
    xCtxt.drawable = draw;

    SetOGL(pState);

    GLuint width, height;
    XWindowAttributes xWindowAttributes = { 0 };
    SWRPBuffer *buf;
    bool isDisplay;
    switch (gDrawables[draw])
    {
    case X:
        XGetWindowAttributes(pDisplay, draw, &xWindowAttributes);
        width = xWindowAttributes.width;
        height = xWindowAttributes.height;
        isDisplay = true;
        break;
    case PBUFFER:
        buf = (SWRPBuffer *)draw;
        width = buf->width;
        height = buf->height;
        isDisplay = false;
        break;
    default:
        assert(0 && "Invalid buffer type");
        return 0;
    }

    // bind render target set to SWR pipeline
    FrameBuffer *fb;
    if (gDrawableBuffers.find(draw) == gDrawableBuffers.end())
    {
        // we haven't seen this drawable yet, create a new frame buffer
        fb = new FrameBuffer();
        fb->Initialize(width, height, draw, xCtxt.pDisplay, xCtxt.pVisInfo, isDisplay);
        gDrawableBuffers[draw] = fb;
    }
    else
    {
        fb = gDrawableBuffers[draw];
    }

    OGL::GetDDProcTable().pfnSetRenderTarget(OGL::GetDDHandle(), fb->GetBackBuffer(), fb->GetDepthBuffer());

    // according to spec, only set current viewport to draw buffer dimensions if the context hasn't
    // been initialized
    if (!xCtxt.initialized)
    {
        pState->mViewport.x = 0;
        pState->mViewport.y = 0;
        pState->mViewport.width = width;
        pState->mViewport.height = height;
        pState->mScissor.x = 0;
        pState->mScissor.y = 0;
        pState->mScissor.width = width;
        pState->mScissor.height = height;
        xCtxt.initialized = true;
    }

    currentContext = contexts.find(pState);

    return 1;
}
Example #22
0
};

typedef std::unordered_map<int, SWRContext> Contexts;

Contexts DummyContexts()
{
    Contexts ctxts;
    SWRContext c = { 0 };

    ctxts.insert(std::make_pair(0, (SWRContext)c));
    return ctxts;
}

static Contexts gContexts = DummyContexts();
static bool gCurrentContextSet = false;
static Contexts::iterator gCurrentContext = gContexts.end();

// We support ONE format.

static const PIXELFORMATDESCRIPTOR gPxFmts[] =
{
    {   // This is a dummy descriptor.
    },
    {
        sizeof(PIXELFORMATDESCRIPTOR), // nSize
        0xBAAB,                        // nVersion
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED | PFD_DOUBLEBUFFER | PFD_SWAP_EXCHANGE | PFD_SUPPORT_COMPOSITION,
        PFD_TYPE_RGBA, // iPixelType
        32,            // cColorBits
        8,             // cRedBits
        16,            // cRedShift
void CompositeViewer::eventTraversal()
{
    if (_done) return;

    if (_views.empty()) return;

    double cutOffTime = _frameStamp->getReferenceTime();

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

    // need to copy events from the GraphicsWindow's into local EventQueue for each view;
    typedef std::map<osgViewer::View*, osgGA::EventQueue::Events> ViewEventsMap;
    ViewEventsMap viewEventsMap;

    Contexts contexts;
    getContexts(contexts);

    // set done if there are no windows
    checkWindowStatus(contexts);
    if (_done) return;

    osgGA::EventQueue::Events all_events;

    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, cutOffTime);

            for(osgGA::EventQueue::Events::iterator itr = gw_events.begin();
                    itr != gw_events.end();
                    ++itr)
            {
                (*itr)->setGraphicsContext(gw);
            }

            all_events.insert(all_events.end(), gw_events.begin(), gw_events.end());
        }
    }

    // sort all the events in time order so we can make sure we pass them all on in the correct order.
    all_events.sort(SortEvents());

    // pass on pointer data onto non mouse events to keep the position data usable by all recipients of all events.
    for(osgGA::EventQueue::Events::iterator itr = all_events.begin();
            itr != all_events.end();
            ++itr)
    {
        osgGA::GUIEventAdapter* event = itr->get();

        switch(event->getEventType())
        {
        case(osgGA::GUIEventAdapter::PUSH):
        case(osgGA::GUIEventAdapter::RELEASE):
        case(osgGA::GUIEventAdapter::DOUBLECLICK):
        case(osgGA::GUIEventAdapter::MOVE):
        case(osgGA::GUIEventAdapter::DRAG):
        {
            if ((event->getEventType()!=osgGA::GUIEventAdapter::DRAG && event->getEventType()!=osgGA::GUIEventAdapter::RELEASE) ||
                    !_previousEvent ||
                    _previousEvent->getGraphicsContext()!=event->getGraphicsContext() ||
                    _previousEvent->getNumPointerData()<2)
            {
                generatePointerData(*event);
            }
            else
            {
                reprojectPointerData(*_previousEvent, *event);
            }

#if 0
            // assign topmost PointeData settings as the events X,Y and InputRange
            osgGA::PointerData* pd = event->getPointerData(event->getNumPointerData()-1);
            event->setX(pd->x);
            event->setY(pd->y);
            event->setInputRange(pd->xMin, pd->yMin, pd->xMax, pd->yMax);
            event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
#else
            if (event->getMouseYOrientation()!=osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS)
            {
                event->setY((event->getYmax()-event->getY())+event->getYmin());
                event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
            }
#endif

            _previousEvent = event;

            break;
        }
        default:
            if (_previousEvent.valid()) event->copyPointerDataFrom(*_previousEvent);
            break;
        }

        osgGA::PointerData* pd = event->getNumPointerData()>0 ? event->getPointerData(event->getNumPointerData()-1) : 0;
        osg::Camera* camera = pd ? dynamic_cast<osg::Camera*>(pd->object.get()) : 0;
        osgViewer::View* view = camera ? dynamic_cast<osgViewer::View*>(camera->getView()) : 0;

        if (!view)
        {
            if (_viewWithFocus.valid())
            {
                // OSG_NOTICE<<"Falling back to using _viewWithFocus"<<std::endl;
                view = _viewWithFocus.get();
            }
            else if (!_views.empty())
            {
                // OSG_NOTICE<<"Falling back to using first view as one with focus"<<std::endl;
                view = _views[0].get();
            }
        }

        // reassign view with focus
        if (_viewWithFocus != view)  _viewWithFocus = view;

        if (view)
        {
            viewEventsMap[view].push_back( event );

            osgGA::GUIEventAdapter* eventState = view->getEventQueue()->getCurrentEventState();
            eventState->copyPointerDataFrom(*event);
        }

        _previousEvent = event;
    }

    // handle any close windows
    for(osgGA::EventQueue::Events::iterator itr = all_events.begin();
            itr != all_events.end();
            ++itr)
    {
        osgGA::GUIEventAdapter* event = itr->get();
        switch(event->getEventType())
        {
        case(osgGA::GUIEventAdapter::CLOSE_WINDOW):
        {
            bool wasThreading = areThreadsRunning();
            if (wasThreading) stopThreading();

            if (event->getGraphicsContext())
            {
                event->getGraphicsContext()->close();
            }

            if (wasThreading) startThreading();

            break;
        }
        default:
            break;
        }
    }


    for(RefViews::iterator vitr = _views.begin();
            vitr != _views.end();
            ++vitr)
    {
        View* view = vitr->get();

        // get events from user Devices attached to Viewer.
        for(osgViewer::View::Devices::iterator eitr = view->getDevices().begin();
                eitr != view->getDevices().end();
                ++eitr)
        {
            osgGA::Device* es = eitr->get();
            if (es->getCapabilities() & osgGA::Device::RECEIVE_EVENTS)
                es->checkEvents();

            // open question, will we need to reproject mouse coordinates into current view's coordinate frame as is down for GraphicsWindow provided events?
            // for now assume now and just get the events directly without any reprojection.
            es->getEventQueue()->takeEvents(viewEventsMap[view], cutOffTime);
        }

        // generate frame event
        view->getEventQueue()->frame( getFrameStamp()->getReferenceTime() );

        view->getEventQueue()->takeEvents(viewEventsMap[view], cutOffTime);
    }

    if ((_keyEventSetsDone!=0) || _quitEventSetsDone)
    {
        for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
                veitr != viewEventsMap.end();
                ++veitr)
        {
            for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
                    itr != veitr->second.end();
                    ++itr)
            {
                osgGA::GUIEventAdapter* event = itr->get();
                switch(event->getEventType())
                {
                case(osgGA::GUIEventAdapter::KEYUP):
                    if (_keyEventSetsDone && event->getKey()==_keyEventSetsDone) _done = true;
                    break;

                case(osgGA::GUIEventAdapter::QUIT_APPLICATION):
                    if (_quitEventSetsDone) _done = true;
                    break;

                default:
                    break;
                }
            }
        }
    }

    if (_done) return;

    if (_eventVisitor.valid())
    {
        _eventVisitor->setFrameStamp(getFrameStamp());
        _eventVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber());

        for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
                veitr != viewEventsMap.end();
                ++veitr)
        {
            View* view = veitr->first;

            if (view && view->getSceneData())
            {
                _eventVisitor->setActionAdapter(view);

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

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

                    view->getSceneData()->accept(*_eventVisitor);

                    // Do EventTraversal for slaves with their own subgraph
                    for(unsigned int i=0; i<view->getNumSlaves(); ++i)
                    {
                        osg::View::Slave& slave = view->getSlave(i);
                        osg::Camera* camera = slave._camera.get();
                        if(camera && !slave._useMastersSceneData)
                        {
                            camera->accept(*_eventVisitor);
                        }
                    }

                    // call any camera event 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 (view->getCamera() && view->getCamera()->getEventCallback()) view->getCamera()->accept(*_eventVisitor);

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

                    _eventVisitor->setTraversalMode(tm);

                }
            }
        }

    }

    for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
            veitr != viewEventsMap.end();
            ++veitr)
    {
        View* view = veitr->first;

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

            for(View::EventHandlers::iterator hitr = view->getEventHandlers().begin();
                    hitr != view->getEventHandlers().end();
                    ++hitr)
            {
                (*hitr)->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view, 0, _eventVisitor.get());
            }
        }
    }

    for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
            veitr != viewEventsMap.end();
            ++veitr)
    {
        View* view = veitr->first;

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

            if (view->getCameraManipulator())
            {
                view->getCameraManipulator()->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view);
            }
        }
    }

    if (getViewerStats() && getViewerStats()->collectStats("event"))
    {
        double endEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());

        // update current frames stats
        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal begin time", beginEventTraversal);
        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal end time", endEventTraversal);
        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal time taken", endEventTraversal-beginEventTraversal);
    }
}
void CompositeViewer::realize()
{
    //OSG_INFO<<"CompositeViewer::realize()"<<std::endl;

    setCameraWithFocus(0);

    if (_views.empty())
    {
        OSG_NOTICE<<"CompositeViewer::realize() - No views to realize."<<std::endl;
        _done = true;
        return;
    }

    Contexts contexts;
    getContexts(contexts);

    if (contexts.empty())
    {
        OSG_INFO<<"CompositeViewer::realize() - No valid contexts found, setting up view across all screens."<<std::endl;

        // no windows are already set up so set up a default view
        _views[0]->setUpViewAcrossAllScreens();

        getContexts(contexts);
    }

    if (contexts.empty())
    {
        OSG_NOTICE<<"CompositeViewer::realize() - failed to set up any windows"<<std::endl;
        _done = true;
        return;
    }

    unsigned int maxTexturePoolSize = osg::DisplaySettings::instance()->getMaxTexturePoolSize();
    unsigned int maxBufferObjectPoolSize = osg::DisplaySettings::instance()->getMaxBufferObjectPoolSize();

    for(Contexts::iterator citr = contexts.begin();
            citr != contexts.end();
            ++citr)
    {
        osg::GraphicsContext* gc = *citr;

        // set the pool sizes, 0 the default will result in no GL object pools.
        gc->getState()->setMaxTexturePoolSize(maxTexturePoolSize);
        gc->getState()->setMaxBufferObjectPoolSize(maxBufferObjectPoolSize);

        gc->realize();

        if (_realizeOperation.valid() && gc->valid())
        {
            gc->makeCurrent();

            (*_realizeOperation)(gc);

            gc->releaseContext();
        }
    }

    // attach contexts to _incrementalCompileOperation if attached.
    if (_incrementalCompileOperation) _incrementalCompileOperation->assignContexts(contexts);


    bool grabFocus = true;
    if (grabFocus)
    {
        for(Contexts::iterator citr = contexts.begin();
                citr != contexts.end();
                ++citr)
        {
            osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
            if (gw)
            {
                gw->grabFocusIfPointerInWindow();
            }
        }
    }


    startThreading();

    // initialize the global timer to be relative to the current time.
    osg::Timer::instance()->setStartTick();

    // pass on the start tick to all the associated eventqueues
    setStartTick(osg::Timer::instance()->getStartTick());

    if (osg::DisplaySettings::instance()->getCompileContextsHint())
    {
        int numProcessors = OpenThreads::GetNumberOfProcessors();
        int processNum = 0;

        for(unsigned int i=0; i<= osg::GraphicsContext::getMaxContextID(); ++i)
        {
            osg::GraphicsContext* gc = osg::GraphicsContext::getOrCreateCompileContext(i);

            if (gc)
            {
                gc->createGraphicsThread();
                gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors);
                gc->getGraphicsThread()->startThread();

                ++processNum;
            }
        }
    }

}
Example #25
0
void ViewerBase::stopThreading()
{
    if (!_threadsRunning) return;

    OSG_INFO<<"ViewerBase::stopThreading() - stopping threading"<<std::endl;

    Contexts contexts;
    getContexts(contexts);

    Cameras cameras;
    getCameras(cameras);

    Contexts::iterator gcitr;
    Cameras::iterator citr;

    for(Cameras::iterator camItr = cameras.begin();
        camItr != cameras.end();
        ++camItr)
    {
        osg::Camera* camera = *camItr;
        Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer());
        if (renderer) renderer->release();
    }

    // delete all the graphics threads.
    for(gcitr = contexts.begin();
        gcitr != contexts.end();
        ++gcitr)
    {
        (*gcitr)->setGraphicsThread(0);
    }

    // delete all the camera threads.
    for(citr = cameras.begin();
        citr != cameras.end();
        ++citr)
    {
        (*citr)->setCameraThread(0);
    }

    for(Cameras::iterator camItr = cameras.begin();
        camItr != cameras.end();
        ++camItr)
    {
        osg::Camera* camera = *camItr;
        Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer());
        if (renderer)
        {
            renderer->setGraphicsThreadDoesCull( true );
            renderer->setDone(false);
        }
    }


    _threadsRunning = false;
    _startRenderingBarrier = 0;
    _endRenderingDispatchBarrier = 0;
    _endDynamicDrawBlock = 0;

    OSG_INFO<<"Viewer::stopThreading() - stopped threading."<<std::endl;
}
Example #26
0
void ViewerBase::startThreading()
{
    if (_threadsRunning) return;

    OSG_INFO<<"Viewer::startThreading() - starting threading"<<std::endl;

    // release any context held by the main thread.
    releaseContext();

    _threadingModel = _threadingModel==AutomaticSelection ? suggestBestThreadingModel() : _threadingModel;

    Contexts contexts;
    getContexts(contexts);

    OSG_INFO<<"Viewer::startThreading() - contexts.size()="<<contexts.size()<<std::endl;

    Cameras cameras;
    getCameras(cameras);

    unsigned int numThreadsOnStartBarrier = 0;
    unsigned int numThreadsOnEndBarrier = 0;
    switch(_threadingModel)
    {
        case(SingleThreaded):
            numThreadsOnStartBarrier = 1;
            numThreadsOnEndBarrier = 1;
            return;
        case(CullDrawThreadPerContext):
            numThreadsOnStartBarrier = contexts.size()+1;
            numThreadsOnEndBarrier = contexts.size()+1;
            break;
        case(DrawThreadPerContext):
            numThreadsOnStartBarrier = 1;
            numThreadsOnEndBarrier = 1;
            break;
        case(CullThreadPerCameraDrawThreadPerContext):
            numThreadsOnStartBarrier = cameras.size()+1;
            numThreadsOnEndBarrier = 1;
            break;
        default:
            OSG_NOTICE<<"Error: Threading model not selected"<<std::endl;
            return;
    }

    // using multi-threading so make sure that new objects are allocated with thread safe ref/unref
    osg::Referenced::setThreadSafeReferenceCounting(true);

    Scenes scenes;
    getScenes(scenes);
    for(Scenes::iterator scitr = scenes.begin();
        scitr != scenes.end();
        ++scitr)
    {
        if ((*scitr)->getSceneData())
        {
            OSG_INFO<<"Making scene thread safe"<<std::endl;

            // make sure that existing scene graph objects are allocated with thread safe ref/unref
            (*scitr)->getSceneData()->setThreadSafeRefUnref(true);

            // update the scene graph so that it has enough GL object buffer memory for the graphics contexts that will be using it.
            (*scitr)->getSceneData()->resizeGLObjectBuffers(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts());
        }
    }

    int numProcessors = OpenThreads::GetNumberOfProcessors();
    bool affinity = numProcessors>1;

    Contexts::iterator citr;

    unsigned int numViewerDoubleBufferedRenderingOperation = 0;

    bool graphicsThreadsDoesCull = _threadingModel == CullDrawThreadPerContext || _threadingModel==SingleThreaded;

    for(Cameras::iterator camItr = cameras.begin();
        camItr != cameras.end();
        ++camItr)
    {
        osg::Camera* camera = *camItr;
        Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer());
        if (renderer)
        {
            renderer->setGraphicsThreadDoesCull(graphicsThreadsDoesCull);
            renderer->setDone(false);
            renderer->reset();
            ++numViewerDoubleBufferedRenderingOperation;
        }
    }

    if (_threadingModel==CullDrawThreadPerContext)
    {
        _startRenderingBarrier = 0;
        _endRenderingDispatchBarrier = 0;
        _endDynamicDrawBlock = 0;
    }
    else if (_threadingModel==DrawThreadPerContext ||
             _threadingModel==CullThreadPerCameraDrawThreadPerContext)
    {
        _startRenderingBarrier = 0;
        _endRenderingDispatchBarrier = 0;
        _endDynamicDrawBlock = new osg::EndOfDynamicDrawBlock(numViewerDoubleBufferedRenderingOperation);

#ifndef OSGUTIL_RENDERBACKEND_USE_REF_PTR
        if (!osg::Referenced::getDeleteHandler()) osg::Referenced::setDeleteHandler(new osg::DeleteHandler(2));
        else osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(2);
#endif
    }

    if (numThreadsOnStartBarrier>1)
    {
        _startRenderingBarrier = new osg::BarrierOperation(numThreadsOnStartBarrier, osg::BarrierOperation::NO_OPERATION);
    }

    if (numThreadsOnEndBarrier>1)
    {
        _endRenderingDispatchBarrier = new osg::BarrierOperation(numThreadsOnEndBarrier, _endBarrierOperation);
    }


    osg::ref_ptr<osg::BarrierOperation> swapReadyBarrier = contexts.empty() ? 0 : new osg::BarrierOperation(contexts.size(), osg::BarrierOperation::NO_OPERATION);

    osg::ref_ptr<osg::SwapBuffersOperation> swapOp = new osg::SwapBuffersOperation();

    typedef std::map<OpenThreads::Thread*, int> ThreadAffinityMap;
    ThreadAffinityMap threadAffinityMap;

    unsigned int processNum = 1;
    for(citr = contexts.begin();
        citr != contexts.end();
        ++citr, ++processNum)
    {
        osg::GraphicsContext* gc = (*citr);

        if (!gc->isRealized())
        {
            OSG_INFO<<"ViewerBase::startThreading() : Realizng window "<<gc<<std::endl;
            gc->realize();
        }

        gc->getState()->setDynamicObjectRenderingCompletedCallback(_endDynamicDrawBlock.get());

        // create the a graphics thread for this context
        gc->createGraphicsThread();

        if (affinity) gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors);
        threadAffinityMap[gc->getGraphicsThread()] = processNum % numProcessors;

        // add the startRenderingBarrier
        if (_threadingModel==CullDrawThreadPerContext && _startRenderingBarrier.valid()) gc->getGraphicsThread()->add(_startRenderingBarrier.get());

        // add the rendering operation itself.
        gc->getGraphicsThread()->add(new osg::RunOperations());

        if (_threadingModel==CullDrawThreadPerContext && _endBarrierPosition==BeforeSwapBuffers && _endRenderingDispatchBarrier.valid())
        {
            // add the endRenderingDispatchBarrier
            gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get());
        }

        if (swapReadyBarrier.valid()) gc->getGraphicsThread()->add(swapReadyBarrier.get());

        // add the swap buffers
        gc->getGraphicsThread()->add(swapOp.get());

        if (_threadingModel==CullDrawThreadPerContext && _endBarrierPosition==AfterSwapBuffers && _endRenderingDispatchBarrier.valid())
        {
            // add the endRenderingDispatchBarrier
            gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get());
        }

    }

    if (_threadingModel==CullThreadPerCameraDrawThreadPerContext && numThreadsOnStartBarrier>1)
    {
        Cameras::iterator camItr;

        for(camItr = cameras.begin();
            camItr != cameras.end();
            ++camItr, ++processNum)
        {
            osg::Camera* camera = *camItr;
            camera->createCameraThread();

            if (affinity) camera->getCameraThread()->setProcessorAffinity(processNum % numProcessors);
            threadAffinityMap[camera->getCameraThread()] = processNum % numProcessors;

            osg::GraphicsContext* gc = camera->getGraphicsContext();

            // add the startRenderingBarrier
            if (_startRenderingBarrier.valid()) camera->getCameraThread()->add(_startRenderingBarrier.get());

            Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer());
            renderer->setGraphicsThreadDoesCull(false);
            camera->getCameraThread()->add(renderer);

            if (_endRenderingDispatchBarrier.valid())
            {
                // add the endRenderingDispatchBarrier
                gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get());
            }

        }

        for(camItr = cameras.begin();
            camItr != cameras.end();
            ++camItr)
        {
            osg::Camera* camera = *camItr;
            if (camera->getCameraThread() && !camera->getCameraThread()->isRunning())
            {
                OSG_INFO<<"  camera->getCameraThread()-> "<<camera->getCameraThread()<<std::endl;
                camera->getCameraThread()->startThread();
            }
        }
    }

#if 0
    if (affinity)
    {
        OpenThreads::SetProcessorAffinityOfCurrentThread(0);
        if (_scene.valid() && _scene->getDatabasePager())
        {
#if 0
            _scene->getDatabasePager()->setProcessorAffinity(1);
#else
            _scene->getDatabasePager()->setProcessorAffinity(0);
#endif
        }
    }
#endif

#if 0
    if (affinity)
    {
        for(ThreadAffinityMap::iterator titr = threadAffinityMap.begin();
            titr != threadAffinityMap.end();
            ++titr)
        {
            titr->first->setProcessorAffinity(titr->second);
        }
    }
#endif


    for(citr = contexts.begin();
        citr != contexts.end();
        ++citr)
    {
        osg::GraphicsContext* gc = (*citr);
        if (gc->getGraphicsThread() && !gc->getGraphicsThread()->isRunning())
        {
            OSG_INFO<<"  gc->getGraphicsThread()->startThread() "<<gc->getGraphicsThread()<<std::endl;
            gc->getGraphicsThread()->startThread();
            // OpenThreads::Thread::YieldCurrentThread();
        }
    }

    _threadsRunning = true;

    OSG_INFO<<"Set up threading"<<std::endl;
}
Example #27
0
void ViewerBase::renderingTraversals()
{
    bool _outputMasterCameraLocation = false;
    if (_outputMasterCameraLocation)
    {
        Views views;
        getViews(views);

        for(Views::iterator itr = views.begin();
            itr != views.end();
            ++itr)
        {
            osgViewer::View* view = *itr;
            if (view)
            {
                const osg::Matrixd& m = view->getCamera()->getInverseViewMatrix();
                OSG_NOTICE<<"View "<<view<<", Master Camera position("<<m.getTrans()<<"), rotation("<<m.getRotate()<<")"<<std::endl;
            }
        }
    }

    Contexts contexts;
    getContexts(contexts);

    // check to see if windows are still valid
    checkWindowStatus(contexts);
    if (_done) return;

    double beginRenderingTraversals = elapsedTime();

    osg::FrameStamp* frameStamp = getViewerFrameStamp();

    if (getViewerStats() && getViewerStats()->collectStats("scene"))
    {
        unsigned int frameNumber = frameStamp ? frameStamp->getFrameNumber() : 0;

        Views views;
        getViews(views);
        for(Views::iterator vitr = views.begin();
            vitr != views.end();
            ++vitr)
        {
            View* view = *vitr;
            osg::Stats* stats = view->getStats();
            osg::Node* sceneRoot = view->getSceneData();
            if (sceneRoot && stats)
            {
                osgUtil::StatsVisitor statsVisitor;
                sceneRoot->accept(statsVisitor);
                statsVisitor.totalUpStats();

                unsigned int unique_primitives = 0;
                osgUtil::Statistics::PrimitiveCountMap::iterator pcmitr;
                for(pcmitr = statsVisitor._uniqueStats.GetPrimitivesBegin();
                    pcmitr != statsVisitor._uniqueStats.GetPrimitivesEnd();
                    ++pcmitr)
                {
                    unique_primitives += pcmitr->second;
                }

                stats->setAttribute(frameNumber, "Number of unique StateSet", static_cast<double>(statsVisitor._statesetSet.size()));
                stats->setAttribute(frameNumber, "Number of unique Group", static_cast<double>(statsVisitor._groupSet.size()));
                stats->setAttribute(frameNumber, "Number of unique Transform", static_cast<double>(statsVisitor._transformSet.size()));
                stats->setAttribute(frameNumber, "Number of unique LOD", static_cast<double>(statsVisitor._lodSet.size()));
                stats->setAttribute(frameNumber, "Number of unique Switch", static_cast<double>(statsVisitor._switchSet.size()));
                stats->setAttribute(frameNumber, "Number of unique Geode", static_cast<double>(statsVisitor._geodeSet.size()));
                stats->setAttribute(frameNumber, "Number of unique Drawable", static_cast<double>(statsVisitor._drawableSet.size()));
                stats->setAttribute(frameNumber, "Number of unique Geometry", static_cast<double>(statsVisitor._geometrySet.size()));
                stats->setAttribute(frameNumber, "Number of unique Vertices", static_cast<double>(statsVisitor._uniqueStats._vertexCount));
                stats->setAttribute(frameNumber, "Number of unique Primitives", static_cast<double>(unique_primitives));

                unsigned int instanced_primitives = 0;
                for(pcmitr = statsVisitor._instancedStats.GetPrimitivesBegin();
                    pcmitr != statsVisitor._instancedStats.GetPrimitivesEnd();
                    ++pcmitr)
                {
                    instanced_primitives += pcmitr->second;
                }

                stats->setAttribute(frameNumber, "Number of instanced Stateset", static_cast<double>(statsVisitor._numInstancedStateSet));
                stats->setAttribute(frameNumber, "Number of instanced Group", static_cast<double>(statsVisitor._numInstancedGroup));
                stats->setAttribute(frameNumber, "Number of instanced Transform", static_cast<double>(statsVisitor._numInstancedTransform));
                stats->setAttribute(frameNumber, "Number of instanced LOD", static_cast<double>(statsVisitor._numInstancedLOD));
                stats->setAttribute(frameNumber, "Number of instanced Switch", static_cast<double>(statsVisitor._numInstancedSwitch));
                stats->setAttribute(frameNumber, "Number of instanced Geode", static_cast<double>(statsVisitor._numInstancedGeode));
                stats->setAttribute(frameNumber, "Number of instanced Drawable", static_cast<double>(statsVisitor._numInstancedDrawable));
                stats->setAttribute(frameNumber, "Number of instanced Geometry", static_cast<double>(statsVisitor._numInstancedGeometry));
                stats->setAttribute(frameNumber, "Number of instanced Vertices", static_cast<double>(statsVisitor._instancedStats._vertexCount));
                stats->setAttribute(frameNumber, "Number of instanced Primitives", static_cast<double>(instanced_primitives));
           }
        }
    }

    Scenes scenes;
    getScenes(scenes);

    for(Scenes::iterator sitr = scenes.begin();
        sitr != scenes.end();
        ++sitr)
    {
        Scene* scene = *sitr;
        osgDB::DatabasePager* dp = scene ? scene->getDatabasePager() : 0;
        if (dp) dp->signalBeginFrame(frameStamp);

        osgDB::ImagePager* ip = scene ? scene->getImagePager() : 0;
        if (ip) ip->signalBeginFrame(frameStamp);

        if (scene->getSceneData())
        {
            // fire off a build of the bounding volumes while we
            // are still running single threaded.
            scene->getSceneData()->getBound();
        }
    }

    // OSG_NOTICE<<std::endl<<"Start frame"<<std::endl;


    Cameras cameras;
    getCameras(cameras);

    Contexts::iterator itr;

    bool doneMakeCurrentInThisThread = false;

    if (_endDynamicDrawBlock.valid())
    {
        _endDynamicDrawBlock->reset();
    }

    // dispatch the rendering threads
    if (_startRenderingBarrier.valid()) _startRenderingBarrier->block();

    // reset any double buffer graphics objects
    for(Cameras::iterator camItr = cameras.begin();
        camItr != cameras.end();
        ++camItr)
    {
        osg::Camera* camera = *camItr;
        Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer());
        if (renderer)
        {
            if (!renderer->getGraphicsThreadDoesCull() && !(camera->getCameraThread()))
            {
                renderer->cull();
            }
        }
    }

    for(itr = contexts.begin();
        itr != contexts.end() && !_done;
        ++itr)
    {
        if (!((*itr)->getGraphicsThread()) && (*itr)->valid())
        {
            doneMakeCurrentInThisThread = true;
            makeCurrent(*itr);
            (*itr)->runOperations();
        }
    }

    // OSG_NOTICE<<"Joing _endRenderingDispatchBarrier block "<<_endRenderingDispatchBarrier.get()<<std::endl;

    // wait till the rendering dispatch is done.
    if (_endRenderingDispatchBarrier.valid()) _endRenderingDispatchBarrier->block();

    for(itr = contexts.begin();
        itr != contexts.end() && !_done;
        ++itr)
    {
        if (!((*itr)->getGraphicsThread()) && (*itr)->valid())
        {
            doneMakeCurrentInThisThread = true;
            makeCurrent(*itr);
            (*itr)->swapBuffers();
        }
    }

    for(Scenes::iterator sitr = scenes.begin();
        sitr != scenes.end();
        ++sitr)
    {
        Scene* scene = *sitr;
        osgDB::DatabasePager* dp = scene ? scene->getDatabasePager() : 0;
        if (dp) dp->signalEndFrame();

        osgDB::ImagePager* ip = scene ? scene->getImagePager() : 0;
        if (ip) ip->signalEndFrame();
    }

    // wait till the dynamic draw is complete.
    if (_endDynamicDrawBlock.valid())
    {
        // osg::Timer_t startTick = osg::Timer::instance()->tick();
        _endDynamicDrawBlock->block();
        // OSG_NOTICE<<"Time waiting "<<osg::Timer::instance()->delta_m(startTick, osg::Timer::instance()->tick())<<std::endl;;
    }

    if (_releaseContextAtEndOfFrameHint && doneMakeCurrentInThisThread)
    {
        //OSG_NOTICE<<"Doing release context"<<std::endl;
        releaseContext();
    }

    if (getViewerStats() && getViewerStats()->collectStats("update"))
    {
        double endRenderingTraversals = elapsedTime();

        // update current frames stats
        getViewerStats()->setAttribute(frameStamp->getFrameNumber(), "Rendering traversals begin time ", beginRenderingTraversals);
        getViewerStats()->setAttribute(frameStamp->getFrameNumber(), "Rendering traversals end time ", endRenderingTraversals);
        getViewerStats()->setAttribute(frameStamp->getFrameNumber(), "Rendering traversals time taken", endRenderingTraversals-beginRenderingTraversals);
    }

    _requestRedraw = false;
}
Example #28
0
void CompositeViewer::eventTraversal()
{
    if (_done) return;

    if (_views.empty()) return;

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

    // OSG_NOTICE<<"CompositeViewer::frameEventTraversal()."<<std::endl;

    // need to copy events from the GraphicsWindow's into local EventQueue;

    typedef std::map<osgViewer::View*, osgGA::EventQueue::Events> ViewEventsMap;
    ViewEventsMap viewEventsMap;

    Contexts contexts;
    getContexts(contexts);

    Scenes scenes;
    getScenes(scenes);

    osgViewer::View* masterView = getViewWithFocus() ? getViewWithFocus() : _views[0].get();

    osg::Camera* masterCamera = masterView->getCamera();
    osgGA::GUIEventAdapter* eventState = masterView->getEventQueue()->getCurrentEventState();
    osg::Matrix masterCameraVPW = masterCamera->getViewMatrix() * masterCamera->getProjectionMatrix();
    if (masterCamera->getViewport())
    {
        osg::Viewport* viewport = masterCamera->getViewport();
        masterCameraVPW *= viewport->computeWindowMatrix();
    }

    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);

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

                //OSG_NOTICE<<"event->getGraphicsContext()="<<event->getGraphicsContext()<<std::endl;

                bool pointerEvent = false;

                float x = event->getX();
                float y = event->getY();

                bool invert_y = event->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
                if (invert_y && gw->getTraits()) y = gw->getTraits()->height - y;

                switch(event->getEventType())
                {
                    case(osgGA::GUIEventAdapter::RESIZE):
                        setCameraWithFocus(0);
                        break;
                    case(osgGA::GUIEventAdapter::PUSH):
                    case(osgGA::GUIEventAdapter::RELEASE):
                    case(osgGA::GUIEventAdapter::DOUBLECLICK):
                    case(osgGA::GUIEventAdapter::DRAG):
                    case(osgGA::GUIEventAdapter::MOVE):
                    {
                        pointerEvent = true;

                        if (event->getEventType()!=osgGA::GUIEventAdapter::DRAG || !getCameraWithFocus())
                        {
                            osg::GraphicsContext::Cameras& cameras = gw->getCameras();
                            for(osg::GraphicsContext::Cameras::iterator citr = cameras.begin();
                                citr != cameras.end();
                                ++citr)
                            {
                                osg::Camera* camera = *citr;
                                if (camera->getView() &&
                                    camera->getAllowEventFocus() &&
                                    camera->getRenderTargetImplementation()==osg::Camera::FRAME_BUFFER)
                                {
                                    osg::Viewport* viewport = camera ? camera->getViewport() : 0;
                                    if (viewport &&
                                        x >= viewport->x() && y >= viewport->y() &&
                                        x <= (viewport->x()+viewport->width()) && y <= (viewport->y()+viewport->height()) )
                                    {
                                        setCameraWithFocus(camera);

                                        // If this camera is not a slave camera
                                        if (camera->getView()->getCamera() == camera)
                                        {
                                            eventState->setGraphicsContext(gw);
                                            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);
                                        }

                                        if (getViewWithFocus()!=masterView)
                                        {
                                            // need to reset the masterView
                                            masterView = getViewWithFocus();
                                            masterCamera = masterView->getCamera();
                                            eventState = masterView->getEventQueue()->getCurrentEventState();
                                            masterCameraVPW = masterCamera->getViewMatrix() * masterCamera->getProjectionMatrix();

                                            if (masterCamera->getViewport())
                                            {
                                                osg::Viewport* viewport = masterCamera->getViewport();
                                                masterCameraVPW *= viewport->computeWindowMatrix();
                                            }
                                        }

                                        // If this camera is not a slave camera
                                        if (camera->getView()->getCamera() == camera)
                                        {
                                            eventState->setGraphicsContext(gw);
                                            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);
                                        }
                                    }
                                }
                            }
                        }

                        break;
                    }
                    default:
                        break;
                }

                if (pointerEvent)
                {
                    if (getCameraWithFocus())
                    {
                        osg::Viewport* viewport = getCameraWithFocus()->getViewport();
                        osg::Matrix localCameraVPW = getCameraWithFocus()->getViewMatrix() * getCameraWithFocus()->getProjectionMatrix();
                        if (viewport) localCameraVPW *= viewport->computeWindowMatrix();

                        osg::Matrix matrix( osg::Matrix::inverse(localCameraVPW) * masterCameraVPW );

                        osg::Vec3d new_coord = osg::Vec3d(x,y,0.0) * matrix;

                        x = new_coord.x();
                        y = new_coord.y();

                        event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
                        event->setX(x);
                        event->setY(y);
                        event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);

                    }
                    // pass along the new pointer events details to the eventState of the viewer
                    eventState->setX(x);
                    eventState->setY(y);
                    eventState->setButtonMask(event->getButtonMask());
                    eventState->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);

                }
                else
                {
                    event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
                    event->setX(eventState->getX());
                    event->setY(eventState->getY());
                    event->setButtonMask(eventState->getButtonMask());
                    event->setMouseYOrientation(eventState->getMouseYOrientation());
                }
            }

            for(itr = gw_events.begin();
                itr != gw_events.end();
                ++itr)
            {
                osgGA::GUIEventAdapter* event = itr->get();
                switch(event->getEventType())
                {
                    case(osgGA::GUIEventAdapter::CLOSE_WINDOW):
                    {
                        bool wasThreading = areThreadsRunning();
                        if (wasThreading) stopThreading();

                        gw->close();

                        if (wasThreading) startThreading();

                        break;
                    }
                    default:
                        break;
                }
            }

            viewEventsMap[masterView].insert( viewEventsMap[masterView].end(), gw_events.begin(), gw_events.end() );

        }
    }


    // OSG_NOTICE<<"mouseEventState Xmin = "<<eventState->getXmin()<<" Ymin="<<eventState->getYmin()<<" xMax="<<eventState->getXmax()<<" Ymax="<<eventState->getYmax()<<std::endl;


    for(RefViews::iterator vitr = _views.begin();
        vitr != _views.end();
        ++vitr)
    {
        View* view = vitr->get();
        view->getEventQueue()->frame( getFrameStamp()->getReferenceTime() );
        view->getEventQueue()->takeEvents(viewEventsMap[view]);
    }


    // OSG_NOTICE<<"Events "<<events.size()<<std::endl;

    if ((_keyEventSetsDone!=0) || _quitEventSetsDone)
    {
        for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
            veitr != viewEventsMap.end();
            ++veitr)
        {
            for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
                itr != veitr->second.end();
                ++itr)
            {
                osgGA::GUIEventAdapter* event = itr->get();
                switch(event->getEventType())
                {
                    case(osgGA::GUIEventAdapter::KEYUP):
                        if (_keyEventSetsDone && event->getKey()==_keyEventSetsDone) _done = true;
                        break;

                    case(osgGA::GUIEventAdapter::QUIT_APPLICATION):
                        if (_quitEventSetsDone) _done = true;
                        break;

                    default:
                        break;
                }
            }
        }
    }

    if (_done) return;

    if (_eventVisitor.valid())
    {
        _eventVisitor->setFrameStamp(getFrameStamp());
        _eventVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber());

        for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
            veitr != viewEventsMap.end();
            ++veitr)
        {
            View* view = veitr->first;
            _eventVisitor->setActionAdapter(view);

            if (view->getSceneData())
            {
                for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
                    itr != veitr->second.end();
                    ++itr)
                {
                    osgGA::GUIEventAdapter* event = itr->get();

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

                    view->getSceneData()->accept(*_eventVisitor);

                    // Do EventTraversal for slaves with their own subgraph
                    for(unsigned int i=0; i<view->getNumSlaves(); ++i)
                    {
                        osg::View::Slave& slave = view->getSlave(i);
                        osg::Camera* camera = slave._camera.get();
                        if(camera && !slave._useMastersSceneData)
                        {
                            camera->accept(*_eventVisitor);
                        }
                    }

                    // call any camera event 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 (view->getCamera() && view->getCamera()->getEventCallback()) view->getCamera()->accept(*_eventVisitor);

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

                    _eventVisitor->setTraversalMode(tm);

                }
            }
        }

    }

    for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
        veitr != viewEventsMap.end();
        ++veitr)
    {
        View* view = veitr->first;

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

            for(View::EventHandlers::iterator hitr = view->getEventHandlers().begin();
                hitr != view->getEventHandlers().end();
                ++hitr)
            {
                (*hitr)->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view, 0, 0);
            }
        }
    }

    for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
        veitr != viewEventsMap.end();
        ++veitr)
    {
        View* view = veitr->first;

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

            if (view->getCameraManipulator())
            {
                view->getCameraManipulator()->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view);
            }
        }
    }



    if (getViewerStats() && getViewerStats()->collectStats("event"))
    {
        double endEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());

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