source: experimental/distortionNG/extViewer.cpp @ 331

Last change on this file since 331 was 331, checked in by Torben Dannhauer, 12 years ago

Initial intensityMap support added

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