root/OpenSceneGraph/trunk/examples/osgshaderterrain/osgshaderterrain.cpp @ 13748

Revision 13574, 10.4 kB (checked in by robert, 9 days ago)

Fixed comment

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osgshaderterrain.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19#include <osg/AlphaFunc>
20#include <osg/Billboard>
21#include <osg/BlendFunc>
22#include <osg/Depth>
23#include <osg/Geode>
24#include <osg/Geometry>
25#include <osg/GL2Extensions>
26#include <osg/Material>
27#include <osg/Math>
28#include <osg/MatrixTransform>
29#include <osg/PolygonOffset>
30#include <osg/Program>
31#include <osg/Projection>
32#include <osg/Shader>
33#include <osg/ShapeDrawable>
34#include <osg/StateSet>
35#include <osg/Switch>
36#include <osg/Texture2D>
37#include <osg/Uniform>
38
39#include <osgDB/ReadFile>
40#include <osgDB/FileUtils>
41
42#include <osgUtil/SmoothingVisitor>
43
44#include <osgText/Text>
45
46#include <osgViewer/Viewer>
47
48#include <iostream>
49
50// for the grid data..
51#include "../osghangglide/terrain_coords.h"
52
53osg::Node* createScene()
54{
55    osg::Group* scene = new osg::Group;
56
57    unsigned int numColumns = 38;
58    unsigned int numRows = 39;
59    unsigned int r;
60    unsigned int c;
61
62    osg::Vec3 origin(0.0f,0.0f,0.0f);
63    osg::Vec3 size(1000.0f,1000.0f,250.0f);
64    osg::Vec3 scaleDown(1.0f/size.x(),1.0f/size.y(),1.0f/size.z());
65
66    // ---------------------------------------
67    // Set up a StateSet to texture the objects
68    // ---------------------------------------
69    osg::StateSet* stateset = new osg::StateSet();
70
71
72    osg::Uniform* originUniform = new osg::Uniform("terrainOrigin",origin);
73    stateset->addUniform(originUniform);
74
75    osg::Uniform* sizeUniform = new osg::Uniform("terrainSize",size);
76    stateset->addUniform(sizeUniform);
77
78    osg::Uniform* scaleDownUniform = new osg::Uniform("terrainScaleDown",scaleDown);
79    stateset->addUniform(scaleDownUniform);
80
81    osg::Uniform* terrainTextureSampler = new osg::Uniform("terrainTexture",0);
82    stateset->addUniform(terrainTextureSampler);
83
84    osg::Uniform* baseTextureSampler = new osg::Uniform("baseTexture",1);
85    stateset->addUniform(baseTextureSampler);
86
87    osg::Uniform* treeTextureSampler = new osg::Uniform("treeTexture",1);
88    stateset->addUniform(treeTextureSampler);
89
90
91    // compute z range of z values of grid data so we can scale it.
92    float min_z = FLT_MAX;
93    float max_z = -FLT_MAX;
94    for(r=0;r<numRows;++r)
95    {
96        for(c=0;c<numColumns;++c)
97        {
98            min_z = osg::minimum(min_z,vertex[r+c*numRows][2]);
99            max_z = osg::maximum(max_z,vertex[r+c*numRows][2]);
100        }
101    }
102
103    float scale_z = size.z()/(max_z-min_z);
104
105    osg::Image* terrainImage = new osg::Image;
106    terrainImage->allocateImage(numColumns,numRows,1,GL_LUMINANCE, GL_FLOAT);
107    terrainImage->setInternalTextureFormat(GL_LUMINANCE_FLOAT32_ATI);
108    for(r=0;r<numRows;++r)
109    {
110        for(c=0;c<numColumns;++c)
111        {
112            *((float*)(terrainImage->data(c,r))) = (vertex[r+c*numRows][2]-min_z)*scale_z;
113        }
114    }
115
116    osg::Texture2D* terrainTexture = new osg::Texture2D;
117    terrainTexture->setImage(terrainImage);
118    terrainTexture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST);
119    terrainTexture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST);
120    terrainTexture->setResizeNonPowerOfTwoHint(false);
121    stateset->setTextureAttributeAndModes(0,terrainTexture,osg::StateAttribute::ON);
122
123
124    osg::Image* image = osgDB::readImageFile("Images/lz.rgb");
125    if (image)
126    {
127        osg::Texture2D* texture = new osg::Texture2D;
128
129        texture->setImage(image);
130        stateset->setTextureAttributeAndModes(1,texture,osg::StateAttribute::ON);
131    }
132
133    {
134        std::cout<<"Creating terrain...";
135
136        osg::Geode* geode = new osg::Geode();
137        geode->setStateSet( stateset );
138
139
140        {
141            osg::Program* program = new osg::Program;
142            stateset->setAttribute(program);
143
144#if 1
145            // use inline shaders
146
147            ///////////////////////////////////////////////////////////////////
148            // vertex shader using just Vec4 coefficients
149            char vertexShaderSource[] =
150               "uniform sampler2D terrainTexture;\n"
151               "uniform vec3 terrainOrigin;\n"
152               "uniform vec3 terrainScaleDown;\n"
153               "\n"
154               "varying vec2 texcoord;\n"
155               "\n"
156               "void main(void)\n"
157               "{\n"
158               "    texcoord = gl_Vertex.xy - terrainOrigin.xy;\n"
159               "    texcoord.x *= terrainScaleDown.x;\n"
160               "    texcoord.y *= terrainScaleDown.y;\n"
161               "\n"
162               "    vec4 position;\n"
163               "    position.x = gl_Vertex.x;\n"
164               "    position.y = gl_Vertex.y;\n"
165               "    position.z = texture2D(terrainTexture, texcoord).r;\n"
166               "    position.w = 1.0;\n"
167               " \n"
168               "    gl_Position     = gl_ModelViewProjectionMatrix * position;\n"
169                "   gl_FrontColor = vec4(1.0,1.0,1.0,1.0);\n"
170               "}\n";
171
172            //////////////////////////////////////////////////////////////////
173            // fragment shader
174            //
175            char fragmentShaderSource[] =
176                "uniform sampler2D baseTexture; \n"
177                "varying vec2 texcoord;\n"
178                "\n"
179                "void main(void) \n"
180                "{\n"
181                "    gl_FragColor = texture2D( baseTexture, texcoord); \n"
182                "}\n";
183
184            program->addShader(new osg::Shader(osg::Shader::VERTEX, vertexShaderSource));
185            program->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource));
186
187#else
188
189            // get shaders from source
190            program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, osgDB::findDataFile("shaders/terrain.vert")));
191            program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, osgDB::findDataFile("shaders/terrain.frag")));
192
193#endif
194
195            // get shaders from source
196        }
197
198
199        {
200            osg::Geometry* geometry = new osg::Geometry;
201
202            osg::Vec3Array& v = *(new osg::Vec3Array(numColumns*numRows));
203            osg::Vec4ubArray& color = *(new osg::Vec4ubArray(1));
204
205            color[0].set(255,255,255,255);
206
207            float rowCoordDelta = size.y()/(float)(numRows-1);
208            float columnCoordDelta = size.x()/(float)(numColumns-1);
209
210            float rowTexDelta = 1.0f/(float)(numRows-1);
211            float columnTexDelta = 1.0f/(float)(numColumns-1);
212
213            osg::Vec3 pos = origin;
214            osg::Vec2 tex(0.0f,0.0f);
215            int vi=0;
216            for(r=0;r<numRows;++r)
217            {
218                pos.x() = origin.x();
219                tex.x() = 0.0f;
220                for(c=0;c<numColumns;++c)
221                {
222                    v[vi].set(pos.x(),pos.y(),pos.z());
223                    pos.x()+=columnCoordDelta;
224                    tex.x()+=columnTexDelta;
225                    ++vi;
226                }
227                pos.y() += rowCoordDelta;
228                tex.y() += rowTexDelta;
229            }
230
231            geometry->setVertexArray(&v);
232            geometry->setColorArray(&color, osg::Array::BIND_OVERALL);
233
234            for(r=0;r<numRows-1;++r)
235            {
236                osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(GL_QUAD_STRIP,2*numColumns));
237                geometry->addPrimitiveSet(&drawElements);
238                int ei=0;
239                for(c=0;c<numColumns;++c)
240                {
241                    drawElements[ei++] = (r+1)*numColumns+c;
242                    drawElements[ei++] = (r)*numColumns+c;
243                }
244            }
245
246            geometry->setInitialBound(osg::BoundingBox(origin, origin+size));
247
248            geode->addDrawable(geometry);
249
250            scene->addChild(geode);
251        }
252    }
253
254    std::cout<<"done."<<std::endl;
255
256    return scene;
257}
258
259class TestSupportOperation: public osg::GraphicsOperation
260{
261public:
262
263    TestSupportOperation():
264        osg::GraphicsOperation("TestSupportOperation",false),
265        _supported(true),
266        _errorMessage() {}
267
268    virtual void operator () (osg::GraphicsContext* gc)
269    {
270        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
271
272        unsigned int contextID = gc->getState()->getContextID();
273        osg::GL2Extensions* gl2ext = osg::GL2Extensions::Get(contextID,true);
274        if( gl2ext )
275        {
276            if( !gl2ext->isGlslSupported() )
277            {
278                _supported = false;
279                _errorMessage = "ERROR: GLSL not supported by OpenGL driver.";
280            }
281
282            GLint numVertexTexUnits = 0;
283            glGetIntegerv( GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &numVertexTexUnits );
284            if( numVertexTexUnits <= 0 )
285            {
286                _supported = false;
287                _errorMessage = "ERROR: vertex texturing not supported by OpenGL driver.";
288            }
289        }
290        else
291        {
292            _supported = false;
293            _errorMessage = "ERROR: GLSL not supported.";
294        }
295    }
296
297    OpenThreads::Mutex  _mutex;
298    bool                _supported;
299    std::string         _errorMessage;
300};
301
302int main(int, char **)
303{
304    // construct the viewer.
305    osgViewer::Viewer viewer;
306
307    osg::Node* node = createScene();
308
309    // add model to viewer.
310    viewer.setSceneData( node );
311
312    viewer.setUpViewAcrossAllScreens();
313
314    osg::ref_ptr<TestSupportOperation> testSupportOperation = new TestSupportOperation;
315#if 0
316    // temporily commenting out as its causing the viewer to crash... no clue yet to why
317    viewer.setRealizeOperation(testSupportOperation.get());
318#endif
319    // create the windows and run the threads.
320    viewer.realize();
321
322    if (!testSupportOperation->_supported)
323    {
324        osg::notify(osg::WARN)<<testSupportOperation->_errorMessage<<std::endl;
325
326        return 1;
327    }
328
329    return viewer.run();
330}
Note: See TracBrowser for help on using the browser.