source: experimental/distortionNG/extViewer.cpp @ 335

Last change on this file since 335 was 335, checked in by Torben Dannhauer, 12 years ago
File size: 13.0 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#include <osgDB/FileUtils>
13
14#include <osgUtil/SmoothingVisitor>
15
16extViewer::extViewer() : Viewer()
17{
18}
19
20extViewer::extViewer(osg::ArgumentParser& arguments) : Viewer(arguments)
21{
22
23}
24
25extViewer::extViewer(const osgViewer::Viewer& viewer, const osg::CopyOp& copyop) : Viewer(viewer, copyop)
26{
27
28}
29
30extViewer::~extViewer()
31{
32
33}
34
35static osg::Texture* loadTexture( const std::string& fileName )
36{
37    std::string foundFileName = osgDB::findDataFile(fileName);
38    if (foundFileName.length() != 0 )
39    {
40        // load distortion map texture file
41        osg::Image* image = osgDB::readImageFile(foundFileName);
42        if (image)
43        {
44                        osg::Texture2D* texture = new osg::Texture2D;
45            texture->setImage(image);
46            texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST);
47            texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST);
48            texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
49            texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
50            return texture;
51        }
52    }
53
54    OSG_NOTIFY(osg::WARN) << "File \"" << fileName << "\" not found." << std::endl;
55
56    return NULL;
57}
58
59static osg::Geometry* createMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector, unsigned int columns, unsigned int rows, osg::Image* intensityMap, bool applyIntensityMapAsColours, const osg::Matrix& projectorMatrix)
60{
61        // Create Quad to render on
62        osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
63
64        geom->setUseDisplayList( false );
65
66        osg::Vec3 xAxis(widthVector);
67    float width = widthVector.length();
68    xAxis /= width;
69
70    osg::Vec3 yAxis(heightVector);
71    float height = heightVector.length();
72    yAxis /= height;
73
74        osg::Vec3 dx = xAxis*(width/((float)(columns-1)));
75    osg::Vec3 dy = yAxis*(height/((float)(rows-1)));
76
77
78        // Create vertices and coordinates
79        osg::Vec3Array* vertices = new osg::Vec3Array;
80    osg::Vec2Array* texcoords0 = new osg::Vec2Array;
81    osg::Vec2Array* texcoords1 = intensityMap==0 ? new osg::Vec2Array : 0;
82    osg::Vec4Array* colors = new osg::Vec4Array;
83
84        geom->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);
85
86        for ( unsigned int row=0; row<rows; row++ )
87        {
88                for ( unsigned int col=0; col<columns; col++ )
89                {
90                        // Create coordinates of the mesh node (geometry).
91                        vertices->push_back( origin+dy*row+dx*col );
92
93                        // Create tex coordinates
94                        osg::Vec2 texcoord = osg::Vec2((float)col/(float)(columns-1), (float)row/(float)(rows-1));
95
96                        // Set Coordinates for RTT-Texture (scene rendering)
97                        texcoords0->push_back( texcoord );
98
99                        // Set Color of the mesh node
100                        if (intensityMap && applyIntensityMapAsColours)
101                        {
102                                colors->push_back(intensityMap->getColor(texcoord));
103                        }
104                        else
105                        {
106                                colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
107                        }
108
109                        // Set coordinates for second texcoords array (if applyIntensityMapAsColours==true)
110                        if (texcoords1) 
111                                texcoords1->push_back( texcoord );
112                }
113        }
114
115        // Pass the created vertex array to the points geometry object.
116        geom->setUseVertexBufferObjects( true );
117        geom->setVertexArray(vertices);
118
119        geom->setColorArray(colors);
120    geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
121
122    geom->setTexCoordArray(0,texcoords0);
123    if (texcoords1)
124                geom->setTexCoordArray(1,texcoords1);
125
126
127        for ( unsigned int row=0; row<rows-1; row++ )   // each strip consists of two affected vertex rows, so we need only row-1 strips.
128        {
129                osg::ref_ptr<osg::DrawElementsUInt> de = new osg::DrawElementsUInt(GL_QUAD_STRIP, columns*2);   // columns*2 = number of involved vertices for this strip.
130                for ( unsigned int col=0; col<columns; col++ )
131                {
132                        (*de)[col*2 + 0] = row*columns + col;
133                        (*de)[col*2 + 1] = (row+1)*columns + col;
134                }
135                geom->addPrimitiveSet( de.get() );
136        }
137
138        //if (intensityMap && !applyIntensityMapAsColours)
139        //{
140        //      // create shaders for distortion
141        //      osg::Program* distortProgram = new osg::Program;
142        //      distortProgram->setName( "distortion" );
143        //      osg::Shader* vShader = osg::Shader::readShaderFile( osg::Shader::VERTEX, "shader.vert" );
144        //      vShader->setName("intensityMapVertShader");
145        //      osg::Shader* fShader = osg::Shader::readShaderFile( osg::Shader::FRAGMENT, "shader.frag" );
146        //      fShader->setName("intensityMapFragShader");
147
148        //      if ( vShader && fShader )
149        //      {
150        //              //distortProgram->addShader( vShader );
151        //              distortProgram->addShader( fShader );
152        //              geom->getOrCreateStateSet()->addUniform( new osg::Uniform("sceneTexture", 0) );
153        //              geom->getOrCreateStateSet()->addUniform( new osg::Uniform("intensityMapTexture", 1) );
154        //              geom->getOrCreateStateSet()->setAttributeAndModes(distortProgram, osg::StateAttribute::ON);
155        //      }
156        //}
157
158        return geom.release();
159}
160
161void extViewer::setUpViewForManualDistortion(unsigned int screenNum, osg::Image* intensityMap, const osg::Matrixd& projectorMatrix)
162{
163        OSG_INFO<<"View::setUpViewForManualDistortion(sn="<<screenNum<<", im="<<intensityMap<<")"<<std::endl;
164
165    osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
166    if (!wsi)
167    {
168        OSG_NOTICE<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
169        return;
170    }
171
172        osg::GraphicsContext::ScreenIdentifier si;
173    si.readDISPLAY();
174
175    // displayNum has not been set so reset it to 0.
176    if (si.displayNum<0) si.displayNum = 0;
177
178    si.screenNum = screenNum;
179
180    unsigned int width, height;
181    wsi->getScreenResolution(si, width, height);
182
183        osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
184    traits->hostName = si.hostName;
185    traits->displayNum = si.displayNum;
186    traits->screenNum = si.screenNum;
187    traits->x = 0;
188    traits->y = 0;
189    traits->width = width;
190    traits->height = height;
191    traits->windowDecoration = false;
192    traits->doubleBuffer = true;
193    traits->sharedContext = 0;
194
195        bool applyIntensityMapAsColours = false;
196
197        osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
198    if (!gc)
199    {
200        OSG_NOTICE<<"GraphicsWindow has not been created successfully."<<std::endl;
201        return;
202    }
203
204        // Set up projection Matrix as it is done in View::setUpViewOnSingleScreen(
205        double fovy, aspectRatio, zNear, zFar;
206        _camera->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
207
208        double newAspectRatio = double(traits->width) / double(traits->height);
209        double aspectRatioChange = newAspectRatio / aspectRatio;
210        if (aspectRatioChange != 1.0)
211        {
212                _camera->getProjectionMatrix() *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0);
213        }
214
215
216    int tex_width = width;
217    int tex_height = height;
218
219    int camera_width = tex_width;
220    int camera_height = tex_height;
221
222    osg::TextureRectangle* sceneTexture = new osg::TextureRectangle;
223
224    sceneTexture->setTextureSize(tex_width, tex_height);
225    sceneTexture->setInternalFormat(GL_RGB);
226    sceneTexture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
227    sceneTexture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);
228    sceneTexture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
229    sceneTexture->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
230
231
232#if 0
233    osg::Camera::RenderTargetImplementation renderTargetImplementation = osg::Camera::SEPERATE_WINDOW;
234    GLenum buffer = GL_FRONT;
235#else
236    osg::Camera::RenderTargetImplementation renderTargetImplementation = osg::Camera::FRAME_BUFFER_OBJECT;
237    GLenum buffer = GL_FRONT;
238#endif
239
240        // Scene camera
241    {
242        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
243        camera->setName("Scene cam");
244        camera->setGraphicsContext(gc.get());
245        camera->setViewport(new osg::Viewport(0,0,camera_width, camera_height));
246        camera->setDrawBuffer(buffer);
247        camera->setReadBuffer(buffer);
248        camera->setAllowEventFocus(false);
249        // tell the camera to use OpenGL frame buffer object where supported.
250        camera->setRenderTargetImplementation(renderTargetImplementation);
251        // attach the texture and use it as the color buffer.
252        camera->attach(osg::Camera::COLOR_BUFFER, sceneTexture);
253
254        addSlave(camera.get(), osg::Matrixd(), osg::Matrixd());
255    }
256
257    // distortion correction set up.
258    {
259                osg::Geode* geode = new osg::Geode();
260
261                // new we need to add the scene texture to the mesh, we do so by creating a
262        // StateSet to contain the Texture StateAttribute.
263        osg::StateSet* stateset = geode->getOrCreateStateSet();
264        //stateset->setTextureAttributeAndModes(0, sceneTexture,osg::StateAttribute::ON);
265        //stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
266
267                //osg::TexMat* texmat = new osg::TexMat;
268  //      texmat->setScaleByTextureRectangleSize(true);
269  //      stateset->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON);
270
271                // If the intensityMap is used but not applyIntensityMapAsColours: Apply intensityMap as intensityMapTexture on unit 1
272                if (!applyIntensityMapAsColours && intensityMap)
273        {
274                        osg::Texture2D* intensityMapTexture = new osg::Texture2D(intensityMap);
275            intensityMapTexture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST);
276            intensityMapTexture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST);
277            intensityMapTexture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
278            intensityMapTexture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
279
280            stateset->setTextureAttributeAndModes(1, intensityMapTexture, osg::StateAttribute::ON);
281
282                        osg::Texture* tmp = loadTexture( "test.jpg" );
283                        if(tmp)
284                        {
285                                stateset->setTextureAttributeAndModes(0, tmp,osg::StateAttribute::ON);
286
287                                osg::TexMat* texmat = new osg::TexMat;
288                                texmat->setScaleByTextureRectangleSize(true);
289                                stateset->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON);
290                        }
291
292        }
293
294                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, applyIntensityMapAsColours, projectorMatrix);
295                geode->addDrawable(distortionMesh);
296
297                if (intensityMap && !applyIntensityMapAsColours)
298                {
299                        // create shaders for distortion
300                        osg::Program* distortProgram = new osg::Program;
301                        distortProgram->setName( "distortion" );
302                        osg::Shader* vShader = osg::Shader::readShaderFile( osg::Shader::VERTEX, "shader.vert" ); 
303                        vShader->setName("intensityMapVertShader");
304                        osg::Shader* fShader = osg::Shader::readShaderFile( osg::Shader::FRAGMENT, "shader.frag" ); 
305                        fShader->setName("intensityMapFragShader");
306
307                        if ( vShader && fShader )
308                        {
309                                //distortProgram->addShader( vShader );
310                                distortProgram->addShader( fShader );
311                                stateset->addUniform( new osg::Uniform("sceneTexture", 0) );
312                                stateset->addUniform( new osg::Uniform("intensityMapTexture", 1) );
313                                stateset->setAttributeAndModes(distortProgram, osg::StateAttribute::ON);
314                        }
315                }
316
317
318        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
319        camera->setGraphicsContext(gc.get());
320        camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
321        camera->setClearColor( osg::Vec4(0.0,1.0,0.0,1.0) );
322        camera->setViewport(new osg::Viewport(0, 0, width, height));
323        GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
324        camera->setDrawBuffer(buffer);
325        camera->setReadBuffer(buffer);
326        camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
327        camera->setAllowEventFocus(false);
328        camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE);
329        //camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
330
331        camera->setProjectionMatrixAsOrtho2D(0,width,0,height);
332        camera->setViewMatrix(osg::Matrix::identity());
333
334                //// selector
335                //geode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
336                //geode->getOrCreateStateSet()->setAttributeAndModes( new osg::PolygonOffset(1.0f, 1.0f) );
337                //osg::ref_ptr<distortionHandler> selector = new distortionHandler( camera, distortionMesh );
338                osg::ref_ptr<osg::Group> root = new osg::Group;
339                root->addChild(geode);
340                //root->addChild(selector->createVertexHighlighter());
341                //addEventHandler( selector.get() );
342                camera->addChild(root);
343                //// Avoid that the highlighter is culled away
344                //osg::CullSettings::CullingMode mode = camera->getCullingMode();
345                //camera->setCullingMode( mode & (~osg::CullSettings::SMALL_FEATURE_CULLING) );
346
347
348        camera->setName("Dist Cam");
349
350        addSlave(camera.get(), osg::Matrixd(), osg::Matrixd(), false);
351    }
352}
Note: See TracBrowser for help on using the repository browser.