diff --git a/src/osgPlugins/logos/Makefile b/src/osgPlugins/logos/Makefile new file mode 100644 index 000000000..d528d0a5a --- /dev/null +++ b/src/osgPlugins/logos/Makefile @@ -0,0 +1,13 @@ +TOPDIR = ../../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + ReaderWriterLOGO.cpp\ + +LIBS += $(OSG_LIBS) $(OTHER_LIBS) + +TARGET_BASENAME = logo +include $(TOPDIR)/Make/cygwin_plugin_def +PLUGIN = $(PLUGIN_PREFIX)$(TARGET_BASENAME).$(PLUGIN_EXT) + +include $(TOPDIR)/Make/makerules diff --git a/src/osgPlugins/logos/ReaderWriterLOGO.cpp b/src/osgPlugins/logos/ReaderWriterLOGO.cpp new file mode 100644 index 000000000..2954bec8e --- /dev/null +++ b/src/osgPlugins/logos/ReaderWriterLOGO.cpp @@ -0,0 +1,224 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +using namespace osg; +using namespace osgDB; + + +class Logos: public osg::Drawable +{ + public: + enum RelativePosition{ + Center, + UpperLeft, + UpperRight, + LowerLeft, + LowerRight, + UpperCenter, + LowerCenter, + last_position + }; + + struct logosCullCallback : public osg::Drawable::CullCallback + { + virtual bool cull(osg::NodeVisitor *visitor, osg::Drawable* drawable, osg::State *state=NULL) const + { + Logos *logos = dynamic_cast (drawable); + osgUtil::CullVisitor *cv = dynamic_cast(visitor); + if( logos != NULL && cv != NULL ) + { + osg::Viewport *vp = cv->getViewport(); + if( vp != NULL ) + { + int x, y, aw, ah, bw, bh; + logos->getViewport()->getViewport( x, y, aw, ah ); + vp->getViewport(x, y, bw, bh ); + if( aw != bw || ah != bh ) + { + logos->getViewport()->setViewport( x, y, bw, bh ); + logos->dirtyDisplayList(); + } + } + } + return false; + } + }; + + Logos() + { + osg::StateSet *sset = new osg::StateSet; + osg::BlendFunc *transp = new osg::BlendFunc; + transp->setFunction(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + sset->setAttribute( transp ); + sset->setMode( GL_BLEND, osg::StateAttribute::ON ); + sset->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF ); + sset->setRenderBinDetails( StateSet::TRANSPARENT_BIN + 1 , "RenderBin" ); + setStateSet( sset ); + viewport = new osg::Viewport; + setCullCallback( new logosCullCallback ); + } + + Logos(const Logos& logo, const CopyOp& copyop=CopyOp::SHALLOW_COPY) :Drawable( logo, copyop ) {} + virtual Object* cloneType() const { return new Logos(); } + virtual Object* clone( const CopyOp& copyop) const { return new Logos(*this, copyop ); } + virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* className() const { return "Logos"; } + + virtual void drawImmediateMode( osg::State &state ) + { + int x = 0, y = 0, w = 1, h = 1; + if( viewport != NULL ) + viewport->getViewport( x, y, w, h ); + float vx = x; + float vy = y; + float vw = w; + float vh = h; + + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + glOrtho( 0.0, vw, 0.0, vh, -1.0, 1.0 ); + + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); + + vector ::iterator p; + float th = 0.0; + for( p = logos[Center].begin(); p != logos[Center].end(); p++ ) + th += (*p)->t(); + + float place[][4] = { + { vw*0.5, ((vh*0.5) + th*0.5), -0.5, -1.0 }, + { vx, vh, 0.0, -1.0 }, + { vw, vh, -1.0, -1.0 }, + { vx, vy, 0.0, 1.0 }, + { vw, vy, -1.0, 1.0 }, + { vw*0.5, vh , -0.5, -1.0 }, + { vw*0.5, 0.0 , -0.5, 1.0 }, + }; + + for( int i = Center; i < last_position; i++ ) + { + if( logos[i].size() != 0 ) + { + float x = place[i][0]; + float y = place[i][1]; + float xi = place[i][2]; + float yi = place[i][3]; + for( p = logos[i].begin(); p != logos[i].end(); p++ ) + { + osg::Image *img = *p; + x = place[i][0] + xi * img->s(); + if( i == Center || i == UpperLeft || i == UpperRight || i == UpperCenter) + y += yi * img->t(); + glRasterPos2f( x, y ); + glDrawPixels( img->s(), img->t(), img->getPixelFormat(), img->getDataType(), img->data() ); + if( i == LowerLeft || i == LowerRight || i == LowerCenter) + y += yi * img->t(); + } + } + } + + glPopMatrix(); + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + } + + void addLogo( RelativePosition pos, std::string name ) + { + osg::Image *image = osgDB::readImageFile( name.c_str() ); + if( image != NULL ) + logos[pos].push_back( image ); + } + + osg::Viewport *getViewport() { return viewport; } + + protected: + Logos(const Logos&):Drawable() {} + Logos& operator = (const Logos&) { return *this;} + + virtual ~Logos() {} + virtual const bool computeBound() const + { + _bbox.set( -1, -1, -1, 1, 1, 1 ); + return true; + } + private : + vector logos[last_position]; + osg::Viewport *viewport; +}; + + +class LOGOReaderWriter : public osgDB::ReaderWriter +{ +public: + virtual const char* className() { return "Logo Database Reader/Writer"; } + + virtual bool acceptsExtension(const std::string& extension) + { + return osgDB::equalCaseInsensitive(extension,"logo"); + } + + virtual ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options*) + { + std::string ext = osgDB::getLowerCaseFileExtension(fileName); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + osg::notify(osg::INFO)<< "ReaderWriterLOGO::readNode( "<addDrawable( ld ); + + Logos::RelativePosition pos = Logos::LowerRight; + + filebuf fb; + fb.open( fileName.c_str(), "r"); + istream in(&fb); + while( !in.eof() ) + { + std::string str; + in>> str; + + if( str == "Center" ) + pos = Logos::Center; + else if( str == "UpperLeft" ) + pos = Logos::UpperLeft; + else if( str == "UpperRight" ) + pos = Logos::UpperRight; + else if( str == "LowerLeft" ) + pos = Logos::LowerLeft; + else if( str == "LowerRight" ) + pos = Logos::LowerRight; + else if( str == "UpperCenter" ) + pos = Logos::UpperCenter; + else if( str == "LowerCenter" ) + pos = Logos::LowerCenter; + else + ld->addLogo( pos, str ); + } + return geode; + } +}; + + +// now register with Registry to instantiate the above +// reader/writer. + +osgDB::RegisterReaderWriterProxy g_LOGOReaderWriterProxy; +