From e8fc5248fa90abe163879887888e44c03deeb90a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 Aug 2005 13:29:07 +0000 Subject: [PATCH] Added realize() and isRealized() methods to osg::GraphicsContext. Added osgcamera example that uses osg::GraphicsContext to create the required window for rendering too, will eventually use osg::CameraNode to replace usage of osgUtil::SceneView. --- Make/makedirdefs | 1 + examples/osgcamera/GNUmakefile | 27 ++++++ examples/osgcamera/GNUmakefile.inst | 14 +++ examples/osgcamera/osgcamera.cpp | 97 +++++++++++++++++++ include/osg/GraphicsContext | 14 ++- .../osgProducer/GraphicsContextImplementation | 7 +- .../GraphicsContextImplementation.cpp | 30 ++++-- src/osgUtil/CullVisitor.cpp | 2 + 8 files changed, 182 insertions(+), 10 deletions(-) create mode 100644 examples/osgcamera/GNUmakefile create mode 100644 examples/osgcamera/GNUmakefile.inst create mode 100644 examples/osgcamera/osgcamera.cpp diff --git a/Make/makedirdefs b/Make/makedirdefs index 54f57fa23..d7470745e 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -176,6 +176,7 @@ EXAMPLE_DIRS = \ osgblendequation\ osgcallback\ osgcatch\ + osgcamera\ osgcameragroup\ osgclip\ osgcluster\ diff --git a/examples/osgcamera/GNUmakefile b/examples/osgcamera/GNUmakefile new file mode 100644 index 000000000..970a7ca6a --- /dev/null +++ b/examples/osgcamera/GNUmakefile @@ -0,0 +1,27 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgcamera.cpp\ + +LIBS += -losgProducer -lProducer -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) -lOpenThreads + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgcamera + +INC += $(X_INC) +LDFLAGS += -L/usr/X11R6/lib + + +ifeq ($(USE_OPEN_THREAD),1) + DEF += -D_USE_OPEN_THREAD + INC += $(INC_OPEN_THREAD) + LDFLAGS += $(LIB_OPEN_THREAD) + LIBS += -lOpenThread +endif + +include $(TOPDIR)/Make/makerules + diff --git a/examples/osgcamera/GNUmakefile.inst b/examples/osgcamera/GNUmakefile.inst new file mode 100644 index 000000000..223881046 --- /dev/null +++ b/examples/osgcamera/GNUmakefile.inst @@ -0,0 +1,14 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgcamera.cpp\ + +LIBS += -lProducer -losgDB --losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgcamera + +INC += $(PRODUCER_INCLUDE_DIR) $(X_INC) +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgcamera/osgcamera.cpp b/examples/osgcamera/osgcamera.cpp new file mode 100644 index 000000000..8e23ca16b --- /dev/null +++ b/examples/osgcamera/osgcamera.cpp @@ -0,0 +1,97 @@ +// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL. +// +// Simple example of use of Producer::RenderSurface to create an OpenGL +// graphics window, and OSG for rendering. + +#include +#include +#include +#include +#include + +int main( int argc, char **argv ) +{ + if (argc<2) + { + std::cout << argv[0] <<": requires filename argument." << std::endl; + return 1; + } + + // load the scene. + osg::ref_ptr loadedModel = osgDB::readNodeFile(argv[1]); + if (!loadedModel) + { + std::cout << argv[0] <<": No data loaded." << std::endl; + return 1; + } + + osg::ref_ptr traits = new osg::GraphicsContext::Traits; + traits->_windowName = "osgcamera"; + traits->_x = 100; + traits->_y = 100; + traits->_width = 800; + traits->_height = 800; + traits->_windowDecoration = true; + traits->_doubleBuffer = true; + + osg::ref_ptr gfxc = osg::GraphicsContext::createGraphicsContext(traits.get()); + + if (!gfxc) + { + std::cout<<"Unable to create window."<realize(); + + // create the view of the scene. + osg::ref_ptr sceneView = new osgUtil::SceneView; + sceneView->setDefaults(); + sceneView->setSceneData(loadedModel.get()); + + // initialize the view to look at the center of the scene graph + const osg::BoundingSphere& bs = loadedModel->getBound(); + osg::Matrix viewMatrix; + viewMatrix.makeLookAt(bs.center()-osg::Vec3(0.0,2.0f*bs.radius(),0.0),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); + + // record the timer tick at the start of rendering. + osg::Timer_t start_tick = osg::Timer::instance()->tick(); + + unsigned int frameNum = 0; + + // make the graphics context current + gfxc->makeCurrent(); + + // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.) + while( gfxc->isRealized() ) + { + // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly + osg::ref_ptr frameStamp = new osg::FrameStamp; + frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick())); + frameStamp->setFrameNumber(frameNum++); + + // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp + sceneView->setFrameStamp(frameStamp.get()); + + // update the viewport dimensions, incase the window has been resized. + sceneView->setViewport(0,0,traits->_width,traits->_height); + + // set the view + sceneView->setViewMatrix(viewMatrix); + + // do the update traversal the scene graph - such as updating animations + sceneView->update(); + + // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins + sceneView->cull(); + + // draw the rendering bins. + sceneView->draw(); + + // Swap Buffers + gfxc->swapBuffers(); + } + + return 0; +} diff --git a/include/osg/GraphicsContext b/include/osg/GraphicsContext index 59289e650..ebe128fc9 100644 --- a/include/osg/GraphicsContext +++ b/include/osg/GraphicsContext @@ -134,19 +134,27 @@ class OSG_EXPORT GraphicsContext : public Referenced /** Get the const State object which tracks the current OpenGL state for this graphics context.*/ inline const State* getState() const { return _state.get(); } - - /** Return true if the current thread has this OpenGL graphics context.*/ - inline bool isCurrent() const { return _threadOfLastMakeCurrent == OpenThreads::Thread::CurrentThread(); } + + /** Realise the GraphicsContext.*/ + virtual bool realize() = 0; + + /** Return true if the graphics context has been realised and is ready to use.*/ + virtual bool isRealized() const = 0; /** Release the graphics context.*/ virtual void release() = 0; + /** Make this graphics context current.*/ virtual void makeCurrent() = 0; /** Make this graphics context current with specified read context.*/ virtual void makeContextCurrent(GraphicsContext* readContext) = 0; + /** Return true if the current thread has this OpenGL graphics context.*/ + inline bool isCurrent() const { return _threadOfLastMakeCurrent == OpenThreads::Thread::CurrentThread(); } + + /** Bind the graphics context to associated texture.*/ virtual void bindPBufferToTexture(GLenum buffer) = 0; diff --git a/include/osgProducer/GraphicsContextImplementation b/include/osgProducer/GraphicsContextImplementation index 00668955f..e70939bd4 100644 --- a/include/osgProducer/GraphicsContextImplementation +++ b/include/osgProducer/GraphicsContextImplementation @@ -36,7 +36,6 @@ class OSGPRODUCER_EXPORT GraphicsContextImplementation : public osg::GraphicsCon GraphicsContextImplementation(Producer::RenderSurface* rs); /** Return true of graphics context is realized.*/ - bool isRealized() { return _rs.valid() && _rs->isRealized(); } /** Return the RenderSurface that implements the graphics context.*/ Producer::RenderSurface* getRenderSurface() { return _rs.get(); } @@ -45,6 +44,12 @@ class OSGPRODUCER_EXPORT GraphicsContextImplementation : public osg::GraphicsCon const Producer::RenderSurface* getRenderSurface() const { return _rs.get(); } + /** Realise the GraphicsContext.*/ + virtual bool realize(); + + /** Return true if the graphics context has been realised and is ready to use.*/ + virtual bool isRealized() const { return _rs.valid() && _rs->isRealized(); } + /** Release the graphics context.*/ virtual void release(); diff --git a/src/osgProducer/GraphicsContextImplementation.cpp b/src/osgProducer/GraphicsContextImplementation.cpp index cbfff08d7..8f63bdbae 100644 --- a/src/osgProducer/GraphicsContextImplementation.cpp +++ b/src/osgProducer/GraphicsContextImplementation.cpp @@ -50,7 +50,6 @@ GraphicsContextImplementation::GraphicsContextImplementation(Traits* traits) _rs->setWindowRectangle(traits->_x, traits->_y, traits->_width, traits->_height); _rs->useBorder(traits->_windowDecoration); -#if 1 // set the visual chooser Producer::VisualChooser* rs_vc = _rs->getVisualChooser(); if (!rs_vc) @@ -71,11 +70,8 @@ GraphicsContextImplementation::GraphicsContextImplementation(Traits* traits) rs_vc->addAttribute( Producer::VisualChooser::RGBA ); - // Always use UseGL rs_vc->addAttribute( Producer::VisualChooser::UseGL ); - -#endif if (traits->_pbuffer) { @@ -141,7 +137,7 @@ GraphicsContextImplementation::GraphicsContextImplementation(Traits* traits) } // but we share texture objects etc. so we also share the same contextID - _rs->realize( 0, sharedContext->_rs->getGLContext() ); + //_rs->realize( 0, sharedContext->_rs->getGLContext() ); } else @@ -151,7 +147,7 @@ GraphicsContextImplementation::GraphicsContextImplementation(Traits* traits) setState( new osg::State ); getState()->setContextID( GraphicsContext::createNewContextID() ); - _rs->realize(); + //_rs->realize(); } } @@ -166,6 +162,28 @@ GraphicsContextImplementation::~GraphicsContextImplementation() release(); } +bool GraphicsContextImplementation::realize() +{ + if (_rs.valid()) + { + GraphicsContextImplementation* sharedContext = dynamic_cast(_traits->_sharedContext); + + if (sharedContext) + { + _rs->realize( 0, sharedContext->_rs->getGLContext() ); + } + else + { + _rs->realize(); + } + return _rs->isRealized(); + } + else + { + return false; + } +} + void GraphicsContextImplementation::makeCurrent() { if (!_rs) return; diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index 7354bd9e9..7765ab4cd 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -1302,6 +1302,8 @@ void CullVisitor::apply(osg::CameraNode& camera) } rtts->setGraphicsContext(context.get()); + + context->realize(); } }