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

Revision 13574, 26.6 kB (checked in by robert, 9 days ago)

Release OpenSceneGraph-3.2.1

  • 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.