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

Revision 13041, 11.0 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

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