source: experimental/distortionNG/extViewer.cpp @ 333

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