root/OpenSceneGraph/trunk/examples/osgparametric/osgparametric.cpp @ 5927

Revision 5927, 18.5 kB (checked in by robert, 7 years ago)

Ported following examples to osgViewer:

osggeodemo
osggeometry
osghud
osgimpostor
osgkeyboard
osglauncher
osglight
osglightpoint
osglogicop
osglogo
osgmovie
osgmultiplecameras
osgmultitexture
osgoccluder
osgparametric
osgparticle

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osg/Vec3>
2#include <osg/Vec4>
3#include <osg/Quat>
4#include <osg/Matrix>
5#include <osg/ShapeDrawable>
6#include <osg/Geometry>
7#include <osg/Geode>
8#include <osg/Texture2D>
9
10#include <osgDB/FileUtils>
11#include <osgDB/ReadFile>
12
13#include <osgUtil/Optimizer>
14#include <osgUtil/TriStripVisitor>
15
16#include <osgViewer/Viewer>
17
18#include <iostream>
19
20// for the grid data..
21#include "../osghangglide/terrain_coords.h"
22
23///////////////////////////////////////////////////////////////////
24// vertex shader using just Vec4 coefficients
25char vertexShaderSource_simple[] =
26    "uniform vec4 coeff; \n"
27    "\n"
28    "void main(void) \n"
29    "{ \n"
30    "\n"
31    "    gl_TexCoord[0] = gl_Vertex; \n"
32    "    vec4 vert = gl_Vertex; \n"
33    "    vert.z = gl_Vertex.x*coeff[0] + gl_Vertex.x*gl_Vertex.x* coeff[1] + \n"
34    "             gl_Vertex.y*coeff[2] + gl_Vertex.y*gl_Vertex.y* coeff[3]; \n"
35    "    gl_Position = gl_ModelViewProjectionMatrix * vert;\n"
36    "}\n";
37 
38 
39//////////////////////////////////////////////////////////////////
40// vertex shader using full Matrix4 coefficients
41char vertexShaderSource_matrix[] =
42    "uniform vec4  origin; \n"
43    "uniform mat4  coeffMatrix; \n"
44    "\n"
45    "void main(void) \n"
46    "{ \n"
47    "\n"
48    "    gl_TexCoord[0] = gl_Vertex; \n"
49    "    vec4 v = vec4(gl_Vertex.x, gl_Vertex.x*gl_Vertex.x, gl_Vertex.y, gl_Vertex.y*gl_Vertex.y ); \n"
50    "    gl_Position = gl_ModelViewProjectionMatrix * (origin + coeffMatrix * v);\n"
51    "}\n";
52
53//////////////////////////////////////////////////////////////////
54// vertex shader using texture read
55char vertexShaderSource_texture[] =
56    "uniform sampler2D vertexTexture; \n"
57    "\n"
58    "void main(void) \n"
59    "{ \n"
60    "\n"
61    "    gl_TexCoord[0] = gl_Vertex; \n"
62    "    vec4 vert = gl_Vertex; \n"
63    "    vert.z = texture2D( vertexTexture, gl_TexCoord[0].xy).x*0.1; \n"
64    "    gl_Position = gl_ModelViewProjectionMatrix * vert;\n"
65    "}\n";
66
67//////////////////////////////////////////////////////////////////
68// vertex shader using texture read
69char vertexShaderSource_texture2[] =
70    "uniform sampler2D vertexTexture; \n"
71    "uniform sampler2D vertexTexture2; \n"
72    "uniform float osg_FrameTime;\n"
73    "\n"
74    "void main(void) \n"
75    "{ \n"
76    "\n"
77    "    gl_TexCoord[0] = gl_Vertex; \n"
78    "    vec4 vert = gl_Vertex; \n"
79    "    float r = 1.0 + 0.5 * sin(osg_FrameTime);\n"
80    "    vert.z = (texture2D( vertexTexture, gl_TexCoord[0].xy).x * (1-r) + texture2D( vertexTexture2, gl_TexCoord[0].xy).x * r)*0.1; \n"
81    "    gl_Position = gl_ModelViewProjectionMatrix * vert;\n"
82    "}\n";
83
84//////////////////////////////////////////////////////////////////
85// fragment shader
86//
87char fragmentShaderSource[] =
88    "uniform sampler2D baseTexture; \n"
89    "\n"
90    "void main(void) \n"
91    "{ \n"
92    "    gl_FragColor = texture2D( baseTexture, gl_TexCoord[0].xy); \n"
93    "}\n";
94
95#if 0
96char fragmentShaderNormalSource[] =
97    "uniform sampler2D baseTexture; \n"
98    "uniform sampler2D vertexTexture; \n"
99    "\n"
100    "void main(void) \n"
101    "{ \n"
102    "    const float dx = 0.0010;  \n"
103    "    const float dy = 0.0010;  \n"
104    "    float dz_dx = texture2D( vertexTexture, gl_TexCoord[0].xy + vec2(dx,0.0)).x - texture2D( vertexTexture, gl_TexCoord[0].xy + vec2(-dx,0.0)).x; \n"
105    "    float dz_dy = texture2D( vertexTexture, gl_TexCoord[0].xy + vec2(0.0,dy)).x - texture2D( vertexTexture, gl_TexCoord[0].xy + vec2(0.0,-dy)).x; \n"
106    "    vec3 normal = normalize(vec3(-dz_dx, -dz_dy, dx*50));\n"
107    " \n"
108    "    gl_FragColor = vec4(normal.z,normal.z,normal.z,1.0); \n"
109    "}\n";
110#else
111char fragmentShaderNormalSource[] =
112    "uniform sampler2D baseTexture; \n"
113    "uniform sampler2D vertexTexture; \n"
114    "\n"
115    "void main(void) \n"
116    "{ \n"
117    "    vec3 normal = normalize(texture2D( baseTexture, gl_TexCoord[0].xy).xyz);\n"
118    " \n"
119    "    gl_FragColor = vec4(normal.z,normal.z,normal.z,1.0); \n"
120    "}\n";
121#endif
122
123class UniformVarying : public osg::Uniform::Callback
124{
125    virtual void operator () (osg::Uniform* uniform, osg::NodeVisitor* nv)
126    {
127        const osg::FrameStamp* fs = nv->getFrameStamp();
128        float value = sinf(fs->getReferenceTime());
129        uniform->set(osg::Vec4(value,-value,-value,value));
130    }
131};
132
133osg::Node* createModel(const std::string& shader, const std::string& textureFileName, const std::string& terrainFileName, const std::string& terrainFileName2, unsigned int cacheSize, unsigned int maxSize, bool joinStrips, const std::string& mesh)
134{
135    osg::Geode* geode = new osg::Geode;
136   
137    osg::Geometry* geom = new osg::Geometry;
138    geode->addDrawable(geom);
139   
140    // dimensions for ~one million triangles :-)
141    unsigned int num_x = 708;
142    unsigned int num_y = 708;
143
144    // set up state
145    {
146   
147        osg::StateSet* stateset = geom->getOrCreateStateSet();
148
149        osg::Program* program = new osg::Program;
150        stateset->setAttribute(program);
151
152        if (shader=="simple")
153        {
154            osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource_simple);
155            program->addShader(vertex_shader);
156
157            osg::Uniform* coeff = new osg::Uniform("coeff",osg::Vec4(1.0,-1.0f,-1.0f,1.0f));
158            coeff->setUpdateCallback(new UniformVarying);
159            stateset->addUniform(coeff);
160        }
161        else if (shader=="matrix")
162        {
163            osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource_matrix);
164            program->addShader(vertex_shader);
165
166            osg::Uniform* origin = new osg::Uniform("origin",osg::Vec4(0.0f,0.0f,0.0f,1.0f));
167            stateset->addUniform(origin);
168
169            osg::Uniform* coeffMatrix = new osg::Uniform("coeffMatrix",
170                osg::Matrix(1.0f,0.0f,1.0f,0.0f,
171                            0.0f,0.0f,-1.0f,0.0f,
172                            0.0f,1.0f,-1.0f,0.0f,
173                            0.0f,0.0f,1.0f,0.0f));
174
175            stateset->addUniform(coeffMatrix);
176        }
177        else if (shader=="texture")
178        {
179
180            osg::Image* image = 0;
181
182            if (terrainFileName.empty())
183            {
184                image = new osg::Image;
185                unsigned int tx = 38;
186                unsigned int ty = 39;
187                image->allocateImage(tx,ty,1,GL_LUMINANCE,GL_FLOAT,1);
188                for(unsigned int r=0;r<ty;++r)
189                {
190                    for(unsigned int c=0;c<tx;++c)
191                    {
192                        *((float*)image->data(c,r)) = vertex[r+c*39][2]*0.1;
193                    }
194                }
195
196                num_x = tx;
197                num_y = tx;
198            }
199            else
200            {
201                image = osgDB::readImageFile(terrainFileName);
202
203                num_x = image->s();
204                num_y = image->t();
205            }
206
207            osg::Texture2D* vertexTexture = new osg::Texture2D(image);
208
209
210            vertexTexture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::NEAREST);
211            vertexTexture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::NEAREST);
212           
213            vertexTexture->setInternalFormat(GL_LUMINANCE_FLOAT32_ATI);
214           
215            vertexTexture->setResizeNonPowerOfTwoHint(false);
216            stateset->setTextureAttributeAndModes(1,vertexTexture);
217
218            osg::Uniform* vertexTextureSampler = new osg::Uniform("vertexTexture",1);
219            stateset->addUniform(vertexTextureSampler);
220
221            if (!terrainFileName2.empty())
222            {
223                osg::Image* image2 = osgDB::readImageFile(terrainFileName2);
224                osg::Texture2D* vertexTexture2 = new osg::Texture2D(image2);
225
226
227                vertexTexture2->setFilter(osg::Texture::MIN_FILTER,osg::Texture::NEAREST);
228                vertexTexture2->setFilter(osg::Texture::MAG_FILTER,osg::Texture::NEAREST);
229
230                vertexTexture2->setInternalFormat(GL_LUMINANCE_FLOAT32_ATI);
231
232                vertexTexture2->setResizeNonPowerOfTwoHint(false);
233                stateset->setTextureAttributeAndModes(2,vertexTexture2);
234
235                osg::Uniform* vertexTextureSampler2 = new osg::Uniform("vertexTexture2",2);
236                stateset->addUniform(vertexTextureSampler2);
237
238            }
239
240        }
241
242        if (terrainFileName2.empty())
243        {
244            osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderNormalSource);
245            program->addShader(fragment_shader);
246
247            osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource_texture);
248            program->addShader(vertex_shader);
249        }
250        else
251        {
252
253            osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource);
254            program->addShader(fragment_shader);
255
256            osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource_texture2);
257            program->addShader(vertex_shader);
258        }
259       
260        osg::Texture2D* texture = new osg::Texture2D(osgDB::readImageFile(textureFileName));
261        stateset->setTextureAttributeAndModes(0,texture);
262
263        osg::Uniform* baseTextureSampler = new osg::Uniform("baseTexture",0);
264        stateset->addUniform(baseTextureSampler);
265
266    }
267
268
269    // set up geometry data.
270
271    osg::Vec3Array* vertices = new osg::Vec3Array( num_x * num_y );
272   
273    float dx = 1.0f/(float)(num_x-1);
274    float dy = 1.0f/(float)(num_y-1);
275    osg::Vec3 row(0.0f,0.0f,0.0);
276   
277    unsigned int vert_no = 0;
278    unsigned int iy;
279    for(iy=0; iy<num_y; ++iy)
280    {
281        osg::Vec3 column = row;
282        for(unsigned int ix=0;ix<num_x;++ix)
283        {
284            (*vertices)[vert_no++] = column;
285            column.x() += dx;
286        }       
287        row.y() += dy;
288    }
289
290    geom->setVertexArray(vertices);
291
292    unsigned int totalIndices = 0;
293    if (mesh=="triangles" || mesh=="tristrip")
294    {
295        if (cacheSize)
296        {
297            unsigned int index=0;
298            osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_TRIANGLES);
299            geom->addPrimitiveSet(elements);   
300            elements->dirty();
301           
302            for(unsigned int is=0; is<num_x; is += cacheSize-1)
303            {
304           
305                for(iy=0; iy<num_y-1; ++iy)
306                {
307                    unsigned int num_in_stripe = osg::minimum(cacheSize, num_x-is);
308                   
309                    bool rightToLeft = true;
310
311                    if (elements->size() > maxSize)
312                    {
313                        osg::notify(osg::NOTICE)<<"elements->size() = "<<elements->size()<<std::endl;
314                        totalIndices += elements->size();
315
316                        index=0;
317                        elements = new osg::DrawElementsUInt(GL_TRIANGLES);
318                        geom->addPrimitiveSet(elements);   
319                        elements->dirty();
320
321                    }
322
323                    if (rightToLeft)
324                    {
325
326                        index = iy * num_x + is;
327
328                        for(unsigned int ix = 0; ix<num_in_stripe-1; ++ix)
329                        {
330                            (*elements).push_back(index + num_x);
331                            (*elements).push_back(index);
332                            (*elements).push_back(index+1);
333
334                            (*elements).push_back(index + num_x);
335                            (*elements).push_back(index+1);
336                            (*elements).push_back(index + num_x + 1);
337
338                            ++index;
339                        }
340                    }
341                    else
342                    {
343                        index = iy * num_x + is + (num_x-2);
344
345                        for(unsigned int ix = 0; ix<num_in_stripe-1; ++ix)
346                        {
347                            (*elements).push_back(index + num_x);
348                            (*elements).push_back(index);
349                            (*elements).push_back(index+1);
350
351                            (*elements).push_back(index + num_x);
352                            (*elements).push_back(index+1);
353                            (*elements).push_back(index + num_x + 1);
354
355                            --index;
356                        }
357                    }
358                   
359                    rightToLeft = !rightToLeft;                   
360                   
361                }
362               
363            }
364            totalIndices += elements->size();
365            osg::notify(osg::NOTICE)<<"elements->size() = "<<elements->size()<<std::endl;
366        }
367        else
368        {
369            osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_TRIANGLES, (num_x-1)*(num_y-1)*6);
370            elements->dirty();
371            unsigned int element_no = 0;
372            for(iy=0; iy<num_y-1; ++iy)
373            {
374                unsigned int index = iy * num_x;
375                for(unsigned int ix = 0; ix<num_x-1; ++ix)
376                {
377                    (*elements)[element_no++] = index + num_x;
378                    (*elements)[element_no++] = index;
379                    (*elements)[element_no++] = index+1;
380
381                    (*elements)[element_no++] = index + num_x;
382                    (*elements)[element_no++] = index+1;
383                    (*elements)[element_no++] = index + num_x + 1;
384                   
385                    ++index;
386                }
387            }
388            geom->addPrimitiveSet(elements);   
389            osg::notify(osg::NOTICE)<<"elements->size() = "<<elements->size()<<std::endl;
390        }
391    }
392    else
393    {
394   
395        if (cacheSize)
396        {
397            bool needToJoin = false;
398            unsigned int index=0;
399            osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_TRIANGLE_STRIP);
400            geom->addPrimitiveSet(elements);   
401            elements->dirty();
402
403            for(unsigned int is=0; is<num_x; is += cacheSize-1)
404            {
405           
406                for(iy=0; iy<num_y-1; ++iy)
407                {
408                    unsigned int num_in_stripe = osg::minimum(cacheSize, num_x-is);
409                   
410                    bool rightToLeft = true;
411
412                    if (elements->size() > maxSize)
413                    {
414                        osg::notify(osg::NOTICE)<<"elements->size() = "<<elements->size()<<std::endl;
415
416                        totalIndices += elements->size();
417
418                        needToJoin = false;
419                        index=0;
420                        elements = new osg::DrawElementsUInt(GL_TRIANGLE_STRIP);
421                        geom->addPrimitiveSet(elements);   
422                        elements->dirty();
423
424                    }
425
426                    if (needToJoin) (*elements).push_back(elements->back());
427                   
428                    if (rightToLeft)
429                    {
430
431                        index = iy * num_x + is;
432
433                        if (needToJoin) (*elements).push_back(index + num_x);
434
435                        for(unsigned int ix = 0; ix<num_in_stripe; ++ix)
436                        {
437                            (*elements).push_back(index + num_x);
438                            (*elements).push_back(index++);
439                        }
440                    }
441                    else
442                    {
443                        index = iy * num_x + is + (num_x-1);
444
445                        if (needToJoin) (*elements).push_back(index);
446
447                        for(unsigned int ix = 0; ix<num_in_stripe; ++ix)
448                        {
449                            (*elements).push_back(index);
450                            (*elements).push_back(index-- + num_x);
451                        }
452                    }
453                   
454                    rightToLeft = !rightToLeft;                   
455                   
456                    needToJoin = true;
457                }
458               
459            }
460            totalIndices += elements->size();
461        }
462        else
463        {
464            osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_TRIANGLE_STRIP);
465            elements->dirty();
466            geom->addPrimitiveSet(elements);   
467            bool needToJoin = false;
468            unsigned int index=0;
469            for(iy=0; iy<num_y-1; ++iy)
470            {
471
472                if (needToJoin) (*elements).push_back(index-1);
473
474                index = iy * num_x;
475
476                if (needToJoin) (*elements).push_back(index + num_x);
477
478                for(unsigned int ix = 0; ix<num_x; ++ix)
479                {
480                    (*elements).push_back(index + num_x);
481                    (*elements).push_back(index++);
482                }
483                needToJoin = true;
484
485            }
486        }
487    }
488
489    osg::notify(osg::NOTICE)<<"totalIndices = "<<totalIndices<<std::endl;
490
491    if (mesh=="tristrip")
492    {   osgUtil::TriStripVisitor stripper;
493        stripper.stripify(*geom);
494    }
495
496#if 0
497    geom->setUseVertexBufferObjects(true);
498#else
499    geom->setUseVertexBufferObjects(false);
500#endif
501
502    return geode;
503}
504
505int main(int argc, char *argv[])
506{
507    // use an ArgumentParser object to manage the program arguments.
508    osg::ArgumentParser arguments(&argc,argv);
509
510    // set up the usage document, in case we need to print out how to use this program.
511    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrate support for ARB_vertex_program.");
512    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
513    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
514   
515    // construct the viewer.
516    osgViewer::Viewer viewer;
517
518    std::string shader("simple");
519    while(arguments.read("-s",shader)) {}
520   
521    std::string textureFileName("Images/lz.rgb");
522    while(arguments.read("-t",textureFileName)) {}
523
524    std::string terrainFileName("");
525    while(arguments.read("-d",terrainFileName)) {}
526
527    std::string terrainFileName2("");
528    while(arguments.read("-d2",terrainFileName2)) {}
529
530    unsigned int cacheSize = 0;
531    while(arguments.read("--cache",cacheSize)) {}
532
533    unsigned int maxSize = 2048;
534    while(arguments.read("--max",maxSize)) {}
535
536    std::string mesh("strip");
537    while(arguments.read("--mesh",mesh)) {}
538
539    bool joinStrips = false;
540    while(arguments.read("--join")) { joinStrips = true; }
541
542    // if user request help write it out to cout.
543    if (arguments.read("-h") || arguments.read("--help"))
544    {
545        arguments.getApplicationUsage()->write(std::cout);
546        return 1;
547    }
548
549    // load the nodes from the commandline arguments.
550    osg::Node* model = createModel(shader,textureFileName,terrainFileName,terrainFileName2, cacheSize, maxSize, joinStrips,mesh);
551    if (!model)
552    {
553        return 1;
554    }
555   
556    viewer.setSceneData(model);
557
558    return viewer.run();
559}
Note: See TracBrowser for help on using the browser.