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

Revision 4345, 5.6 kB (checked in by robert, 9 years ago)

Added very simply osgparametric example which uses an OpenGL shader program
to create an animated parametric surface.

  • 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
15#include <osgProducer/Viewer>
16
17char vertexShaderSource[] =
18    "uniform vec2  xCoeff; \n"
19    "uniform vec2  yCoeff; \n"
20    "\n"
21    "void main(void) \n"
22    "{ \n"
23    "\n"
24    "    gl_TexCoord[0] = gl_Vertex; \n"
25    "    gl_Vertex.z = gl_Vertex.x*xCoeff[0] + gl_Vertex.x*gl_Vertex.x* xCoeff[1] + \n"
26    "                  gl_Vertex.y*yCoeff[1] + gl_Vertex.y*gl_Vertex.y* yCoeff[1]; \n"
27    "    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
28    "}\n";
29   
30char fragmentShaderSource[] =
31    "uniform sampler2D baseTexture; \n"
32    "\n"
33    "void main(void) \n"
34    "{ \n"
35    "    gl_FragColor = texture2D( baseTexture, gl_TexCoord[0].xy); \n"
36    "}\n";
37
38
39class UniformVarying : public osg::Uniform::Callback
40{
41    virtual void operator () (osg::Uniform* uniform, osg::NodeVisitor* nv)
42    {
43        const osg::FrameStamp* fs = nv->getFrameStamp();
44        float value = sinf(fs->getReferenceTime());
45        uniform->set(osg::Vec2(value,-value));
46    }
47};
48
49osg::Node* createModel()
50{
51    osg::Geode* geode = new osg::Geode;
52   
53    osg::Geometry* geom = new osg::Geometry;
54    geode->addDrawable(geom);
55   
56    // dimensions for ~one million triangles :-)
57    unsigned int num_x = 708;
58    unsigned int num_y = 708;
59
60    osg::Vec3Array* vertices = new osg::Vec3Array( num_x * num_y );
61   
62    float dx = 1.0f/(float)(num_x-1);
63    float dy = 1.0f/(float)(num_y-1);
64    osg::Vec3 row(0.0f,0.0f,0.0);
65   
66    unsigned int vert_no = 0;
67    for(unsigned int iy=0; iy<num_y; ++iy)
68    {
69        osg::Vec3 column = row;
70        for(unsigned int ix=0;ix<num_x;++ix)
71        {
72            (*vertices)[vert_no++] = column;
73            column.x() += dx;
74        }       
75        row.y() += dy;
76    }
77
78    geom->setVertexArray(vertices);
79
80    for(unsigned int iy=0; iy<num_y-1; ++iy)
81    {
82        unsigned int element_no = 0;
83        osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_TRIANGLE_STRIP, num_x*2);
84        unsigned int index = iy * num_x;
85        for(unsigned int ix = 0; ix<num_x; ++ix)
86        {
87            (*elements)[element_no++] = index + num_x;
88            (*elements)[element_no++] = index++;
89        }
90        geom->addPrimitiveSet(elements);   
91    }
92   
93    geom->setUseVertexBufferObjects(true);
94   
95   
96    osg::StateSet* stateset = geom->getOrCreateStateSet();
97
98    osg::Program* program = new osg::Program;
99    stateset->setAttribute(program);
100
101    osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource);
102    program->addShader(vertex_shader);
103   
104
105    osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource);
106    program->addShader(fragment_shader);
107
108
109    osg::Uniform* xCoeff = new osg::Uniform("xCoeff",osg::Vec2(1.0,-1.0f));
110    xCoeff->setUpdateCallback(new UniformVarying);
111    stateset->addUniform(xCoeff);
112
113    osg::Uniform* yCoeff = new osg::Uniform("yCoeff",osg::Vec2(-1.0f,1.0f));
114    stateset->addUniform(yCoeff);
115   
116   
117    stateset->setTextureAttributeAndModes(0,new osg::Texture2D(osgDB::readImageFile("lz.rgb")));
118
119    osg::Uniform* baseTextureSampler = new osg::Uniform("baseTexture",0);
120    stateset->addUniform(baseTextureSampler);
121   
122    return geode;
123
124}
125
126int main(int argc, char *argv[])
127{
128    // use an ArgumentParser object to manage the program arguments.
129    osg::ArgumentParser arguments(&argc,argv);
130
131    // set up the usage document, in case we need to print out how to use this program.
132    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrate support for ARB_vertex_program.");
133    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
134    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
135   
136    // construct the viewer.
137    osgProducer::Viewer viewer(arguments);
138
139    // set up the value with sensible default event handlers.
140    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
141
142    // get details on keyboard and mouse bindings used by the viewer.
143    viewer.getUsage(*arguments.getApplicationUsage());
144
145    // if user request help write it out to cout.
146    if (arguments.read("-h") || arguments.read("--help"))
147    {
148        arguments.getApplicationUsage()->write(std::cout);
149        return 1;
150    }
151
152    // any option left unread are converted into errors to write out later.
153    arguments.reportRemainingOptionsAsUnrecognized();
154
155    // report any errors if they have occured when parsing the program aguments.
156    if (arguments.errors())
157    {
158        arguments.writeErrorMessages(std::cout);
159        return 1;
160    }
161
162    // load the nodes from the commandline arguments.
163    osg::Node* model = createModel();
164    if (!model)
165    {
166        return 1;
167    }
168
169    // add a viewport to the viewer and attach the scene graph.
170    viewer.setSceneData(model);
171   
172    // create the windows and run the threads.
173    viewer.realize();
174
175    while( !viewer.done() )
176    {
177        // wait for all cull and draw threads to complete.
178        viewer.sync();
179
180        // update the scene by traversing it with the the update visitor which will
181        // call all node update callbacks and animations.
182        viewer.update();
183         
184        // fire off the cull and draw traversals of the scene.
185        viewer.frame();
186       
187    }
188   
189    // wait for all cull and draw threads to complete before exit.
190    viewer.sync();
191
192    return 0;
193}
Note: See TracBrowser for help on using the browser.