source: experimental/distortionNG/extViewer.cpp @ 334

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