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

Revision 11516, 10.9 kB (checked in by robert, 4 years ago)

Converted osg::notify to OSG_INFO etc.

  • 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                        x = place[i][0] + xi * img->s();
156                        if( i == Center || i == UpperLeft || i == UpperRight || i == UpperCenter)
157                            y += yi * img->t();
158                        glRasterPos2f( x, y );
159                        glDrawPixels( img->s(), img->t(), img->getPixelFormat(), img->getDataType(), img->data() );
160                        if( i == LowerLeft || i == LowerRight || i == LowerCenter)
161                            y += yi * img->t();
162                    }
163                }
164            }
165
166            glPopMatrix();
167            glMatrixMode( GL_PROJECTION );
168            glPopMatrix();
169            glMatrixMode( GL_MODELVIEW );           
170        #else
171            OSG_NOTICE<<"Warning: Logos::drawImplementation(..) not supported."<<std::endl;
172        #endif
173        }
174
175        void addLogo( RelativePosition pos, std::string name )
176        {
177            osg::ref_ptr<osg::Image> image = osgDB::readRefImageFile( name.c_str() );
178            if( image.valid())
179            {
180                _logos[pos].push_back( image );
181            }
182            else
183            {
184                OSG_WARN<< "Logos::addLogo image file not found : " << name << ".\n";
185            }
186        }
187
188        osg::Viewport *getViewport() { return _viewport.get(); }
189
190        void setContextID( unsigned int id ) { _contextID = id; }
191        unsigned int getContextID() { return _contextID; }
192
193        bool hasLogos()
194        {
195            int n = 0;
196            for( int i = Center; i < last_position; i++ )
197                n += _logos[i].size();
198            return (n != 0);
199        }
200
201        virtual osg::BoundingBox computeBound() const 
202        {
203            return osg::BoundingBox( -1, -1, -1, 1, 1, 1);
204        }
205
206    protected:
207        Logos& operator = (const Logos&) { return *this;}
208
209        virtual ~Logos() {}
210    private :
211        typedef std::vector < osg::ref_ptr<osg::Image> >  Images;
212
213        Images _logos[last_position];
214        osg::ref_ptr<osg::Viewport> _viewport;
215        unsigned int _contextID;
216};
217
218
219class LOGOReaderWriter : public osgDB::ReaderWriter
220{
221    public:
222        LOGOReaderWriter()
223        {
224            supportsExtension("logo","Ascii logo placement format");
225        }
226       
227        virtual const char* className() const { return "Logo Database Reader/Writer"; }
228
229        virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const
230        {
231            std::string ext = osgDB::getLowerCaseFileExtension(file);
232            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
233
234            std::string fileName = osgDB::findDataFile( file, options );
235            if (fileName.empty())
236                return ReadResult::FILE_NOT_FOUND;
237
238            OSG_INFO<< "ReaderWriterLOGO::readNode( "<<fileName.c_str()<<" )\n";
239
240            std::string filePath = osgDB::getFilePath(fileName);
241            if (!filePath.empty()) {
242                OSG_DEBUG<< "Adding : " << filePath << " to the file data path\n";
243                osgDB::getDataFilePathList().push_back(filePath);
244            }
245
246
247            osg::Geode *geode = new osg::Geode;
248
249            unsigned int screen = 0;
250
251            Logos* ld = new Logos;
252            ld->setContextID( screen );
253
254            Logos::RelativePosition pos = Logos::LowerRight;
255
256            FILE *fp;
257            if( (fp = osgDB::fopen( fileName.c_str(), "r")) == NULL )
258                return NULL;
259            while( !feof(fp))
260            {
261                char buff[128];
262
263                if( fscanf( fp, "%s", buff ) != 1 )
264                    break;
265
266                std::string str(buff);
267
268                if( str == "Center" )
269                    pos = Logos::Center;
270                else if( str == "UpperLeft" )
271                    pos = Logos::UpperLeft;
272                else if( str == "UpperRight" )
273                    pos = Logos::UpperRight;
274                else if( str == "LowerLeft" )
275                    pos = Logos::LowerLeft;
276                else if( str == "LowerRight" )
277                    pos = Logos::LowerRight;
278                else if( str == "UpperCenter" )
279                    pos = Logos::UpperCenter;
280                else if( str == "LowerCenter" )
281                    pos = Logos::LowerCenter;
282                else if( str == "Camera" )
283                {
284                    int tn;
285                    if( (fscanf( fp, "%d", &tn )) != 1 )
286                    {
287                        OSG_WARN << "Error... Camera requires an integer argument\n";
288                        break;
289                    }
290                   
291                    if (tn < 0)
292                    {
293                        OSG_WARN << "Error... Camera requires an positive or null value argument\n";
294                        break;
295                    }
296                   
297                    unsigned int n = static_cast<unsigned int>(tn);
298                    if( screen != n )
299                    {
300                        screen = n;
301                        if( ld->hasLogos() )
302                        {
303                        geode->addDrawable( ld );
304                        ld = new Logos;
305                        ld->setContextID( screen );
306                    }
307                    else
308                        ld->setContextID( screen );
309                    }
310                }
311                else
312                {
313                    if( str.length() )
314                    ld->addLogo( pos, str );
315                }
316            }
317            fclose( fp );
318       
319            if( ld->hasLogos() )
320                geode->addDrawable( ld );
321       
322            geode->setCullingActive(false);
323            return geode;
324        }
325};
326
327
328// now register with Registry to instantiate the above
329// reader/writer.
330REGISTER_OSGPLUGIN(logo, LOGOReaderWriter)
Note: See TracBrowser for help on using the browser.