source: experimental/distortionNG/extViewer.cpp @ 329

Last change on this file since 329 was 329, checked in by Torben Dannhauer, 12 years ago
File size: 9.5 KB
Line 
1#include "extViewer.h"
2#include "distortionNG.h"
3
4#include <osg/PolygonOffset>
5#include<osg/Texture2D>
6#include<osg/TextureRectangle>
7#include<osg/TexMat>
8#include<osg/ComputeBoundsVisitor>
9#include<osg/Vec2>
10
11#include<osgDB/ReadFile>
12
13#include <osgUtil/SmoothingVisitor>
14
15extViewer::extViewer() : Viewer()
16{
17}
18
19extViewer::extViewer(osg::ArgumentParser& arguments) : Viewer(arguments)
20{
21
22}
23
24extViewer::extViewer(const osgViewer::Viewer& viewer, const osg::CopyOp& copyop) : Viewer(viewer, copyop)
25{
26
27}
28
29extViewer::~extViewer()
30{
31
32}
33
34void extViewer::setUpViewForManualDistortion(unsigned int screenNum, osg::Image* intensityMap, const osg::Matrixd& projectorMatrix)
35{
36        OSG_INFO<<"View::setUpViewForManualDistortion(sn="<<screenNum<<", im="<<intensityMap<<")"<<std::endl;
37
38    osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
39    if (!wsi)
40    {
41        OSG_NOTICE<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
42        return;
43    }
44
45        osg::GraphicsContext::ScreenIdentifier si;
46    si.readDISPLAY();
47
48    // displayNum has not been set so reset it to 0.
49    if (si.displayNum<0) si.displayNum = 0;
50
51    si.screenNum = screenNum;
52
53    unsigned int width, height;
54    wsi->getScreenResolution(si, width, height);
55
56        osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
57    traits->hostName = si.hostName;
58    traits->displayNum = si.displayNum;
59    traits->screenNum = si.screenNum;
60    traits->x = 0;
61    traits->y = 0;
62    traits->width = width;
63    traits->height = height;
64    traits->windowDecoration = false;
65    traits->doubleBuffer = true;
66    traits->sharedContext = 0;
67
68        bool applyIntensityMapAsColours = true;
69
70        osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
71    if (!gc)
72    {
73        OSG_NOTICE<<"GraphicsWindow has not been created successfully."<<std::endl;
74        return;
75    }
76       
77        // Set up projection Matrix as it is done in View::setUpViewOnSingleScreen(
78        double fovy, aspectRatio, zNear, zFar;
79        _camera->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
80
81        double newAspectRatio = double(traits->width) / double(traits->height);
82        double aspectRatioChange = newAspectRatio / aspectRatio;
83        if (aspectRatioChange != 1.0)
84        {
85                _camera->getProjectionMatrix() *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0);
86        }
87
88
89    int tex_width = width;
90    int tex_height = height;
91
92    int camera_width = tex_width;
93    int camera_height = tex_height;
94
95    osg::TextureRectangle* texture = new osg::TextureRectangle;
96
97    texture->setTextureSize(tex_width, tex_height);
98    texture->setInternalFormat(GL_RGB);
99    texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
100    texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);
101    texture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
102    texture->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
103
104
105#if 0
106    osg::Camera::RenderTargetImplementation renderTargetImplementation = osg::Camera::SEPERATE_WINDOW;
107    GLenum buffer = GL_FRONT;
108#else
109    osg::Camera::RenderTargetImplementation renderTargetImplementation = osg::Camera::FRAME_BUFFER_OBJECT;
110    GLenum buffer = GL_FRONT;
111#endif
112
113        // Scene camera
114    {
115        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
116        camera->setName("Scene cam");
117        camera->setGraphicsContext(gc.get());
118        camera->setViewport(new osg::Viewport(0,0,camera_width, camera_height));
119        camera->setDrawBuffer(buffer);
120        camera->setReadBuffer(buffer);
121        camera->setAllowEventFocus(false);
122        // tell the camera to use OpenGL frame buffer object where supported.
123        camera->setRenderTargetImplementation(renderTargetImplementation);
124
125        // attach the texture and use it as the color buffer.
126        camera->attach(osg::Camera::COLOR_BUFFER, texture);
127
128        addSlave(camera.get(), osg::Matrixd(), osg::Matrixd());
129    }
130
131    // distortion correction set up.
132    {
133        osg::Geode* geode = new osg::Geode();
134                //geode->addDrawable(createParoramicSphericalDisplayDistortionMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), 1, 0.45, 0, projectorMatrix));
135                osg::Geometry* distortionMesh = createMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), 20, 20, projectorMatrix);
136                geode->addDrawable(distortionMesh);
137
138        // new we need to add the texture to the mesh, we do so by creating a
139        // StateSet to contain the Texture StateAttribute.
140        osg::StateSet* stateset = geode->getOrCreateStateSet();
141        stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON);
142        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
143
144        osg::TexMat* texmat = new osg::TexMat;
145        texmat->setScaleByTextureRectangleSize(true);
146        stateset->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON);
147
148        if (!applyIntensityMapAsColours && intensityMap)
149        {
150            stateset->setTextureAttributeAndModes(1, new osg::Texture2D(intensityMap), osg::StateAttribute::ON);
151        }
152
153        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
154        camera->setGraphicsContext(gc.get());
155        camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
156        camera->setClearColor( osg::Vec4(0.0,0.0,0.0,1.0) );
157        camera->setViewport(new osg::Viewport(0, 0, width, height));
158        GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
159        camera->setDrawBuffer(buffer);
160        camera->setReadBuffer(buffer);
161        camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
162        camera->setAllowEventFocus(false);
163        camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE);
164        //camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
165
166        camera->setProjectionMatrixAsOrtho2D(0,width,0,height);
167        camera->setViewMatrix(osg::Matrix::identity());
168
169        // add subgraph to render
170        //camera->addChild(geode);
171
172                // selector
173                geode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
174                geode->getOrCreateStateSet()->setAttributeAndModes( new osg::PolygonOffset(1.0f, 1.0f) );
175                osg::ref_ptr<distortionHandler> selector = new distortionHandler( camera, distortionMesh );
176                osg::ref_ptr<osg::Group> root = new osg::Group;
177                root->addChild(geode);
178                root->addChild(selector->createVertexHighlighter());
179                addEventHandler( selector.get() );
180                camera->addChild(root);
181                // Avoid that the highlighter is culled away
182                osg::CullSettings::CullingMode mode = camera->getCullingMode();
183                camera->setCullingMode( mode & (~osg::CullSettings::SMALL_FEATURE_CULLING) );
184
185
186        camera->setName("Dist Cam");
187
188        addSlave(camera.get(), osg::Matrixd(), osg::Matrixd(), false);
189    }
190}
191
192osg::Geometry* extViewer::createMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector, unsigned int columns, unsigned int rows, const osg::Matrix& projectorMatrix)
193{
194        // Create Quad to render on
195        osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
196
197        geom->setUseDisplayList( false );
198
199        osg::Vec3 xAxis(widthVector);
200    float width = widthVector.length();
201    xAxis /= width;
202
203    osg::Vec3 yAxis(heightVector);
204    float height = heightVector.length();
205    yAxis /= height;
206
207        osg::Vec3 dx = xAxis*(width/((float)(columns-1)));
208    osg::Vec3 dy = yAxis*(height/((float)(rows-1)));
209
210
211        // Create vertices and coordinates
212        osg::Vec3Array* vertices = new osg::Vec3Array;
213    osg::Vec2Array* texcoords0 = new osg::Vec2Array;
214    //osg::Vec2Array* texcoords1 = intensityMap==0 ? new osg::Vec2Array : 0;
215    osg::Vec4Array* colors = new osg::Vec4Array;
216
217        geom->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);
218
219        for ( unsigned int row=0; row<rows; row++ )
220        {
221                for ( unsigned int col=0; col<columns; col++ )
222                {
223                        vertices->push_back( origin+dy*row+dx*col );    // geometry
224                        osg::Vec2 texcoord = osg::Vec2((float)col/(float)(columns-1), (float)row/(float)(rows-1));
225                        texcoords0->push_back( texcoord );
226
227//      if (intensityMap)
228//    {
229//        colors->push_back(intensityMap->getColor(texcoord1));
230//    }
231//    else
232//    {
233        colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
234//        if (texcoords1) texcoords1->push_back( texcoord1 );
235//    }
236
237                }
238        }
239
240        // Pass the created vertex array to the points geometry object.
241        geom->setUseVertexBufferObjects( true );
242        geom->setVertexArray(vertices);
243
244        geom->setColorArray(colors);
245    geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
246
247    geom->setTexCoordArray(0,texcoords0);
248    //if (texcoords1) geometry->setTexCoordArray(1,texcoords1);
249
250 //   osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES);
251 //   geometry->addPrimitiveSet(elements);
252
253        for ( unsigned int row=0; row<rows-1; row++ )   // each strip consists of two affected vertex rows, so we need only row-1 strips.
254        {
255                osg::ref_ptr<osg::DrawElementsUInt> de = new osg::DrawElementsUInt(GL_QUAD_STRIP, columns*2);   // columns*2 = number of involved vertices for this strip.
256                for ( unsigned int col=0; col<columns; col++ )
257                {
258                        (*de)[col*2 + 0] = row*columns + col;
259                        (*de)[col*2 + 1] = (row+1)*columns + col;
260                }
261                geom->addPrimitiveSet( de.get() );
262        }
263
264        return geom.release();
265}
Note: See TracBrowser for help on using the repository browser.