root/OpenSceneGraph/trunk/src/osgPlugins/logo/ReaderWriterLOGO.cpp @ 9550

Revision 9550, 10.3 kB (checked in by robert, 9 years ago)

Converted across to using ref_ptr<> to avoid memory leak/dangling pointer issues.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[1782]1#include <stdio.h>
2#include <osg/Geode>
3#include <osg/Drawable>
4#include <osg/BlendFunc>
5#include <osg/StateSet>
6#include <osg/Notify>
7#include <osg/Viewport>
8
9#include <osgDB/ReadFile>
10#include <osgDB/FileUtils>
11#include <osgDB/FileNameUtils>
12#include <osgDB/Registry>
13#include <osgDB/Input>
14#include <osgDB/Output>
15
16#include <osgUtil/CullVisitor>
17
18using namespace osg;
19using namespace osgDB;
20
21
22class Logos: public osg::Drawable
23{
24    public:
25        enum RelativePosition{
[4514]26            Center,
27            UpperLeft,
28            UpperRight,
29            LowerLeft,
30            LowerRight,
31            UpperCenter,
32            LowerCenter,
33            last_position
[1782]34        };
35
[4514]36        struct logosCullCallback : public osg::Drawable::CullCallback
37        {
[1782]38            virtual bool cull(osg::NodeVisitor *visitor, osg::Drawable* drawable, osg::State*) const
[4514]39            {
40                Logos *logos = dynamic_cast <Logos *>(drawable);
41                osgUtil::CullVisitor *cv = dynamic_cast<osgUtil::CullVisitor *>(visitor);
42                if( logos != NULL && cv != NULL )
43                {
44                    osg::Viewport *vp = cv->getViewport();
45                    if( vp != NULL )
46                    {
[5863]47                        if( vp->width() != logos->getViewport()->width() ||
48                            vp->height() != logos->getViewport()->height() )
[4514]49                        {
[5863]50                            logos->getViewport()->setViewport( vp->x(), vp->y(), vp->width(), vp->height() );
[4514]51                            logos->dirtyDisplayList();
52                        }
53                    }
54                }
55                return false;
56            }
57        };
[1782]58
[4514]59        Logos()
60        {
61            osg::StateSet *sset = new osg::StateSet;
62            osg::BlendFunc *transp = new osg::BlendFunc;
63            transp->setFunction(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
64            sset->setAttribute( transp );
65            sset->setMode( GL_BLEND, osg::StateAttribute::ON );
66            sset->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF );
67            sset->setTextureMode( 0, GL_TEXTURE_2D, osg::StateAttribute::OFF );
[4704]68#if 1           
69            // for now we'll crudely set the bin number to 100 to force it to draw later and ontop of the scene
70            sset->setRenderBinDetails( 100 , "RenderBin" );
71#else
[4514]72            sset->setRenderBinDetails( StateSet::TRANSPARENT_BIN + 1 , "RenderBin" );
[4704]73#endif
[4514]74            setStateSet( sset );
[9550]75            _viewport = new osg::Viewport;
[4514]76            setCullCallback( new logosCullCallback );
77            _contextID = 0;
78        }
[1782]79
80        Logos(const Logos& logo, const CopyOp& copyop=CopyOp::SHALLOW_COPY) :Drawable( logo, copyop ) {}
[1798]81
[1782]82        virtual Object* cloneType() const { return new Logos(); }
83        virtual Object* clone( const CopyOp& copyop) const { return new Logos(*this, copyop ); }
84        virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Logos*>(obj)!=NULL; }
85        virtual const char* className() const { return "Logos"; }
86
[6422]87        virtual void drawImplementation(osg::RenderInfo& renderInfo) const
[4514]88        {
[6422]89            if( renderInfo.getContextID() != _contextID )
[4514]90                return;
[1782]91
92
[5863]93            float vx = 0.0;
94            float vy = 0.0;
95            float vw = 1.0;
96            float vh = 1.0;
[9550]97            if (_viewport.valid())
[5863]98            {
[9550]99                vx = _viewport->x();
100                vy = _viewport->y();
101                vw = _viewport->width();
102                vh = _viewport->height();
[5863]103            }
104
[4514]105            glMatrixMode( GL_PROJECTION );
[1782]106            glPushMatrix();
107            glLoadIdentity();
[4514]108            glOrtho( 0.0, vw, 0.0, vh, -1.0, 1.0 );
[1782]109
[4514]110            glMatrixMode( GL_MODELVIEW );
111            glPushMatrix();
112            glLoadIdentity();
[1782]113
[4514]114            glColor4f( 1, 1, 1, 1 );
[1782]115
[9550]116            Images::const_iterator p;
[4514]117            float th = 0.0;
[9550]118            for( p = _logos[Center].begin(); p != _logos[Center].end(); p++ )
119            {
[4514]120                th += (*p)->t();
[9550]121            }
[1782]122
[4514]123            float place[][4] = {
124                { vw*0.5, ((vh*0.5) + th*0.5), -0.5, -1.0 },
125                { vx, vh, 0.0, -1.0 },
126                { vw, vh, -1.0, -1.0 },
127                { vx, vy, 0.0, 1.0 },
128                { vw, vy, -1.0, 1.0 },
129                { vw*0.5, vh , -0.5, -1.0 },
130                { vw*0.5, 0.0 , -0.5, 1.0 },
131            };
[1782]132
[4514]133            for( int i = Center; i < last_position; i++ )
134            {
[9550]135                if( _logos[i].size() != 0 )
[4514]136                {
137                    float x = place[i][0];
138                    float y = place[i][1];
139                    float xi = place[i][2];
140                    float yi = place[i][3];
[9550]141                    for( p = _logos[i].begin(); p != _logos[i].end(); p++ )
[4514]142                    {
143                        osg::Image *img = *p;
144                        x = place[i][0] + xi * img->s();
145                        if( i == Center || i == UpperLeft || i == UpperRight || i == UpperCenter)
146                            y += yi * img->t();
147                        glRasterPos2f( x, y );
148                        glDrawPixels( img->s(), img->t(), img->getPixelFormat(), img->getDataType(), img->data() );
149                        if( i == LowerLeft || i == LowerRight || i == LowerCenter)
150                            y += yi * img->t();
151                    }
152                }
153            }
[1782]154
[4514]155            glPopMatrix();
156            glMatrixMode( GL_PROJECTION );
157            glPopMatrix();
158            glMatrixMode( GL_MODELVIEW );
159        }
[1782]160
[4514]161        void addLogo( RelativePosition pos, std::string name )
162        {
[9527]163            osg::ref_ptr<osg::Image> image = osgDB::readRefImageFile( name.c_str() );
164            if( image.valid())
[9550]165                _logos[pos].push_back( image );
[8418]166            else
167                osg::notify(osg::WARN)<< "Logos::addLogo image file not found : " << name << ".\n";
[4514]168        }
[1782]169
[9550]170        osg::Viewport *getViewport() { return _viewport.get(); }
[4514]171        void setContextID( unsigned int id ) { _contextID = id; }
[1782]172
[4514]173        bool hasLogos()
174        {
175            int n = 0;
[9397]176            for( int i = Center; i < last_position; i++ )
[9550]177                n += _logos[i].size();
[4514]178            return (n != 0);
179        }
[1782]180
[4202]181        virtual osg::BoundingBox computeBound() const 
[4514]182        {
183            return osg::BoundingBox( -1, -1, -1, 1, 1, 1);
[4202]184        }
185
[1782]186    protected:
187        Logos& operator = (const Logos&) { return *this;}
188
189        virtual ~Logos() {}
190    private :
[9550]191        typedef std::vector < osg::ref_ptr<osg::Image> >  Images;
192
193        Images _logos[last_position];
194        osg::ref_ptr<osg::Viewport> _viewport;
[4514]195        unsigned int _contextID;
[1782]196};
197
198
199class LOGOReaderWriter : public osgDB::ReaderWriter
200{
[4514]201    public:
[8578]202        LOGOReaderWriter()
[1782]203        {
[8578]204            supportsExtension("logo","Ascii logo placement format");
[1782]205        }
[8578]206       
207        virtual const char* className() const { return "Logo Database Reader/Writer"; }
[1782]208
[3694]209        virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const
[1782]210        {
[2501]211            std::string ext = osgDB::getLowerCaseFileExtension(file);
[1782]212            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
[2501]213
[3691]214            std::string fileName = osgDB::findDataFile( file, options );
[4514]215            if (fileName.empty())
216                return ReadResult::FILE_NOT_FOUND;
[2501]217
[8418]218            osg::notify(osg::INFO)<< "ReaderWriterLOGO::readNode( "<<fileName.c_str()<<" )\n";
[1782]219
[8418]220            std::string filePath = osgDB::getFilePath(fileName);
221            if (!filePath.empty()) {
222                osg::notify(osg::DEBUG_INFO)<< "Adding : " << filePath << " to the file data path\n";
223                osgDB::getDataFilePathList().push_back(filePath);
224            }
225
226
[4514]227            osg::Geode *geode = new osg::Geode;
[1782]228
[4514]229            unsigned int screen = 0;
[1782]230
[4514]231            Logos* ld = new Logos;
232            ld->setContextID( screen );
[1782]233
[4514]234            Logos::RelativePosition pos = Logos::LowerRight;
[1782]235
[4514]236            FILE *fp;
[9124]237            if( (fp = osgDB::fopen( fileName.c_str(), "r")) == NULL )
[4514]238                return NULL;
239            while( !feof(fp))
240            {
241                char buff[128];
[1782]242
[4514]243                if( fscanf( fp, "%s", buff ) != 1 )
244                    break;
[1782]245
[4514]246                std::string str(buff);
[1782]247
[4514]248                if( str == "Center" )
249                    pos = Logos::Center;
250                else if( str == "UpperLeft" )
251                    pos = Logos::UpperLeft;
252                else if( str == "UpperRight" )
253                    pos = Logos::UpperRight;
254                else if( str == "LowerLeft" )
255                    pos = Logos::LowerLeft;
256                else if( str == "LowerRight" )
257                    pos = Logos::LowerRight;
258                else if( str == "UpperCenter" )
259                    pos = Logos::UpperCenter;
260                else if( str == "LowerCenter" )
261                    pos = Logos::LowerCenter;
262                else if( str == "Camera" )
263                {
[7375]264                    int tn;
265                    if( (fscanf( fp, "%d", &tn )) != 1 )
[4514]266                    {
267                        osg::notify(osg::WARN) << "Error... Camera requires an integer argument\n";
268                        break;
269                    }
[7375]270                   
271                    if (tn < 0)
272                    {
273                        osg::notify(osg::WARN) << "Error... Camera requires an positive or null value argument\n";
274                        break;
275                    }
276                   
277                    unsigned int n = static_cast<unsigned int>(tn);
[4514]278                    if( screen != n )
279                    {
280                        screen = n;
281                        if( ld->hasLogos() )
282                        {
283                        geode->addDrawable( ld );
284                        ld = new Logos;
285                        ld->setContextID( screen );
286                    }
287                    else
288                        ld->setContextID( screen );
289                    }
290                }
291                else
292                {
293                    if( str.length() )
294                    ld->addLogo( pos, str );
295                }
296            }
297            fclose( fp );
298       
299            if( ld->hasLogos() )
300                geode->addDrawable( ld );
301       
302            geode->setCullingActive(false);
303            return geode;
304        }
[1782]305};
306
307
308// now register with Registry to instantiate the above
309// reader/writer.
[7076]310REGISTER_OSGPLUGIN(logo, LOGOReaderWriter)
Note: See TracBrowser for help on using the browser.