Added Logos loader

This commit is contained in:
Don BURNS
2002-07-14 21:49:51 +00:00
parent 8883f1d571
commit 523b64ef3f
2 changed files with 237 additions and 0 deletions

View File

@@ -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

View File

@@ -0,0 +1,224 @@
#include <stdio.h>
#include <osg/Geode>
#include <osg/Drawable>
#include <osg/BlendFunc>
#include <osg/StateSet>
#include <osg/Notify>
#include <osg/Viewport>
#include <osgDB/ReadFile>
#include <osgDB/FileUtils>
#include <osgDB/FileNameUtils>
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>
#include <osgUtil/CullVisitor>
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 <Logos *>(drawable);
osgUtil::CullVisitor *cv = dynamic_cast<osgUtil::CullVisitor *>(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<const Logos*>(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 <osg::Image *>::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 <osg::Image *> 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( "<<fileName.c_str()<<" )\n";
osg::Geode *geode = new osg::Geode;
Logos* ld = new Logos;
geode->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<LOGOReaderWriter> g_LOGOReaderWriterProxy;