source: experimental/distortionNG/extViewer.cpp @ 340

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

The intersection works and the selector highlighter is set and displayed correctly.
Next steps:

  • use a variable to control whether distortion setup is active or not. temporarily track the Ctrl Key to enably(push or disable(release) the edit mode.
  • Hide the highlighter and disable the intersection/drag tracking on diabled edit mode.
  • catch up dragging values and translate them in the correct coordinate frame.
  • apply dragging values:
  • a) either on the texture coordinate while the grid is constant,
  • b) or apply them on the grid node coordinates while the texture coordinates are constant (check/compare solutions!)



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