root/OpenSceneGraph/trunk/examples/osgmemorytest/osgmemorytest.cpp @ 9143

Revision 9143, 14.6 kB (checked in by robert, 6 years ago)

Added --geometry, --geometry-vbo and --geometry-va command line options and associated geometry test codes

Line 
1/* OpenSceneGraph example, osganimate.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19#include <osg/Notify>
20#include <osg/ArgumentParser>
21#include <osg/Texture1D>
22#include <osg/Texture2D>
23#include <osg/Texture3D>
24#include <osg/Geometry>
25
26#include <osgViewer/Viewer>
27
28#include <stdio.h>
29
30class MemoryTest : public osg::Referenced
31{
32    public:
33};
34
35class GLObject : public osg::Referenced
36{
37    public:
38        virtual void apply(osg::RenderInfo& renderInfo) = 0;
39};
40
41class GLMemoryTest : public MemoryTest
42{
43    public:
44        virtual GLObject* allocate() = 0;
45};
46
47/////////////////////////////////////////////////////////////////////////
48//
49// Context test
50class ContextTest : public MemoryTest
51{
52    public:
53        ContextTest(int width, int height, bool pbuffer):
54            _width(width),
55            _height(height),
56            _pbuffer(pbuffer) {}
57       
58        virtual osg::GraphicsContext* allocate()
59        {
60            osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
61            traits->width = _width;
62            traits->height = _height;
63            traits->windowDecoration = true;
64            traits->pbuffer = _pbuffer;
65           
66            osg::ref_ptr<osg::GraphicsContext> window = osg::GraphicsContext::createGraphicsContext(traits.get());
67            if (window.valid())
68            {
69                if (window->realize())
70                {
71                    return window.release();
72                }
73                else
74                {
75                    if (_pbuffer) throw "Failed to realize PixelBuffer";
76                    else  throw "Failed to realize GraphicsWindow";
77                }
78            }
79            else
80            {
81                if (_pbuffer) throw "Failed to create PixelBuffer";
82                else  throw "Failed to create GraphicsWindow";
83            }
84            return 0;
85        }
86       
87
88    protected:
89   
90        int     _width;
91        int     _height;
92        bool    _pbuffer;
93};
94
95////////////////////////////////////////////////////////////////////////
96//
97// Wrap StateAttribute
98class StateAttributeObject : public GLObject
99{
100    public:
101   
102        StateAttributeObject(osg::StateAttribute* sa): _attribute(sa) {}
103       
104        void apply(osg::RenderInfo& renderInfo)
105        {
106            _attribute->apply(*renderInfo.getState());
107           
108            if (renderInfo.getState()->checkGLErrors(_attribute.get()))
109            {
110                throw "OpenGL error";
111            }
112        }
113       
114        osg::ref_ptr<osg::StateAttribute> _attribute;
115};
116
117/////////////////////////////////////////////////////////////////////////
118//
119// Texture test
120class TextureTest : public GLMemoryTest
121{
122    public:
123
124        TextureTest(int width=256, int height=256, int depth=1):
125            _width(width),
126            _height(height),
127            _depth(depth) {}
128       
129        virtual GLObject* allocate()
130        {
131            if (_depth>1)
132            {
133                osg::ref_ptr<osg::Image> image = new osg::Image;
134                image->allocateImage(_width, _height, _depth, GL_RGBA, GL_UNSIGNED_BYTE);
135               
136                osg::ref_ptr<osg::Texture3D> texture = new osg::Texture3D;
137                texture->setImage(image.get());
138                texture->setResizeNonPowerOfTwoHint(false);
139               
140                return new StateAttributeObject(texture.get());
141            }
142            if (_height>1)
143            {
144                osg::ref_ptr<osg::Image> image = new osg::Image;
145                image->allocateImage(_width, _height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
146               
147                osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
148                texture->setImage(image.get());
149                texture->setResizeNonPowerOfTwoHint(false);
150               
151                return new StateAttributeObject(texture.get());
152            }
153            if (_width>1)
154            {
155                osg::ref_ptr<osg::Image> image = new osg::Image;
156                image->allocateImage(_width, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE);
157               
158                osg::ref_ptr<osg::Texture1D> texture = new osg::Texture1D;
159                texture->setImage(image.get());
160                texture->setResizeNonPowerOfTwoHint(false);
161               
162                return new StateAttributeObject(texture.get());
163            }
164            else
165            {
166                throw "Invalid texture size of 0,0,0";
167            }
168            return 0;           
169        }
170       
171
172    protected:
173   
174        int     _width;
175        int     _height;
176        int     _depth;
177};
178
179
180/////////////////////////////////////////////////////////////////////////
181//
182// FrameBufferObject test
183class FboTest : public GLMemoryTest
184{
185    public:
186
187        FboTest(int width=1024, int height=1024, int depth=2):
188            _width(width),
189            _height(height),
190            _depth(depth) {}
191       
192        virtual GLObject* allocate()
193        {
194            osg::ref_ptr<osg::FrameBufferObject> fbo = new osg::FrameBufferObject;
195
196            if (_depth>=1) fbo->setAttachment(osg::Camera::COLOR_BUFFER, osg::FrameBufferAttachment(new osg::RenderBuffer(_width, _height, GL_RGBA)));
197            if (_depth>=2) fbo->setAttachment(osg::Camera::DEPTH_BUFFER, osg::FrameBufferAttachment(new osg::RenderBuffer(_width, _height, GL_DEPTH_COMPONENT24)));
198
199            return new StateAttributeObject(fbo.get());
200        }
201       
202
203    protected:
204   
205        int     _width;
206        int     _height;
207        int     _depth;
208};
209
210
211
212////////////////////////////////////////////////////////////////////////
213//
214// Wrap Drawable
215class DrawableObject : public GLObject
216{
217    public:
218   
219        DrawableObject(osg::Drawable* drawable): _drawable(drawable) {}
220       
221        void apply(osg::RenderInfo& renderInfo)
222        {
223            _drawable->draw(renderInfo);
224           
225            if (renderInfo.getState()->checkGLErrors("Drawable"))
226            {
227                throw "OpenGL error";
228            }
229        }
230       
231        osg::ref_ptr<osg::Drawable> _drawable;
232};
233
234/////////////////////////////////////////////////////////////////////////
235//
236// Geometry test
237class GeometryTest : public GLMemoryTest
238{
239    public:
240   
241        enum GLObjectType
242        {
243            VERTEX_ARRAY,
244            DISPLAY_LIST,
245            VERTEX_BUFFER_OBJECT
246        };
247   
248
249        GeometryTest(GLObjectType type, int width=64, int height=64):
250            _glObjectType(type),
251            _width(width),
252            _height(height) {}
253       
254        virtual GLObject* allocate()
255        {
256            unsigned int numVertices = _width * _height;
257            osg::Vec3Array* vertices = new osg::Vec3Array(numVertices);
258            for(unsigned int j=0; j<_height; ++j)
259            {
260                for(unsigned i=0; i<_width; ++i)
261                {
262                    (*vertices)[i+j*_width].set(float(i),float(j),0.0f);
263                }
264            }
265
266            unsigned int numIndices = (_width-1) * (_height-1) * 4;
267            osg::DrawElementsUShort* quads = new osg::DrawElementsUShort(GL_QUADS);
268            quads->reserve(numIndices);
269            for(unsigned int j=0; j<_height-1; ++j)
270            {
271                for(unsigned i=0; i<_width-1; ++i)
272                {
273                    quads->push_back(i   + j*_width);
274                    quads->push_back(i+1 + j*_width);
275                    quads->push_back(i+1 + (j+1)*_width);
276                    quads->push_back(i   + (j+1)*_width);
277                }
278            }
279           
280            osg::Geometry* geometry = new osg::Geometry;
281            geometry->setVertexArray(vertices);
282            geometry->addPrimitiveSet(quads);
283           
284            switch(_glObjectType)
285            {
286                case(VERTEX_ARRAY):
287                    geometry->setUseDisplayList(false);
288                    geometry->setUseVertexBufferObjects(false);
289                    break;
290                case(DISPLAY_LIST):
291                    geometry->setUseDisplayList(true);
292                    geometry->setUseVertexBufferObjects(false);
293                    break;
294                case(VERTEX_BUFFER_OBJECT):
295                    geometry->setUseDisplayList(false);
296                    geometry->setUseVertexBufferObjects(true);
297                    break;
298            }
299
300            return new DrawableObject(geometry);
301        }
302       
303
304    protected:
305   
306        GLObjectType    _glObjectType;
307        int             _width;
308        int             _height;
309};
310
311int main( int argc, char **argv )
312{
313    osg::ArgumentParser arguments(&argc,argv);
314   
315    typedef std::list< osg::ref_ptr<MemoryTest> > Tests;
316    Tests tests;
317   
318    int width, height, depth;
319    while(arguments.read("--pbuffer",width,height)) { tests.push_back(new ContextTest(width, height, true)); }
320    while(arguments.read("--pbuffer")) { tests.push_back(new ContextTest(512, 512, true)); }
321
322    while(arguments.read("--window",width,height)) { tests.push_back(new ContextTest(width, height, false)); }
323    while(arguments.read("--window")) { tests.push_back(new ContextTest(512,512, false)); }
324
325    while(arguments.read("--texture",width,height,depth)) { tests.push_back(new TextureTest(width,height,depth)); }
326    while(arguments.read("--texture",width,height)) { tests.push_back(new TextureTest(width,height,1)); }
327    while(arguments.read("--texture",width)) { tests.push_back(new TextureTest(width,1,1)); }
328
329    while(arguments.read("--fbo",width,height,depth)) { tests.push_back(new FboTest(width,height,depth)); }
330    while(arguments.read("--fbo",width,height)) { tests.push_back(new FboTest(width,height,2)); }
331    while(arguments.read("--fbo")) { tests.push_back(new FboTest(1024,1024,2)); }
332
333    while(arguments.read("--geometry",width,height)) { tests.push_back(new GeometryTest(GeometryTest::DISPLAY_LIST,width,height)); }
334    while(arguments.read("--geometry")) { tests.push_back(new GeometryTest(GeometryTest::DISPLAY_LIST,64,64)); }
335
336    while(arguments.read("--geometry-vbo",width,height)) { tests.push_back(new GeometryTest(GeometryTest::VERTEX_BUFFER_OBJECT,width,height)); }
337    while(arguments.read("--geometry-vbo")) { tests.push_back(new GeometryTest(GeometryTest::VERTEX_BUFFER_OBJECT,64,64)); }
338
339    while(arguments.read("--geometry-va",width,height)) { tests.push_back(new GeometryTest(GeometryTest::VERTEX_ARRAY,width,height)); }
340    while(arguments.read("--geometry-va")) { tests.push_back(new GeometryTest(GeometryTest::VERTEX_ARRAY,64,64)); }
341
342    unsigned int sleepTime = 0;
343    while(arguments.read("--delay",sleepTime)) {}
344
345    int maxNumContextIterations = 1;
346    while(arguments.read("-c",maxNumContextIterations)) {}
347
348    int maxNumGLIterations = 1000;
349    while(arguments.read("-g",maxNumGLIterations)) {}
350
351    typedef std::list< osg::ref_ptr<GLMemoryTest> > GLMemoryTests;
352    typedef std::list< osg::ref_ptr<ContextTest> > ContextTests;
353
354   
355    ContextTests contextTests;
356    GLMemoryTests glMemoryTests;
357   
358    for(Tests::iterator itr = tests.begin();
359        itr != tests.end();
360        ++itr)
361    {
362        MemoryTest* test = itr->get();
363        if (dynamic_cast<GLMemoryTest*>(test)!=0)
364        {
365            glMemoryTests.push_back(dynamic_cast<GLMemoryTest*>(test));
366        }
367        else if (dynamic_cast<ContextTest*>(test)!=0)
368        {
369            contextTests.push_back(dynamic_cast<ContextTest*>(test));
370        }
371    }
372
373    typedef std::list< osg::ref_ptr<osg::GraphicsContext> > Contexts;
374    typedef std::list< osg::ref_ptr<GLObject> > GLObjects;
375    Contexts allocatedContexts;
376    GLObjects glObjects;
377
378    int numContextIterations = 0;
379    int numGLObjectIterations = 0;
380    int numGLObjectsApplied = 0;
381    try
382    {
383        for(; numGLObjectIterations<maxNumGLIterations; ++numGLObjectIterations)
384        {   
385            for(GLMemoryTests::iterator itr = glMemoryTests.begin();
386                itr != glMemoryTests.end();
387                ++itr)
388            {
389                osg::ref_ptr<GLObject> glObject = (*itr)->allocate();
390                if (glObject.valid()) glObjects.push_back(glObject.get());
391            }
392        }
393       
394        for(;numContextIterations<maxNumContextIterations; ++numContextIterations)
395        {
396            printf("iteration %i\n",numContextIterations);
397            for(ContextTests::iterator itr = contextTests.begin();
398                itr != contextTests.end();
399                ++itr)
400            {
401                osg::ref_ptr<osg::GraphicsContext> context = (*itr)->allocate();
402                if (context.valid())
403                {
404                    allocatedContexts.push_back(context);
405
406                    context->makeCurrent();
407                   
408                    osg::RenderInfo renderInfo;
409                    renderInfo.setState(context->getState());
410                   
411                    for(GLObjects::iterator gitr = glObjects.begin();
412                        gitr != glObjects.end();
413                        ++gitr)
414                    {
415                        if (sleepTime>0) OpenThreads::Thread::microSleep( sleepTime );
416
417                        printf("%i ",numGLObjectsApplied);fflush(stdout);
418
419                        (*gitr)->apply(renderInfo);
420                        ++numGLObjectsApplied;
421                    }
422                   
423                    context->releaseContext();
424                    printf("\n\n"); fflush(stdout);
425                }
426            }
427        }
428    }
429    catch(const char* errorString)
430    {
431        printf("\nException caught, contexts completed = %i, gl objects successfully applied =%i, error = %s\n\n",numContextIterations, numGLObjectsApplied, errorString);
432        return 1;
433    }
434    catch(...)
435    {
436        printf("\nException caught, contexts completed = %i, gl objects successfully applied =%i\n\n",numContextIterations, numGLObjectsApplied);
437        return 1;
438    }
439
440    printf("\nSuccessful completion, contexts created = %i, gl objects applied =%i\n\n",numContextIterations, numGLObjectsApplied);
441   
442    return 0;
443}
Note: See TracBrowser for help on using the browser.