root/OpenSceneGraph/trunk/examples/osgdistortion/osgdistortion.cpp @ 13802

Revision 13574, 26.6 kB (checked in by robert, 15 hours ago)

From Jason Beverage, "It looks like the Callback header got accidentally removed from the CMakeLists.txt in the submission yesterday for the geometry instancing example."

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osgdistortion.
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/GLExtensions>
20#include <osg/Node>
21#include <osg/Geometry>
22#include <osg/Notify>
23#include <osg/MatrixTransform>
24#include <osg/Texture2D>
25#include <osg/Stencil>
26#include <osg/ColorMask>
27#include <osg/Depth>
28#include <osg/Billboard>
29#include <osg/Material>
30#include <osg/Projection>
31#include <osg/TextureCubeMap>
32#include <osg/io_utils>
33
34
35#include <osgGA/TrackballManipulator>
36#include <osgGA/FlightManipulator>
37#include <osgGA/DriveManipulator>
38#include <osgGA/KeySwitchMatrixManipulator>
39#include <osgGA/StateSetManipulator>
40#include <osgGA/AnimationPathManipulator>
41#include <osgGA/TerrainManipulator>
42
43#include <osgUtil/SmoothingVisitor>
44
45#include <osgDB/Registry>
46#include <osgDB/ReadFile>
47
48#include <osgViewer/Viewer>
49#include <osgViewer/ViewerEventHandlers>
50
51#include <iostream>
52
53using namespace osg;
54
55osg::Node* createDistortionSubgraph(osg::Node* subgraph, const osg::Vec4& clearColour)
56{
57    osg::Group* distortionNode = new osg::Group;
58
59    unsigned int tex_width = 1024;
60    unsigned int tex_height = 1024;
61
62    osg::Texture2D* texture = new osg::Texture2D;
63    texture->setTextureSize(tex_width, tex_height);
64    texture->setInternalFormat(GL_RGBA);
65    texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
66    texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
67
68    // set up the render to texture camera.
69    {
70        osg::Camera* camera = new osg::Camera;
71
72        // set clear the color and depth buffer
73        camera->setClearColor(clearColour);
74        camera->setClearMask(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
75
76        // just inherit the main cameras view
77        camera->setReferenceFrame(osg::Transform::RELATIVE_RF);
78        camera->setProjectionMatrix(osg::Matrixd::identity());
79        camera->setViewMatrix(osg::Matrixd::identity());
80
81        // set viewport
82        camera->setViewport(0,0,tex_width,tex_height);
83
84        // set the camera to render before the main camera.
85        camera->setRenderOrder(osg::Camera::PRE_RENDER);
86
87        // tell the camera to use OpenGL frame buffer object where supported.
88        camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
89
90        // attach the texture and use it as the color buffer.
91        camera->attach(osg::Camera::COLOR_BUFFER, texture);
92
93        // add subgraph to render
94        camera->addChild(subgraph);
95
96        distortionNode->addChild(camera);
97   }
98
99    // set up the hud camera
100    {
101        // create the quad to visualize.
102        osg::Geometry* polyGeom = new osg::Geometry();
103
104        polyGeom->setSupportsDisplayList(false);
105
106        osg::Vec3 origin(0.0f,0.0f,0.0f);
107        osg::Vec3 xAxis(1.0f,0.0f,0.0f);
108        osg::Vec3 yAxis(0.0f,1.0f,0.0f);
109        float height = 1024.0f;
110        float width = 1280.0f;
111        int noSteps = 50;
112
113        osg::Vec3Array* vertices = new osg::Vec3Array;
114        osg::Vec2Array* texcoords = new osg::Vec2Array;
115        osg::Vec4Array* colors = new osg::Vec4Array;
116
117        osg::Vec3 bottom = origin;
118        osg::Vec3 dx = xAxis*(width/((float)(noSteps-1)));
119        osg::Vec3 dy = yAxis*(height/((float)(noSteps-1)));
120
121        osg::Vec2 bottom_texcoord(0.0f,0.0f);
122        osg::Vec2 dx_texcoord(1.0f/(float)(noSteps-1),0.0f);
123        osg::Vec2 dy_texcoord(0.0f,1.0f/(float)(noSteps-1));
124
125        int i,j;
126        for(i=0;i<noSteps;++i)
127        {
128            osg::Vec3 cursor = bottom+dy*(float)i;
129            osg::Vec2 texcoord = bottom_texcoord+dy_texcoord*(float)i;
130            for(j=0;j<noSteps;++j)
131            {
132                vertices->push_back(cursor);
133                texcoords->push_back(osg::Vec2((sin(texcoord.x()*osg::PI-osg::PI*0.5)+1.0f)*0.5f,(sin(texcoord.y()*osg::PI-osg::PI*0.5)+1.0f)*0.5f));
134                colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
135
136                cursor += dx;
137                texcoord += dx_texcoord;
138            }
139        }
140
141        // pass the created vertex array to the points geometry object.
142        polyGeom->setVertexArray(vertices);
143
144        polyGeom->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
145
146        polyGeom->setTexCoordArray(0,texcoords);
147
148
149        for(i=0;i<noSteps-1;++i)
150        {
151            osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::QUAD_STRIP);
152            for(j=0;j<noSteps;++j)
153            {
154                elements->push_back(j+(i+1)*noSteps);
155                elements->push_back(j+(i)*noSteps);
156            }
157            polyGeom->addPrimitiveSet(elements);
158        }
159
160
161        // new we need to add the texture to the Drawable, we do so by creating a
162        // StateSet to contain the Texture StateAttribute.
163        osg::StateSet* stateset = polyGeom->getOrCreateStateSet();
164        stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON);
165        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
166
167        osg::Geode* geode = new osg::Geode();
168        geode->addDrawable(polyGeom);
169
170        // set up the camera to render the textured quad
171        osg::Camera* camera = new osg::Camera;
172
173        // just inherit the main cameras view
174        camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
175        camera->setViewMatrix(osg::Matrix::identity());
176        camera->setProjectionMatrixAsOrtho2D(0,1280,0,1024);
177
178        // set the camera to render before the main camera.
179        camera->setRenderOrder(osg::Camera::NESTED_RENDER);
180
181        // add subgraph to render
182        camera->addChild(geode);
183
184        distortionNode->addChild(camera);
185    }
186    return distortionNode;
187}
188
189void setDomeFaces(osgViewer::Viewer& viewer, osg::ArgumentParser& arguments)
190{
191
192    osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
193    if (!wsi)
194    {
195        osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
196        return;
197    }
198
199    unsigned int width, height;
200    wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
201
202    while (arguments.read("--width",width)) {}
203    while (arguments.read("--height",height)) {}
204
205    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
206    traits->x = 0;
207    traits->y = 0;
208    traits->width = width;
209    traits->height = height;
210    traits->windowDecoration = true;
211    traits->doubleBuffer = true;
212    traits->sharedContext = 0;
213
214    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
215    if (!gc)
216    {
217        osg::notify(osg::NOTICE)<<"GraphicsWindow has not been created successfully."<<std::endl;
218        return;
219    }
220
221
222    int center_x = width/2;
223    int center_y = height/2;
224    int camera_width = 256;
225    int camera_height = 256;
226
227    // front face
228    {
229        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
230        camera->setGraphicsContext(gc.get());
231        camera->setViewport(new osg::Viewport(center_x-camera_width/2, center_y, camera_width, camera_height));
232
233        GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
234        camera->setDrawBuffer(buffer);
235        camera->setReadBuffer(buffer);
236
237        viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd());
238    }
239
240    // top face
241    {
242        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
243        camera->setGraphicsContext(gc.get());
244        camera->setViewport(new osg::Viewport(center_x-camera_width/2, center_y+camera_height, camera_width, camera_height));
245        GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
246        camera->setDrawBuffer(buffer);
247        camera->setReadBuffer(buffer);
248
249        viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(-90.0f), 1.0,0.0,0.0));
250    }
251
252    // left face
253    {
254        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
255        camera->setGraphicsContext(gc.get());
256        camera->setViewport(new osg::Viewport(center_x-camera_width*3/2, center_y, camera_width, camera_height));
257        GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
258        camera->setDrawBuffer(buffer);
259        camera->setReadBuffer(buffer);
260
261        viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(-90.0f), 0.0,1.0,0.0));
262    }
263
264    // right face
265    {
266        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
267        camera->setGraphicsContext(gc.get());
268        camera->setViewport(new osg::Viewport(center_x+camera_width/2, center_y, camera_width, camera_height));
269        GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
270        camera->setDrawBuffer(buffer);
271        camera->setReadBuffer(buffer);
272
273        viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(90.0f), 0.0,1.0,0.0));
274    }
275
276    // bottom face
277    {
278        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
279        camera->setGraphicsContext(gc.get());
280        camera->setViewport(new osg::Viewport(center_x-camera_width/2, center_y-camera_height, camera_width, camera_height));
281        GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
282        camera->setDrawBuffer(buffer);
283        camera->setReadBuffer(buffer);
284
285        viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(90.0f), 1.0,0.0,0.0));
286    }
287
288    // back face
289    {
290        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
291        camera->setGraphicsContext(gc.get());
292        camera->setViewport(new osg::Viewport(center_x-camera_width/2, center_y-2*camera_height, camera_width, camera_height));
293        GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
294        camera->setDrawBuffer(buffer);
295        camera->setReadBuffer(buffer);
296
297        viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(-180.0f), 1.0,0.0,0.0));
298    }
299
300    viewer.getCamera()->setProjectionMatrixAsPerspective(90.0f, 1.0, 1, 1000.0);
301
302    viewer.assignSceneDataToCameras();
303}
304
305osg::Geometry* createDomeDistortionMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector,
306                                        osg::ArgumentParser& arguments)
307{
308    double sphere_radius = 1.0;
309    if (arguments.read("--radius", sphere_radius)) {}
310
311    double collar_radius = 0.45;
312    if (arguments.read("--collar", collar_radius)) {}
313
314    osg::Vec3d center(0.0,0.0,0.0);
315    osg::Vec3d eye(0.0,0.0,0.0);
316
317    double distance = sqrt(sphere_radius*sphere_radius - collar_radius*collar_radius);
318    if (arguments.read("--distance", distance)) {}
319
320    bool centerProjection = false;
321
322    osg::Vec3d projector = eye - osg::Vec3d(0.0,0.0, distance);
323
324
325    osg::notify(osg::NOTICE)<<"Projector position = "<<projector<<std::endl;
326    osg::notify(osg::NOTICE)<<"distance = "<<distance<<std::endl;
327
328
329    // create the quad to visualize.
330    osg::Geometry* geometry = new osg::Geometry();
331
332    geometry->setSupportsDisplayList(false);
333
334    osg::Vec3 xAxis(widthVector);
335    float width = widthVector.length();
336    xAxis /= width;
337
338    osg::Vec3 yAxis(heightVector);
339    float height = heightVector.length();
340    yAxis /= height;
341
342    int noSteps = 50;
343
344    osg::Vec3Array* vertices = new osg::Vec3Array;
345    osg::Vec3Array* texcoords = new osg::Vec3Array;
346    osg::Vec4Array* colors = new osg::Vec4Array;
347
348    osg::Vec3 bottom = origin;
349    osg::Vec3 dx = xAxis*(width/((float)(noSteps-1)));
350    osg::Vec3 dy = yAxis*(height/((float)(noSteps-1)));
351
352    osg::Vec3d screenCenter = origin + widthVector*0.5f + heightVector*0.5f;
353    float screenRadius = heightVector.length() * 0.5f;
354
355    int i,j;
356    if (centerProjection)
357    {
358        for(i=0;i<noSteps;++i)
359        {
360            osg::Vec3 cursor = bottom+dy*(float)i;
361            for(j=0;j<noSteps;++j)
362            {
363                osg::Vec2 delta(cursor.x() - screenCenter.x(), cursor.y() - screenCenter.y());
364                double theta = atan2(-delta.y(), delta.x());
365                double phi = osg::PI_2 * delta.length() / screenRadius;
366                if (phi > osg::PI_2) phi = osg::PI_2;
367
368                phi *= 2.0;
369
370                // osg::notify(osg::NOTICE)<<"theta = "<<theta<< "phi="<<phi<<std::endl;
371
372                osg::Vec3 texcoord(sin(phi) * cos(theta),
373                                   sin(phi) * sin(theta),
374                                   cos(phi));
375
376                vertices->push_back(cursor);
377                colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
378                texcoords->push_back(texcoord);
379
380                cursor += dx;
381            }
382            // osg::notify(osg::NOTICE)<<std::endl;
383        }
384    }
385    else
386    {
387        for(i=0;i<noSteps;++i)
388        {
389            osg::Vec3 cursor = bottom+dy*(float)i;
390            for(j=0;j<noSteps;++j)
391            {
392                osg::Vec2 delta(cursor.x() - screenCenter.x(), cursor.y() - screenCenter.y());
393                double theta = atan2(-delta.y(), delta.x());
394                double phi = osg::PI_2 * delta.length() / screenRadius;
395                if (phi > osg::PI_2) phi = osg::PI_2;
396
397                // osg::notify(osg::NOTICE)<<"theta = "<<theta<< "phi="<<phi<<std::endl;
398
399                double f = distance * sin(phi);
400                double e = distance * cos(phi) + sqrt( sphere_radius*sphere_radius - f*f);
401                double l = e * cos(phi);
402                double h = e * sin(phi);
403                double z = l - distance;
404
405                osg::Vec3 texcoord(h * cos(theta) / sphere_radius,
406                                   h * sin(theta) / sphere_radius,
407                                   z / sphere_radius);
408
409                vertices->push_back(cursor);
410                colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
411                texcoords->push_back(texcoord);
412
413                cursor += dx;
414            }
415            // osg::notify(osg::NOTICE)<<std::endl;
416        }
417    }
418
419    // pass the created vertex array to the points geometry object.
420    geometry->setVertexArray(vertices);
421
422    geometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
423
424    geometry->setTexCoordArray(0,texcoords);
425
426    for(i=0;i<noSteps-1;++i)
427    {
428        osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::QUAD_STRIP);
429        for(j=0;j<noSteps;++j)
430        {
431            elements->push_back(j+(i+1)*noSteps);
432            elements->push_back(j+(i)*noSteps);
433        }
434        geometry->addPrimitiveSet(elements);
435    }
436
437    return geometry;
438}
439
440void setDomeCorrection(osgViewer::Viewer& viewer, osg::ArgumentParser& arguments)
441{
442
443    osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
444    if (!wsi)
445    {
446        osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
447        return;
448    }
449
450    unsigned int width, height;
451    wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
452
453    while (arguments.read("--width",width)) {}
454    while (arguments.read("--height",height)) {}
455
456    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
457    traits->x = 0;
458    traits->y = 0;
459    traits->width = width;
460    traits->height = height;
461    traits->windowDecoration = false;
462    traits->doubleBuffer = true;
463    traits->sharedContext = 0;
464
465
466
467    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
468    if (!gc)
469    {
470        osg::notify(osg::NOTICE)<<"GraphicsWindow has not been created successfully."<<std::endl;
471        return;
472    }
473
474    int tex_width = 512;
475    int tex_height = 512;
476
477    int camera_width = tex_width;
478    int camera_height = tex_height;
479
480    osg::TextureCubeMap* texture = new osg::TextureCubeMap;
481
482    texture->setTextureSize(tex_width, tex_height);
483    texture->setInternalFormat(GL_RGB);
484    texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
485    texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);
486
487#if 0
488    osg::Camera::RenderTargetImplementation renderTargetImplementation = osg::Camera::SEPERATE_WINDOW;
489    GLenum buffer = GL_FRONT;
490#else
491    osg::Camera::RenderTargetImplementation renderTargetImplementation = osg::Camera::FRAME_BUFFER_OBJECT;
492    GLenum buffer = GL_FRONT;
493#endif
494
495    // front face
496    {
497        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
498        camera->setName("Front face camera");
499        camera->setGraphicsContext(gc.get());
500        camera->setViewport(new osg::Viewport(0,0,camera_width, camera_height));
501        camera->setDrawBuffer(buffer);
502        camera->setReadBuffer(buffer);
503        camera->setAllowEventFocus(false);
504        // tell the camera to use OpenGL frame buffer object where supported.
505        camera->setRenderTargetImplementation(renderTargetImplementation);
506
507        // attach the texture and use it as the color buffer.
508        camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, osg::TextureCubeMap::POSITIVE_Y);
509
510        viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd());
511    }
512
513
514    // top face
515    {
516        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
517        camera->setName("Top face camera");
518        camera->setGraphicsContext(gc.get());
519        camera->setViewport(new osg::Viewport(0,0,camera_width, camera_height));
520        GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
521        camera->setDrawBuffer(buffer);
522        camera->setReadBuffer(buffer);
523        camera->setAllowEventFocus(false);
524
525        // tell the camera to use OpenGL frame buffer object where supported.
526        camera->setRenderTargetImplementation(renderTargetImplementation);
527
528        // attach the texture and use it as the color buffer.
529        camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, osg::TextureCubeMap::POSITIVE_Z);
530
531        viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(-90.0f), 1.0,0.0,0.0));
532    }
533
534    // left face
535    {
536        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
537        camera->setName("Left face camera");
538        camera->setGraphicsContext(gc.get());
539        camera->setViewport(new osg::Viewport(0,0,camera_width, camera_height));
540        camera->setDrawBuffer(buffer);
541        camera->setReadBuffer(buffer);
542        camera->setAllowEventFocus(false);
543
544        // tell the camera to use OpenGL frame buffer object where supported.
545        camera->setRenderTargetImplementation(renderTargetImplementation);
546
547        // attach the texture and use it as the color buffer.
548        camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, osg::TextureCubeMap::NEGATIVE_X);
549
550        viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(-90.0f), 0.0,1.0,0.0) * osg::Matrixd::rotate(osg::inDegrees(-90.0f), 0.0,0.0,1.0));
551    }
552
553    // right face
554    {
555        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
556        camera->setName("Right face camera");
557        camera->setGraphicsContext(gc.get());
558        camera->setViewport(new osg::Viewport(0,0,camera_width, camera_height));
559        camera->setDrawBuffer(buffer);
560        camera->setReadBuffer(buffer);
561        camera->setAllowEventFocus(false);
562
563        // tell the camera to use OpenGL frame buffer object where supported.
564        camera->setRenderTargetImplementation(renderTargetImplementation);
565
566        // attach the texture and use it as the color buffer.
567        camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, osg::TextureCubeMap::POSITIVE_X);
568
569        viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(90.0f), 0.0,1.0,0.0 ) * osg::Matrixd::rotate(osg::inDegrees(90.0f), 0.0,0.0,1.0));
570    }
571
572    // bottom face
573    {
574        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
575        camera->setGraphicsContext(gc.get());
576        camera->setName("Bottom face camera");
577        camera->setViewport(new osg::Viewport(0,0,camera_width, camera_height));
578        camera->setDrawBuffer(buffer);
579        camera->setReadBuffer(buffer);
580        camera->setAllowEventFocus(false);
581
582        // tell the camera to use OpenGL frame buffer object where supported.
583        camera->setRenderTargetImplementation(renderTargetImplementation);
584
585        // attach the texture and use it as the color buffer.
586        camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, osg::TextureCubeMap::NEGATIVE_Z);
587
588        viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(90.0f), 1.0,0.0,0.0) * osg::Matrixd::rotate(osg::inDegrees(180.0f), 0.0,0.0,1.0));
589    }
590
591    // back face
592    {
593        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
594        camera->setName("Back face camera");
595        camera->setGraphicsContext(gc.get());
596        camera->setViewport(new osg::Viewport(0,0,camera_width, camera_height));
597        camera->setDrawBuffer(buffer);
598        camera->setReadBuffer(buffer);
599        camera->setAllowEventFocus(false);
600
601        // tell the camera to use OpenGL frame buffer object where supported.
602        camera->setRenderTargetImplementation(renderTargetImplementation);
603
604        // attach the texture and use it as the color buffer.
605        camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, osg::TextureCubeMap::NEGATIVE_Y);
606
607        viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::inDegrees(180.0f), 1.0,0.0,0.0));
608    }
609
610    viewer.getCamera()->setProjectionMatrixAsPerspective(90.0f, 1.0, 1, 1000.0);
611
612
613
614    // distortion correction set up.
615    {
616        osg::Geode* geode = new osg::Geode();
617        geode->addDrawable(createDomeDistortionMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), arguments));
618
619        // new we need to add the texture to the mesh, we do so by creating a
620        // StateSet to contain the Texture StateAttribute.
621        osg::StateSet* stateset = geode->getOrCreateStateSet();
622        stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON);
623        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
624
625        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
626        camera->setGraphicsContext(gc.get());
627        camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
628        camera->setClearColor( osg::Vec4(0.1,0.1,1.0,1.0) );
629        camera->setViewport(new osg::Viewport(0, 0, width, height));
630        GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
631        camera->setDrawBuffer(buffer);
632        camera->setReadBuffer(buffer);
633        camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
634        camera->setAllowEventFocus(false);
635        //camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE);
636        //camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
637
638        camera->setProjectionMatrixAsOrtho2D(0,width,0,height);
639        camera->setViewMatrix(osg::Matrix::identity());
640
641        // add subgraph to render
642        camera->addChild(geode);
643
644        camera->setName("DistortionCorrectionCamera");
645
646        viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd(), false);
647    }
648
649    viewer.getCamera()->setNearFarRatio(0.0001f);
650}
651
652
653int main(int argc, char** argv)
654{
655    // use an ArgumentParser object to manage the program arguments.
656    osg::ArgumentParser arguments(&argc,argv);
657
658    // construct the viewer.
659    osgViewer::Viewer viewer;
660
661    // load the nodes from the commandline arguments.
662    osg::Node* loadedModel = osgDB::readNodeFiles(arguments);
663
664    // if not loaded assume no arguments passed in, try use default mode instead.
665    if (!loadedModel) loadedModel = osgDB::readNodeFile("cow.osgt");
666
667    if (!loadedModel)
668    {
669        std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
670        return 1;
671    }
672
673
674    if (arguments.read("--dome") || arguments.read("--puffer") )
675    {
676
677        setDomeCorrection(viewer, arguments);
678
679        viewer.setSceneData( loadedModel );
680    }
681    else if (arguments.read("--faces"))
682    {
683
684        setDomeFaces(viewer, arguments);
685
686        viewer.setSceneData( loadedModel );
687    }
688    else
689    {
690        osg::Node* distortionNode = createDistortionSubgraph( loadedModel, viewer.getCamera()->getClearColor());
691        viewer.setSceneData( distortionNode );
692    }
693
694    while (arguments.read("--sky-light"))
695    {
696        viewer.setLightingMode(osg::View::SKY_LIGHT);
697    }
698
699    if (viewer.getLightingMode()==osg::View::HEADLIGHT)
700    {
701        viewer.getLight()->setPosition(osg::Vec4(0.0f,0.0f,0.0f,1.0f));
702    }
703
704
705    // load the nodes from the commandline arguments.
706    if (!viewer.getSceneData())
707    {
708        osg::notify(osg::NOTICE)<<"Please specify a model filename on the command line."<<std::endl;
709        return 1;
710    }
711
712
713    // set up the camera manipulators.
714    {
715        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
716
717        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
718        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
719        keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
720        keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
721
722        std::string pathfile;
723        char keyForAnimationPath = '5';
724        while (arguments.read("-p",pathfile))
725        {
726            osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
727            if (apm || !apm->valid())
728            {
729                unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
730                keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
731                keyswitchManipulator->selectMatrixManipulator(num);
732                ++keyForAnimationPath;
733            }
734        }
735
736        viewer.setCameraManipulator( keyswitchManipulator.get() );
737    }
738
739    viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
740
741    // add the state manipulator
742    viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
743
744    // add the stats handler
745    viewer.addEventHandler(new osgViewer::StatsHandler);
746
747    return viewer.run();
748}
Note: See TracBrowser for help on using the browser.