root/branches/Carsten_PtrWork/Tutorials/22Shader.cpp

Revision 835, 9.2 kB (checked in by vossg, 1 year ago)

ported : cluster windows (basic port still need quite some testing and verification)
added : ptr mfield copy to containers
fixed : tutorial compile problems

  • Property svn:eol-style set to native
Line 
1 // OpenSG Tutorial Example: Shader
2 //
3 // This example shows how to use GLSL shaders.
4 // It creates a bouncing ball animation (completely calculated on the GPU).
5 // You need a graphics card supporting the GL_ARB_shading_language_100 extension
6 // to run this tutorial.
7
8 // Headers
9 #include <OpenSG/OSGGLUT.h>
10 #include <OpenSG/OSGConfig.h>
11 #include <OpenSG/OSGSimpleGeometry.h>
12 #include <OpenSG/OSGGLUTWindow.h>
13 #include <OpenSG/OSGSimpleSceneManager.h>
14 #include <OpenSG/OSGBaseFunctions.h>
15 #include <OpenSG/OSGTransform.h>
16 #include <OpenSG/OSGGroup.h>
17 #include <OpenSG/OSGPointLight.h>
18 #include <OpenSG/OSGRenderAction.h>
19 #include <OpenSG/OSGSceneFileHandler.h>
20
21 #include <OpenSG/OSGSimpleMaterial.h>
22 #include <OpenSG/OSGImage.h>
23 #include <OpenSG/OSGTextureObjChunk.h>
24 #include <OpenSG/OSGTextureEnvChunk.h>
25 #include <OpenSG/OSGGradientBackground.h>
26 #include <OpenSG/OSGSHLChunk.h>
27 //#include <OpenSG/OSGShadowMapViewport.h>
28
29 // Activate the OpenSG namespace
30 OSG_USING_NAMESPACE
31
32 // The SimpleSceneManager to manage simple applications
33 SimpleSceneManager *_mgr = NULL;
34 NodePtr _scene = NullFC;
35 SHLChunkPtr _shl = NullFC;
36
37 // vertex shader program.
38 static std::string _vp_program =
39 "uniform float groundHeight;\n"
40 "uniform float bounceMin;\n"
41 "uniform float bounceHeight;\n"
42 "uniform float bounceSpeed;\n"
43 "uniform float time;\n"
44 "uniform float squeezeHeight;\n"
45 "\n"
46 "// output variables to the fragment program.\n"
47 "varying vec3 vNormal;\n"
48 "varying vec3 vViewVec;\n"
49 "\n"
50 "void main(void)\n"
51 "{\n"
52 "   // Normalize and scale, just because the source\n"
53 "   // model is not a perfect sphere around origin\n"
54 "   vec3 pos = 5.0 * normalize(vec3(gl_Vertex));\n"
55 "\n"
56 "   // Basic Bounce\n"
57 "   float t = fract( time * bounceSpeed )  ;\n"
58 "   float center = bounceHeight * t * (1.0 - t);\n"
59 "\n"
60 "   pos.y += center + bounceMin;\n"
61 "\n"
62 "   // Squeeze\n"
63 "   if (pos.y < groundHeight)\n"
64 "   {\n"
65 "      // Squeeze in Z direction\n"
66 "      float squeeze = (1.0 - exp2(1.0 * (pos.y - groundHeight)));\n"
67 "      pos.y = groundHeight - squeeze * squeezeHeight;\n"
68 "\n"
69 "      // Flatten in XZ direcion\n"
70 "      vec2 xyNorm = vec2(normalize(vec3(gl_Normal.xy,1.0)));\n"
71 "      pos.xz += squeeze * xyNorm * squeezeHeight;\n"
72 "\n"
73 "   }\n"
74 "\n"
75 "   gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1.0);\n"
76 "\n"
77 "   // gl_NormalMatrix the inverse of the upper 3x3 of the view matrix.\n"
78 "   vNormal   =  gl_NormalMatrix  * gl_Normal;\n"
79 "\n"
80 "   vViewVec   = -vec3((gl_ModelViewMatrix * vec4(pos, 1.0)));\n"
81 "}\n";
82
83 // fragment shader program for bump mapping in surface local coordinates
84 static std::string _fp_program =
85 "uniform vec3 ballColor;\n"
86 "const vec4 lightDir = vec4(0.43644,-0.43644,-0.87287,1.0);\n"
87 "\n"
88 "// input variables from the vertex program.\n"
89 "varying vec3 vNormal;\n"
90 "varying vec3 vViewVec;\n"
91 "\n"
92 "void main(void)\n"
93 "{\n"
94 "   vec3 nLightVec = normalize(vec3(lightDir.x, lightDir.y, -lightDir.z));\n"
95 "   // Simple diffuse and specular\n"
96 "   vec3 nNormal = normalize(vNormal);  // nNormal = normalized normal\n"
97 "\n"
98 "   float diffuse = clamp( (dot(vNormal, nLightVec)) ,0.0 ,1.0 );\n"
99 "   vec3  reflectVec = reflect(-normalize(vViewVec), nNormal);\n"
100 "\n"
101 "   float specular = pow(clamp( dot(reflectVec, vec3(nLightVec)) ,0.0 ,1.0 ),32.0);\n"
102 "\n"
103 "\n"
104 "   gl_FragColor = vec4(ballColor, 1.0) * diffuse + 0.8 * specular;\n"
105 "}\n";
106
107 // forward declaration so we can have the interesting stuff upfront
108 int setupGLUT(int *argc, char *argv[]);
109
110 // redraw the window
111 void display(void)
112 {
113     static Real32 t = glutGet(GLUT_ELAPSED_TIME);
114
115     Real32 td = (glutGet(GLUT_ELAPSED_TIME) - t) / 100.0f;
116     _shl->setUniformParameter("time", td);
117
118     _mgr->redraw();
119 }
120
121
122 // Initialize GLUT & OpenSG and set up the scene
123 int main(int argc, char **argv)
124 {
125     // OSG init
126     osgInit(argc,argv);
127
128     // GLUT init
129     int winid = setupGLUT(&argc, argv);
130
131     // create the scene
132     _scene = makeCoredNode<Group>();
133
134     // create light
135     TransformPtr point1_trans;
136     PointLightPtr point1_core;
137     NodePtr point1 = makeCoredNode<PointLight>(&point1_core);
138     NodePtr point1_beacon = makeCoredNode<Transform>(&point1_trans);
139     point1_trans->editMatrix().setTranslate(0.0, 100.0, 0.0);
140
141     point1_core->setAmbient(0.15,0.15,0.15,1);
142     point1_core->setDiffuse(0.8,0.8,0.8,1);
143     point1_core->setSpecular(0.0,0.0,0.0,1);
144     point1_core->setBeacon(point1_beacon);
145     point1_core->setOn(true);
146
147     // create bottom
148     NodePtr bottom = makePlane(50.0, 50.0, 128, 128);
149    
150     UChar8 imgdata[] =
151         {  255,0,0,  0,255,0,  0,0,255, 255,255,0 };
152     ImagePtr bottom_img = Image::create();
153     bottom_img->set(Image::OSG_RGB_PF, 2, 2, 1, 1, 1, 0, imgdata);
154
155     TextureObjChunkPtr bottom_tex     = TextureObjChunk::create();
156     TextureEnvChunkPtr bottom_tex_env = TextureEnvChunk::create();
157
158     bottom_tex->setImage(bottom_img);
159     bottom_tex->setMinFilter(GL_LINEAR);
160     bottom_tex->setMagFilter(GL_LINEAR);
161     bottom_tex->setWrapS(GL_REPEAT);
162     bottom_tex->setWrapT(GL_REPEAT);
163     bottom_tex_env->setEnvMode(GL_MODULATE);
164
165     SimpleMaterialPtr bottom_mat = SimpleMaterial::create();
166     bottom_mat->setAmbient(Color3f(0.3,0.3,0.3));
167     bottom_mat->setDiffuse(Color3f(1.0,1.0,1.0));
168     bottom_mat->addChunk(bottom_tex);
169     bottom_mat->addChunk(bottom_tex_env);
170    
171     GeometryPtr bottom_geo = dynamic_cast<GeometryPtr>(bottom->getCore());
172     bottom_geo->setMaterial(bottom_mat);
173    
174     // rotate the bottom about 90 degree.
175     TransformPtr bottom_trans_core;
176     NodePtr bottom_trans = makeCoredNode<Transform>(&bottom_trans_core);
177     Quaternion q;
178     q.setValueAsAxisDeg(1, 0, 0, -90);
179     bottom_trans_core->editMatrix().setRotate(q);
180     bottom_trans->addChild(bottom);
181
182     // create a sphere.
183     NodePtr sphere = makeLatLongSphere(50, 50, 1.0);
184    
185     // create the shader material
186     ChunkMaterialPtr cmat = ChunkMaterial::create();
187     _shl = SHLChunk::create();
188     _shl->setVertexProgram(_vp_program);
189     _shl->setFragmentProgram(_fp_program);
190     _shl->setUniformParameter("groundHeight", 1.0f);
191     _shl->setUniformParameter("bounceMin", -0.1f);
192     _shl->setUniformParameter("bounceHeight", 75.0f);
193     _shl->setUniformParameter("bounceSpeed", 0.05f);
194     _shl->setUniformParameter("time", 0.0f);
195     _shl->setUniformParameter("squeezeHeight", 1.0f);
196     _shl->setUniformParameter("ballColor", Vec3f(1.0f, 0.0f, 0.0f));
197
198     cmat->addChunk(_shl);
199
200     GeometryPtr spheregeo = dynamic_cast<GeometryPtr>(sphere->getCore());
201     spheregeo->setMaterial(cmat);
202
203     point1->addChild(bottom_trans);
204     point1->addChild(sphere);
205
206     _scene->addChild(point1_beacon);
207     _scene->addChild(point1);
208
209     // create ShadowViewport with a gradient background.
210     //ShadowMapViewportPtr svp = ShadowMapViewport::create();
211     GradientBackgroundPtr gbg = GradientBackground::create();
212
213     gbg->addLine(Color3f(0.7, 0.7, 0.8), 0);
214     gbg->addLine(Color3f(0.0, 0.1, 0.3), 1);
215
216     // Shadow viewport
217     //svp->setBackground(gbg);
218     //svp->setRoot(_scene);
219     //svp->setSize(0,0,1,1);
220     //svp->setOffFactor(10.0);
221     //svp->setOffBias(4.0);
222     //svp->setShadowColor(Color4f(0.1, 0.1, 0.1, 1.0));
223     //svp->setMapSize(1024);
224     // you can add the light sources here, as default all light source in
225     // the scenegraph are used.
226     //svp->getLightNodes().push_back(point1);
227
228     // the connection between GLUT and OpenSG
229     GLUTWindowPtr gwin= GLUTWindow::create();
230     gwin->setGlutId(winid);
231     //gwin->addPort(svp);
232     gwin->init();
233
234     commitChanges();
235
236     // create the SimpleSceneManager helper
237     _mgr = new SimpleSceneManager;
238
239     // tell the manager what to manage
240     _mgr->setWindow(gwin );
241     _mgr->setRoot  (_scene);
242
243     //svp->setCamera(_mgr->getCamera());
244
245     _mgr->turnHeadlightOff();
246
247     // show the whole scene
248     _mgr->showAll();
249     _mgr->getNavigator()->setFrom(Pnt3f(0.0, 31, 47));
250
251     // GLUT main loop
252     glutMainLoop();
253
254     return 0;
255 }
256
257 //
258 // GLUT callback functions
259 //
260
261 // react to size changes
262 void reshape(int w, int h)
263 {
264     _mgr->resize(w, h);
265     glutPostRedisplay();
266 }
267
268 // react to mouse button presses
269 void mouse(int button, int state, int x, int y)
270 {
271     if (state)
272         _mgr->mouseButtonRelease(button, x, y);
273     else
274         _mgr->mouseButtonPress(button, x, y);
275        
276     glutPostRedisplay();
277 }
278
279 // react to mouse motions with pressed buttons
280 void motion(int x, int y)
281 {
282     _mgr->mouseMove(x, y);
283     glutPostRedisplay();
284 }
285
286 // react to keys
287 void keyboard(unsigned char k, int x, int y)
288 {
289     switch(k)
290     {
291         case 27:
292             OSG::osgExit();
293             exit(0);
294         break;
295         case 'w':
296             SceneFileHandler::the()->write(_scene, "scene.osb.gz", true);
297             printf("wrote scene.\n");
298         break;
299
300         case 's':
301         {
302             _mgr->setStatistics(!_mgr->getStatistics());
303         }
304         break;
305     }
306 }
307
308 // setup the GLUT library which handles the windows for us
309 int setupGLUT(int *argc, char *argv[])
310 {
311     glutInit(argc, argv);
312     glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
313    
314     int winid = glutCreateWindow("OpenSG");
315    
316     glutReshapeFunc(reshape);
317     glutDisplayFunc(display);
318     glutMouseFunc(mouse);
319     glutMotionFunc(motion);
320     glutKeyboardFunc(keyboard);
321
322     // call the redraw function whenever there's nothing else to do
323     glutIdleFunc(display);
324
325     return winid;
326 }
Note: See TracBrowser for help on using the browser.