source: experimental/distortionNG/extViewer.cpp @ 332

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