Added support for multiple graphics context to osg::VertexProgram and osg::Impostor

This commit is contained in:
Robert Osfield 2003-04-10 12:11:40 +00:00
parent 0dd724e8b7
commit 22546b8085
7 changed files with 67 additions and 39 deletions

View File

@ -19,19 +19,14 @@ OSG News (most significant items from ChangeLog)
configuration of threading and multiple camera views can all be done configuration of threading and multiple camera views can all be done
via ASCII configuration files, no need to recompile. via ASCII configuration files, no need to recompile.
Improvements to the Makefle system. Added Linux 64 bit support for IA64 (Intel Itanium) and x86-64 (AMD Opteron)
which augments the existing support for Solaris and IRIX 64 bit compilation.
64 bit supports allows the use of very large data set, and potential
peformance improvemnts.
Added support for early abort of rendering, useful for interactive Improvements to the makefile system, all makefiles are now named
applications which occasional have rendering that takes that long GNUmakefile which ensures that they are only run by gmake. The new system
enough (i.e. several second) that end users may wish to abort allow multiple build targets to be built from one source code install.
during the drawing.
Improved thread safety when working multipipe systems.
New MD2 plugin which allows Quake animated characters to be loaded
into the OSG.
New DDS plugin for loading compressed and non-compressed images.
Completely new osgText implemention which is simpler to use, faster, and Completely new osgText implemention which is simpler to use, faster, and
thread safe. Support for high quality true type fonts has now been moved thread safe. Support for high quality true type fonts has now been moved
@ -42,6 +37,13 @@ OSG News (most significant items from ChangeLog)
the rest of the core libraries, virtual of this osgText now compiles the rest of the core libraries, virtual of this osgText now compiles
by default on platforms. by default on platforms.
Improved thread safety when working multipipe systems.
New DDS plugin for loading compressed and non-compressed images.
New MD2 plugin which allows Quake animated characters to be loaded
into the OSG.
New osg::TextureRectangle texture class which encapsulates the New osg::TextureRectangle texture class which encapsulates the
NV_texture_rectangle and EXT_texture_rectange extensions. NV_texture_rectangle and EXT_texture_rectange extensions.
@ -52,8 +54,14 @@ OSG News (most significant items from ChangeLog)
New database cache in the osgDB library. New database cache in the osgDB library.
Added support for early abort of rendering, useful for interactive
applications which occasional have rendering that takes that long
enough (i.e. several seconds) that end users may wish to abort
during the drawing.
Clean up of memory management in the OpenFlight loader. Clean up of memory management in the OpenFlight loader.
Various API clean ups and bug fixes.
24th January 2003 - OpenSceneGraph-0.9.3.tar.gz 24th January 2003 - OpenSceneGraph-0.9.3.tar.gz

View File

@ -16,6 +16,7 @@
#include <osg/LOD> #include <osg/LOD>
#include <osg/ImpostorSprite> #include <osg/ImpostorSprite>
#include <osg/buffered_value>
namespace osg { namespace osg {
@ -64,7 +65,6 @@ class SG_EXPORT Impostor : public LOD
Impostor(const Impostor& es, const CopyOp& copyop=CopyOp::SHALLOW_COPY): Impostor(const Impostor& es, const CopyOp& copyop=CopyOp::SHALLOW_COPY):
LOD(es,copyop), LOD(es,copyop),
_impostorSpriteList(),
_impostorThreshold(es._impostorThreshold) {} _impostorThreshold(es._impostorThreshold) {}
META_Node(osg, Impostor); META_Node(osg, Impostor);
@ -87,16 +87,16 @@ class SG_EXPORT Impostor : public LOD
inline float getImpostorThreshold2() const { return _impostorThreshold*_impostorThreshold; } inline float getImpostorThreshold2() const { return _impostorThreshold*_impostorThreshold; }
/** Find the ImposterSprite which fits the current eye point best.*/ /** Find the ImposterSprite which fits the current eye point best.*/
ImpostorSprite* findBestImpostorSprite(const osg::Vec3& currLocalEyePoint); ImpostorSprite* findBestImpostorSprite(unsigned int contextID, const osg::Vec3& currLocalEyePoint) const;
/** Add an ImpostorSprite to the Impostor.*/ /** Add an ImpostorSprite to the Impostor.*/
void addImpostorSprite(ImpostorSprite* is); void addImpostorSprite(unsigned int contextID, ImpostorSprite* is);
/** Get the list of ImpostorSprites attached to this Impostor.*/ /** Get the list of ImpostorSprites attached to this Impostor.*/
inline ImpostorSpriteList& getImpostorSpriteList() { return _impostorSpriteList; } inline ImpostorSpriteList& getImpostorSpriteList(unsigned int contexID) { return _impostorSpriteListBuffer[contexID]; }
/** Get a const list of ImpostorSprites attached to this const Impostor.*/ /** Get a const list of ImpostorSprites attached to this const Impostor.*/
inline const ImpostorSpriteList& getImpostorSpriteList() const { return _impostorSpriteList; } inline const ImpostorSpriteList& getImpostorSpriteList(unsigned int contexID) const { return _impostorSpriteListBuffer[contexID]; }
protected : protected :
@ -104,7 +104,7 @@ class SG_EXPORT Impostor : public LOD
virtual bool computeBound() const; virtual bool computeBound() const;
ImpostorSpriteList _impostorSpriteList; mutable buffered_object<ImpostorSpriteList> _impostorSpriteListBuffer;
float _impostorThreshold; float _impostorThreshold;

View File

@ -202,17 +202,15 @@ class SG_EXPORT Texture : public osg::StateAttribute
/** Get the handle to the texture object for the current context.*/ /** Get the handle to the texture object for the current context.*/
/** return the OpenGL texture object for specified context.*/
inline GLuint& getTextureObject(unsigned int contextID) const inline GLuint& getTextureObject(unsigned int contextID) const
{ {
// get the globj for the current contextID.
return _handleList[contextID]; return _handleList[contextID];
} }
/** get the dirty flag for the current contextID.*/
inline unsigned int& getTextureParameterDirty(unsigned int contextID) const inline unsigned int& getTextureParameterDirty(unsigned int contextID) const
{ {
// get the dirty flag for the current contextID.
return _texParametersDirtyList[contextID]; return _texParametersDirtyList[contextID];
} }

View File

@ -17,6 +17,7 @@
#include <osg/StateAttribute> #include <osg/StateAttribute>
#include <osg/Vec4> #include <osg/Vec4>
#include <osg/Matrix> #include <osg/Matrix>
#include <osg/buffered_value>
#include <map> #include <map>
#include <string> #include <string>
@ -130,7 +131,7 @@ class SG_EXPORT VertexProgram : public StateAttribute
COMPARE_StateAttribute_Types(VertexProgram,sa) COMPARE_StateAttribute_Types(VertexProgram,sa)
// compare each paramter in turn against the rhs. // compare each paramter in turn against the rhs.
COMPARE_StateAttribute_Parameter(_vertexProgramId) COMPARE_StateAttribute_Parameter(_vertexProgram)
return 0; // passed all the above comparison macro's, must be equal. return 0; // passed all the above comparison macro's, must be equal.
} }
@ -142,6 +143,12 @@ class SG_EXPORT VertexProgram : public StateAttribute
// data access methods. // data access methods.
/** Get the handle to the vertex program id for the current context.*/
inline GLuint& getVertexProgramID(unsigned int contextID) const
{
return _vertexProgramIDList[contextID];
}
/** Set the vertex program using C++ style string.*/ /** Set the vertex program using C++ style string.*/
inline void setVertexProgram( const std::string& program ) { _vertexProgram = program; } inline void setVertexProgram( const std::string& program ) { _vertexProgram = program; }
/** Set the vertex program using a C style string.*/ /** Set the vertex program using a C style string.*/
@ -168,7 +175,9 @@ class SG_EXPORT VertexProgram : public StateAttribute
virtual ~VertexProgram(); virtual ~VertexProgram();
mutable GLuint _vertexProgramId; typedef buffered_value<GLuint> VertexProgramIDList;
mutable VertexProgramIDList _vertexProgramIDList;
std::string _vertexProgram; std::string _vertexProgram;
typedef std::map<GLuint,Vec4> LocalParamList; typedef std::map<GLuint,Vec4> LocalParamList;

View File

@ -22,12 +22,14 @@ Impostor::Impostor()
} }
ImpostorSprite* Impostor::findBestImpostorSprite(const osg::Vec3& currLocalEyePoint) ImpostorSprite* Impostor::findBestImpostorSprite(unsigned int contextID, const osg::Vec3& currLocalEyePoint) const
{ {
ImpostorSpriteList& impostorSpriteList = _impostorSpriteListBuffer[contextID];
float min_distance2 = FLT_MAX; float min_distance2 = FLT_MAX;
ImpostorSprite* impostorSprite = NULL; ImpostorSprite* impostorSprite = NULL;
for(ImpostorSpriteList::iterator itr=_impostorSpriteList.begin(); for(ImpostorSpriteList::iterator itr=impostorSpriteList.begin();
itr!=_impostorSpriteList.end(); itr!=impostorSpriteList.end();
++itr) ++itr)
{ {
float distance2 = (currLocalEyePoint-(*itr)->getStoredLocalEyePoint()).length2(); float distance2 = (currLocalEyePoint-(*itr)->getStoredLocalEyePoint()).length2();
@ -40,18 +42,20 @@ ImpostorSprite* Impostor::findBestImpostorSprite(const osg::Vec3& currLocalEyePo
return impostorSprite; return impostorSprite;
} }
void Impostor::addImpostorSprite(ImpostorSprite* is) void Impostor::addImpostorSprite(unsigned int contextID, ImpostorSprite* is)
{ {
if (is && is->getParent()!=this) if (is && is->getParent()!=this)
{ {
ImpostorSpriteList& impostorSpriteList = _impostorSpriteListBuffer[contextID];
// add it to my impostor list first, so it remains referenced // add it to my impostor list first, so it remains referenced
// when its reference in the previous_owner is removed. // when its reference in the previous_owner is removed.
_impostorSpriteList.push_back(is); impostorSpriteList.push_back(is);
if (is->getParent()) if (is->getParent())
{ {
Impostor* previous_owner = is->getParent(); Impostor* previous_owner = is->getParent();
ImpostorSpriteList& isl = previous_owner->_impostorSpriteList; ImpostorSpriteList& isl = previous_owner->_impostorSpriteListBuffer[contextID];
// find and erase reference to is. // find and erase reference to is.
for(ImpostorSpriteList::iterator itr=isl.begin(); for(ImpostorSpriteList::iterator itr=isl.begin();

View File

@ -13,19 +13,18 @@
#include <osg/Notify> #include <osg/Notify>
#include <osg/GLExtensions> #include <osg/GLExtensions>
#include <osg/VertexProgram> #include <osg/VertexProgram>
#include <osg/State>
using namespace osg; using namespace osg;
VertexProgram::VertexProgram() : VertexProgram::VertexProgram()
_vertexProgramId(0)
{ {
} }
VertexProgram::VertexProgram(const VertexProgram& vp,const CopyOp& copyop): VertexProgram::VertexProgram(const VertexProgram& vp,const CopyOp& copyop):
osg::StateAttribute(vp,copyop), osg::StateAttribute(vp,copyop)
_vertexProgramId(vp._vertexProgramId)
{} {}
@ -53,16 +52,19 @@ void VertexProgram::apply(State& state) const
static ProgramLocalParameter4fvProc s_glProgramLocalParameter4fv = static ProgramLocalParameter4fvProc s_glProgramLocalParameter4fv =
(ProgramLocalParameter4fvProc)osg::getGLExtensionFuncPtr("glProgramLocalParameter4fvARB"); (ProgramLocalParameter4fvProc)osg::getGLExtensionFuncPtr("glProgramLocalParameter4fvARB");
GLuint& vertexProgramId=getVertexProgramID(state.getContextID());
// Vertex Program // Vertex Program
if (_vertexProgramId != 0) if (vertexProgramId != 0)
{ {
s_glBindProgram( GL_VERTEX_PROGRAM_ARB, _vertexProgramId ); s_glBindProgram( GL_VERTEX_PROGRAM_ARB, vertexProgramId );
} }
else if (!_vertexProgram.empty()) else if (!_vertexProgram.empty())
{ {
::glGetError(); // Reset Error flags. ::glGetError(); // Reset Error flags.
s_glGenPrograms( 1, &_vertexProgramId ); s_glGenPrograms( 1, &vertexProgramId );
s_glBindProgram( GL_VERTEX_PROGRAM_ARB, _vertexProgramId ); s_glBindProgram( GL_VERTEX_PROGRAM_ARB, vertexProgramId );
s_glProgramString( GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, s_glProgramString( GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
_vertexProgram.length(), _vertexProgram.c_str()); _vertexProgram.length(), _vertexProgram.c_str());

View File

@ -581,6 +581,9 @@ void CullVisitor::apply(Impostor& node)
const BoundingSphere& bs = node.getBound(); const BoundingSphere& bs = node.getBound();
unsigned int contextID = 0;
if (_state.valid()) contextID = _state->getContextID();
float distance2 = (eyeLocal-bs.center()).length2(); float distance2 = (eyeLocal-bs.center()).length2();
if (!_impostorActive || if (!_impostorActive ||
distance2*_LODScale*_LODScale<node.getImpostorThreshold2() || distance2*_LODScale*_LODScale<node.getImpostorThreshold2() ||
@ -605,7 +608,7 @@ void CullVisitor::apply(Impostor& node)
RefMatrix& matrix = getModelViewMatrix(); RefMatrix& matrix = getModelViewMatrix();
// search for the best fit ImpostorSprite; // search for the best fit ImpostorSprite;
ImpostorSprite* impostorSprite = node.findBestImpostorSprite(eyeLocal); ImpostorSprite* impostorSprite = node.findBestImpostorSprite(contextID,eyeLocal);
if (impostorSprite) if (impostorSprite)
{ {
@ -673,6 +676,9 @@ void CullVisitor::apply(Impostor& node)
ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node) ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node)
{ {
unsigned int contextID = 0;
if (_state.valid()) contextID = _state->getContextID();
// default to true right now, will dertermine if perspective from the // default to true right now, will dertermine if perspective from the
// projection matrix... // projection matrix...
bool isPerspectiveProjection = true; bool isPerspectiveProjection = true;
@ -905,9 +911,10 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node)
// update frame number to show that impostor is in action. // update frame number to show that impostor is in action.
impostorSprite->setLastFrameUsed(getTraversalNumber()); impostorSprite->setLastFrameUsed(getTraversalNumber());
// have successfully created an impostor sprite so now need to // have successfully created an impostor sprite so now need to
// add it into the impostor. // add it into the impostor.
node.addImpostorSprite(impostorSprite); node.addImpostorSprite(contextID,impostorSprite);
if (_depthSortImpostorSprites) if (_depthSortImpostorSprites)
{ {