1
0
Fork 0

Simplify canvas OpenVG initialization and fix sometimes rendering too lazy

This commit is contained in:
Thomas Geymayer 2012-10-31 01:40:43 +01:00
parent c79e2465df
commit 71eeb62c1b
4 changed files with 9 additions and 76 deletions

View file

@ -22,7 +22,6 @@
#include <Canvas/MouseEvent.hxx> #include <Canvas/MouseEvent.hxx>
#include <Canvas/property_helper.hxx> #include <Canvas/property_helper.hxx>
#include <Main/fg_props.hxx> #include <Main/fg_props.hxx>
#include <Main/globals.hxx>
#include <Viewer/CameraGroup.hxx> #include <Viewer/CameraGroup.hxx>
#include <Viewer/renderer.hxx> #include <Viewer/renderer.hxx>
@ -49,16 +48,7 @@ class Canvas::DrawCallback:
virtual void operator()(osg::RenderInfo& renderInfo) const virtual void operator()(osg::RenderInfo& renderInfo) const
{ {
const long frame = renderInfo.getView()->getFrameStamp() _canvas->_render_dirty = false;
->getFrameNumber();
static SGPropertyNode_ptr node_frame =
globals->get_props()->getNode(canvas::VG_INIT_SIGNAL, true);
// If OpenVG has been initialized we need to redraw the frame, because
// initializing has happened instead of rendering.
// Otherwise we just reset the _render_dirty flag.
_canvas->_render_dirty = (frame == node_frame->getLongValue());
} }
protected: protected:

View file

@ -32,8 +32,6 @@ typedef boost::weak_ptr<Canvas> CanvasWeakPtr;
namespace canvas namespace canvas
{ {
const std::string VG_INIT_SIGNAL = "/sim/signals/vg-initialized-frame";
class Group; class Group;
class Image; class Image;
class MouseEvent; class MouseEvent;

View file

@ -52,24 +52,10 @@ namespace canvas
setDataVariance(Object::DYNAMIC); setDataVariance(Object::DYNAMIC);
setUpdateCallback(new PathUpdateCallback()); setUpdateCallback(new PathUpdateCallback());
setCullCallback(new NoCullCallback());
} }
virtual ~PathDrawable() virtual ~PathDrawable()
{ {
if( !_vg_initialized )
{
if( _path != VG_INVALID_HANDLE )
SG_LOG
(
SG_GL,
SG_WARN,
"Can't destroy path without OpenVG context: "
<< _path_element->_node->getPath()
);
return;
}
if( _path != VG_INVALID_HANDLE ) if( _path != VG_INVALID_HANDLE )
vgDestroyPath(_path); vgDestroyPath(_path);
if( _paint != VG_INVALID_HANDLE ) if( _paint != VG_INVALID_HANDLE )
@ -93,7 +79,7 @@ namespace canvas
_cmds = cmds; _cmds = cmds;
_coords = coords; _coords = coords;
_attributes_dirty |= PATH; _attributes_dirty |= (PATH | BOUNDING_BOX);
} }
/** /**
@ -182,7 +168,7 @@ namespace canvas
*/ */
virtual void drawImplementation(osg::RenderInfo& renderInfo) const virtual void drawImplementation(osg::RenderInfo& renderInfo) const
{ {
if( (_attributes_dirty & PATH) && _vg_initialized ) if( _attributes_dirty & PATH )
return; return;
osg::State* state = renderInfo.getState(); osg::State* state = renderInfo.getState();
@ -196,21 +182,6 @@ namespace canvas
// eg. doesn't include GL_MULTISAMPLE_BIT // eg. doesn't include GL_MULTISAMPLE_BIT
glPushClientAttrib(~0u); glPushClientAttrib(~0u);
// Initialize OpenVG itself
if( !_vg_initialized )
{
GLint vp[4];
glGetIntegerv(GL_VIEWPORT, vp);
vgCreateContextSH(vp[2], vp[3]);
_vg_initialized = true;
fgSetInt( canvas::VG_INIT_SIGNAL,
renderInfo.getView()->getFrameStamp()->getFrameNumber() );
return;
}
// Initialize/Update the paint // Initialize/Update the paint
if( _attributes_dirty & STROKE_COLOR ) if( _attributes_dirty & STROKE_COLOR )
{ {
@ -268,7 +239,7 @@ namespace canvas
*/ */
virtual osg::BoundingBox computeBound() const virtual osg::BoundingBox computeBound() const
{ {
if( _path == VG_INVALID_HANDLE ) if( _path == VG_INVALID_HANDLE || (_attributes_dirty & PATH) )
return osg::BoundingBox(); return osg::BoundingBox();
VGfloat min[2], size[2]; VGfloat min[2], size[2];
@ -291,8 +262,6 @@ namespace canvas
private: private:
static bool _vg_initialized;
enum Attributes enum Attributes
{ {
PATH = 0x0001, PATH = 0x0001,
@ -352,45 +321,16 @@ namespace canvas
dirtyBound(); dirtyBound();
} }
/**
* Updating the path before drawing is needed to enable correct bounding
* box calculations and make culling work.
*/
struct PathUpdateCallback: struct PathUpdateCallback:
public osg::Drawable::UpdateCallback public osg::Drawable::UpdateCallback
{ {
virtual void update(osg::NodeVisitor*, osg::Drawable* drawable) virtual void update(osg::NodeVisitor*, osg::Drawable* drawable)
{ {
if( !_vg_initialized )
return;
static_cast<PathDrawable*>(drawable)->update(); static_cast<PathDrawable*>(drawable)->update();
} }
}; };
/**
* Callback used to prevent culling as long as OpenVG is not initialized.
* This is needed because OpenVG needs an active OpenGL context for
* initialization which is only available in #drawImplementation.
* As soon as OpenVG is correctly initialized the callback automatically
* removes itself from the node, so that the normal culling can get
* active.
*/
struct NoCullCallback:
public osg::Drawable::CullCallback
{
virtual bool cull( osg::NodeVisitor*,
osg::Drawable* drawable,
osg::State* ) const
{
if( _vg_initialized )
drawable->setCullCallback(0);
return false;
}
};
}; };
bool Path::PathDrawable::_vg_initialized = false;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Path::Path(SGPropertyNode_ptr node, const Style& parent_style): Path::Path(SGPropertyNode_ptr node, const Style& parent_style):
Element(node, parent_style), Element(node, parent_style),

View file

@ -34,6 +34,7 @@
#include <osgDB/Registry> #include <osgDB/Registry>
// Class references // Class references
#include <simgear/canvas/VGInitOperation.hxx>
#include <simgear/scene/model/modellib.hxx> #include <simgear/scene/model/modellib.hxx>
#include <simgear/scene/material/matlib.hxx> #include <simgear/scene/material/matlib.hxx>
#include <simgear/props/AtomicChangeListener.hxx> #include <simgear/props/AtomicChangeListener.hxx>
@ -52,6 +53,7 @@
#include <GUI/gui.h> #include <GUI/gui.h>
#include <Viewer/splash.hxx> #include <Viewer/splash.hxx>
#include <Viewer/renderer.hxx> #include <Viewer/renderer.hxx>
#include <Viewer/WindowSystemAdapter.hxx>
#include <Navaids/NavDataCache.hxx> #include <Navaids/NavDataCache.hxx>
#include "fg_commands.hxx" #include "fg_commands.hxx"
@ -249,6 +251,9 @@ static void fgIdleFunction ( void ) {
globals->get_renderer()->resize( fgGetInt("/sim/startup/xsize"), globals->get_renderer()->resize( fgGetInt("/sim/startup/xsize"),
fgGetInt("/sim/startup/ysize") ); fgGetInt("/sim/startup/ysize") );
WindowSystemAdapter::getWSA()->windows[0]->gc->add(
new simgear::canvas::VGInitOperation()
);
int session = fgGetInt("/sim/session",0); int session = fgGetInt("/sim/session",0);
session++; session++;