Refactored ImpostorSprite so that it no longer uses GLBeginEndAdapter

This commit is contained in:
Robert Osfield 2016-08-25 11:32:00 +01:00
parent 35e19b4f30
commit c637010c9d
3 changed files with 44 additions and 100 deletions

View File

@ -15,8 +15,7 @@
#define OSG_ImpostorSprite 1 #define OSG_ImpostorSprite 1
#include <osg/Vec2> #include <osg/Vec2>
#include <osg/BoundingSphere> #include <osg/Geometry>
#include <osg/Drawable>
#include <osg/AlphaFunc> #include <osg/AlphaFunc>
#include <osg/TexEnv> #include <osg/TexEnv>
#include <osg/Texture2D> #include <osg/Texture2D>
@ -35,7 +34,7 @@ class ImpostorSpriteManager;
* automatically generated by the osgUtil::CullVisitor so it not * automatically generated by the osgUtil::CullVisitor so it not
* necessary to deal with it directly. * necessary to deal with it directly.
*/ */
class OSGSIM_EXPORT ImpostorSprite : public osg::Drawable class OSGSIM_EXPORT ImpostorSprite : public osg::Geometry
{ {
public: public:
@ -77,23 +76,26 @@ class OSGSIM_EXPORT ImpostorSprite : public osg::Drawable
inline unsigned int getLastFrameUsed() const { return _lastFrameUsed; } inline unsigned int getLastFrameUsed() const { return _lastFrameUsed; }
void dirty();
/** Get the coordinates of the corners of the quad. /** Get the coordinates of the corners of the quad.
* Stored in the order, [0] - top_left, [1] - bottom_left, [2] - bottom_right, [3] - top_left. * Stored in the order, [0] - top_left, [1] - bottom_left, [2] - bottom_right, [3] - top_left.
*/ */
inline osg::Vec3* getCoords() { return _coords; } inline osg::Vec3* getCoords() { return &(_coords->front()); }
/** Get the const coordinates of the corners of the quad. */ /** Get the const coordinates of the corners of the quad. */
inline const osg::Vec3* getCoords() const { return _coords; } inline const osg::Vec3* getCoords() const { return &(_coords->front()); }
/** Get the texture coordinates of the corners of the quad. /** Get the texture coordinates of the corners of the quad.
* Stored in the order, [0] - top_left, [1] - bottom_left, [2] - bottom_right, [3] - top_left. * Stored in the order, [0] - top_left, [1] - bottom_left, [2] - bottom_right, [3] - top_left.
*/ */
inline osg::Vec2* getTexCoords() { return _texcoords; } inline osg::Vec2* getTexCoords() { return &(_texcoords->front()); }
/** Get the const texture coordinates of the corners of the quad. */ /** Get the const texture coordinates of the corners of the quad. */
inline const osg::Vec2* getTexCoords() const { return _texcoords; } inline const osg::Vec2* getTexCoords() const { return &(_texcoords->front()); }
/** Get the control coordinates of the corners of the quad. /** Get the control coordinates of the corners of the quad.
* The control coordinates are the corners of the quad projected * The control coordinates are the corners of the quad projected
@ -125,32 +127,6 @@ class OSGSIM_EXPORT ImpostorSprite : public osg::Drawable
int s() const { return _s; } int s() const { return _s; }
int t() const { return _t; } int t() const { return _t; }
/** Draw ImpostorSprite directly. */
virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
/** Return true, osg::ImpostorSprite does support accept(Drawable::AttributeFunctor&). */
virtual bool supports(const Drawable::AttributeFunctor&) const { return true; }
/** Accept an Drawable::AttributeFunctor and call its methods to tell it about the internal attributes that this Drawable has. */
virtual void accept(Drawable::AttributeFunctor& af);
/** Return true, osg::ImpostorSprite does support accept(Drawable::ConstAttributeFunctor&). */
virtual bool supports(const Drawable::ConstAttributeFunctor&) const { return true; }
/** Accept a Drawable::ConstAttributeFunctor and call its methods to tell it about the internal attributes that this Drawable has. */
virtual void accept(Drawable::ConstAttributeFunctor& af) const;
/** Return true, osg::ImpostorSprite does support accept(PrimitiveFunctor&). */
virtual bool supports(const osg::PrimitiveFunctor&) const { return true; }
/** Accept a PrimtiveFunctor and call its methods to tell it about the internal primitives that this Drawable has. */
virtual void accept(osg::PrimitiveFunctor& pf) const;
// for debugging purposes.
osg::Vec4 _color;
virtual osg::BoundingBox computeBoundingBox() const;
/** Set the camera node to use for pre rendering the impostor sprite's texture.*/ /** Set the camera node to use for pre rendering the impostor sprite's texture.*/
void setCamera(osg::Camera* camera) { _camera = camera; } void setCamera(osg::Camera* camera) { _camera = camera; }
@ -167,6 +143,8 @@ class OSGSIM_EXPORT ImpostorSprite : public osg::Drawable
virtual ~ImpostorSprite(); virtual ~ImpostorSprite();
void init();
Impostor* _parent; Impostor* _parent;
friend class osgSim::ImpostorSpriteManager; friend class osgSim::ImpostorSpriteManager;
@ -184,8 +162,8 @@ class OSGSIM_EXPORT ImpostorSprite : public osg::Drawable
osg::Vec3 _storedLocalEyePoint; osg::Vec3 _storedLocalEyePoint;
osg::Vec3 _coords[4]; osg::ref_ptr<osg::Vec3Array> _coords;
osg::Vec2 _texcoords[4]; osg::ref_ptr<osg::Vec2Array> _texcoords;
osg::Vec3 _controlcoords[4]; osg::Vec3 _controlcoords[4];
osg::Texture2D* _texture; osg::Texture2D* _texture;

View File

@ -351,7 +351,7 @@ ImpostorSprite* Impostor::createImpostorSprite(osgUtil::CullVisitor* cv)
coords[3] = c11; coords[3] = c11;
texcoords[3].set(1.0f,1.0f); texcoords[3].set(1.0f,1.0f);
impostorSprite->dirtyBound(); impostorSprite->dirty();
Vec3* controlcoords = impostorSprite->getControlCoords(); Vec3* controlcoords = impostorSprite->getControlCoords();

View File

@ -41,11 +41,12 @@ ImpostorSprite::ImpostorSprite():
{ {
// don't use display list since we will be updating the geometry. // don't use display list since we will be updating the geometry.
setUseDisplayList(false); setUseDisplayList(false);
_color.set(1.0f, 1.0f, 1.0f, 1.0f );
init();
} }
ImpostorSprite::ImpostorSprite(const ImpostorSprite&): ImpostorSprite::ImpostorSprite(const ImpostorSprite&):
osg::Drawable(), osg::Geometry(),
_parent(0), _parent(0),
_ism(0), _ism(0),
_previous(0), _previous(0),
@ -56,7 +57,8 @@ ImpostorSprite::ImpostorSprite(const ImpostorSprite&):
_t(0) _t(0)
{ {
setUseDisplayList(false); setUseDisplayList(false);
_color.set(1.0f, 1.0f, 1.0f, 1.0f );
init();
} }
ImpostorSprite::~ImpostorSprite() ImpostorSprite::~ImpostorSprite()
@ -67,6 +69,30 @@ ImpostorSprite::~ImpostorSprite()
} }
} }
void ImpostorSprite::init()
{
_coords = new osg::Vec3Array(osg::Array::BIND_PER_VERTEX, 4);
_texcoords = new osg::Vec2Array(osg::Array::BIND_PER_VERTEX, 4);
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(osg::Array::BIND_OVERALL);
colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
setVertexArray(_coords.get());
setColorArray(colors);
setTexCoordArray(0, _texcoords.get());
addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
}
void ImpostorSprite::dirty()
{
_coords->dirty();
_texcoords->dirty();
dirtyGLObjects();
dirtyBound();
}
float ImpostorSprite::calcPixelError(const osg::Matrix& MVPW) const float ImpostorSprite::calcPixelError(const osg::Matrix& MVPW) const
{ {
// find the maximum screen space pixel error between the control coords and the quad coners. // find the maximum screen space pixel error between the control coords and the quad coners.
@ -75,7 +101,7 @@ float ImpostorSprite::calcPixelError(const osg::Matrix& MVPW) const
for(int i=0;i<4;++i) for(int i=0;i<4;++i)
{ {
osg::Vec3 projected_coord = _coords[i]*MVPW; osg::Vec3 projected_coord = (*_coords)[i]*MVPW;
osg::Vec3 projected_control = _controlcoords[i]*MVPW; osg::Vec3 projected_control = _controlcoords[i]*MVPW;
float dx = (projected_coord.x()-projected_control.x()); float dx = (projected_coord.x()-projected_control.x());
@ -89,46 +115,6 @@ float ImpostorSprite::calcPixelError(const osg::Matrix& MVPW) const
return sqrtf(max_error_sqrd); return sqrtf(max_error_sqrd);
} }
void ImpostorSprite::drawImplementation(osg::RenderInfo& renderInfo) const
{
osg::GLBeginEndAdapter& gl = (renderInfo.getState()->getGLBeginEndAdapter());
// when the tex env is set to REPLACE, and the
// texture is set up correctly the color has no effect.
gl.Color4fv( _color.ptr() );
gl.Begin( GL_QUADS );
gl.TexCoord2fv( (GLfloat *)&_texcoords[0] );
gl.Vertex3fv( (GLfloat *)&_coords[0] );
gl.TexCoord2fv( (GLfloat *)&_texcoords[1] );
gl.Vertex3fv( (GLfloat *)&_coords[1] );
gl.TexCoord2fv( (GLfloat *)&_texcoords[2] );
gl.Vertex3fv( (GLfloat *)&_coords[2] );
gl.TexCoord2fv( (GLfloat *)&_texcoords[3] );
gl.Vertex3fv( (GLfloat *)&_coords[3] );
gl.End();
}
osg::BoundingBox ImpostorSprite::computeBoundingBox() const
{
osg::BoundingBox bbox;
bbox.expandBy(_coords[0]);
bbox.expandBy(_coords[1]);
bbox.expandBy(_coords[2]);
bbox.expandBy(_coords[3]);
if (!bbox.valid())
{
OSG_WARN << "******* ImpostorSprite::computeBound() problem"<<std::endl;
}
return bbox;
}
void ImpostorSprite::setTexture(osg::Texture2D* tex,int s,int t) void ImpostorSprite::setTexture(osg::Texture2D* tex,int s,int t)
{ {
@ -138,26 +124,6 @@ void ImpostorSprite::setTexture(osg::Texture2D* tex,int s,int t)
} }
void ImpostorSprite::accept(AttributeFunctor& af)
{
af.apply(VERTICES,4,_coords);
af.apply(TEXTURE_COORDS_0,4,_texcoords);
}
void ImpostorSprite::accept(ConstAttributeFunctor& af) const
{
af.apply(VERTICES,4,_coords);
af.apply(TEXTURE_COORDS_0,4,_texcoords);
}
void ImpostorSprite::accept(osg::PrimitiveFunctor& functor) const
{
functor.setVertexArray(4,_coords);
functor.drawArrays( GL_QUADS, 0, 4);
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Helper class for managing the reuse of ImpostorSprite resources. // Helper class for managing the reuse of ImpostorSprite resources.
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////