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

Revision 1039, 9.4 kB (checked in by cneumann, 11 months ago)

changed: - factory functions return a TransitPtr? that can not be implicitly

converted to C Ptr. Should help with porting.

added: - GlobalRefPtr?, needed for cases where upon return from main

a RefPtr? goes out of scope (it would attempt to access the
FCFactory which is already shutdown at that point).

status: - vrml loader does not compile (needs porting to ref ptr)

  • tutorials compile, run and exit cleanly
  • multithreading and cluster are untested, yet
  • 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 NodeGlobalRefPtr     _scene;
35 SHLChunkGlobalRefPtr _shl;
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      
117     _shl->setUniformParameter("time", td);
118
119     _mgr->redraw();
120 }
121
122
123 // Initialize GLUT & OpenSG and set up the scene
124 int main(int argc, char **argv)
125 {
126     // OSG init
127     osgInit(argc,argv);
128
129     // GLUT init
130     int winid = setupGLUT(&argc, argv);
131
132     // create the scene
133     _scene = makeCoredNode<Group>();
134
135     // create light
136     TransformGlobalRefPtr point1_trans;
137     PointLightGlobalRefPtr point1_core;
138     NodeGlobalRefPtr point1 = makeCoredNode<PointLight>(&point1_core);
139     NodeGlobalRefPtr point1_beacon = makeCoredNode<Transform>(&point1_trans);
140     point1_trans->editMatrix().setTranslate(0.0, 100.0, 0.0);
141
142     point1_core->setAmbient(0.15,0.15,0.15,1);
143     point1_core->setDiffuse(0.8,0.8,0.8,1);
144     point1_core->setSpecular(0.0,0.0,0.0,1);
145     point1_core->setBeacon(point1_beacon);
146     point1_core->setOn(true);
147
148     // create bottom
149     NodeGlobalRefPtr bottom = makePlane(50.0, 50.0, 128, 128);
150    
151     UChar8 imgdata[] =
152         {  255,0,0,  0,255,0,  0,0,255, 255,255,0 };
153     ImageGlobalRefPtr bottom_img = Image::create();
154     bottom_img->set(Image::OSG_RGB_PF, 2, 2, 1, 1, 1, 0, imgdata);
155
156     TextureObjChunkGlobalRefPtr bottom_tex     = TextureObjChunk::create();
157     TextureEnvChunkGlobalRefPtr bottom_tex_env = TextureEnvChunk::create();
158
159     bottom_tex->setImage(bottom_img);
160     bottom_tex->setMinFilter(GL_LINEAR);
161     bottom_tex->setMagFilter(GL_LINEAR);
162     bottom_tex->setWrapS(GL_REPEAT);
163     bottom_tex->setWrapT(GL_REPEAT);
164     bottom_tex_env->setEnvMode(GL_MODULATE);
165
166     SimpleMaterialGlobalRefPtr bottom_mat = SimpleMaterial::create();
167     bottom_mat->setAmbient(Color3f(0.3,0.3,0.3));
168     bottom_mat->setDiffuse(Color3f(1.0,1.0,1.0));
169     bottom_mat->addChunk(bottom_tex);
170     bottom_mat->addChunk(bottom_tex_env);
171    
172     GeometryGlobalRefPtr bottom_geo(dynamic_cast<GeometryPtr>(bottom->getCore()));
173     bottom_geo->setMaterial(bottom_mat);
174    
175     // rotate the bottom about 90 degree.
176     TransformGlobalRefPtr bottom_trans_core;
177     NodeGlobalRefPtr bottom_trans = makeCoredNode<Transform>(&bottom_trans_core);
178     Quaternion q;
179     q.setValueAsAxisDeg(1, 0, 0, -90);
180     bottom_trans_core->editMatrix().setRotate(q);
181     bottom_trans->addChild(bottom);
182
183     // create a sphere.
184     NodeGlobalRefPtr sphere = makeLatLongSphere(50, 50, 1.0);
185    
186     // create the shader material
187     ChunkMaterialGlobalRefPtr cmat = ChunkMaterial::create();
188     _shl = SHLChunk::create();
189     _shl->setVertexProgram(_vp_program);
190     _shl->setFragmentProgram(_fp_program);
191     _shl->setUniformParameter("groundHeight", 1.0f);
192     _shl->setUniformParameter("bounceMin", -0.1f);
193     _shl->setUniformParameter("bounceHeight", 75.0f);
194     _shl->setUniformParameter("bounceSpeed", 0.05f);
195     _shl->setUniformParameter("time", 0.0f);
196     _shl->setUniformParameter("squeezeHeight", 1.0f);
197     _shl->setUniformParameter("ballColor", Vec3f(1.0f, 0.0f, 0.0f));
198
199     cmat->addChunk(_shl);
200
201     GeometryGlobalRefPtr spheregeo(dynamic_cast<GeometryPtr>(sphere->getCore()));
202     spheregeo->setMaterial(cmat);
203
204     point1->addChild(bottom_trans);
205     point1->addChild(sphere);
206
207     _scene->addChild(point1_beacon);
208     _scene->addChild(point1);
209
210     // create ShadowViewport with a gradient background.
211     //ShadowMapViewportPtr svp = ShadowMapViewport::create();
212     GradientBackgroundGlobalRefPtr gbg = GradientBackground::create();
213
214     gbg->addLine(Color3f(0.7, 0.7, 0.8), 0);
215     gbg->addLine(Color3f(0.0, 0.1, 0.3), 1);
216
217     // Shadow viewport
218     //svp->setBackground(gbg);
219     //svp->setRoot(_scene);
220     //svp->setSize(0,0,1,1);
221     //svp->setOffFactor(10.0);
222     //svp->setOffBias(4.0);
223     //svp->setShadowColor(Color4f(0.1, 0.1, 0.1, 1.0));
224     //svp->setMapSize(1024);
225     // you can add the light sources here, as default all light source in
226     // the scenegraph are used.
227     //svp->getLightNodes().push_back(point1);
228
229     // the connection between GLUT and OpenSG
230     GLUTWindowGlobalRefPtr gwin = GLUTWindow::create();
231     gwin->setGlutId(winid);
232     //gwin->addPort(svp);
233     gwin->init();
234
235     commitChanges();
236
237     // create the SimpleSceneManager helper
238     _mgr = new SimpleSceneManager;
239
240     // tell the manager what to manage
241     _mgr->setWindow(gwin );
242     _mgr->setRoot  (_scene);
243
244     //svp->setCamera(_mgr->getCamera());
245
246     _mgr->turnHeadlightOff();
247
248     // show the whole scene
249     _mgr->showAll();
250     _mgr->getNavigator()->setFrom(Pnt3f(0.0, 31, 47));
251
252     // GLUT main loop
253     glutMainLoop();
254
255     return 0;
256 }
257
258 //
259 // GLUT callback functions
260 //
261
262 // react to size changes
263 void reshape(int w, int h)
264 {
265     _mgr->resize(w, h);
266     glutPostRedisplay();
267 }
268
269 // react to mouse button presses
270 void mouse(int button, int state, int x, int y)
271 {
272     if (state)
273         _mgr->mouseButtonRelease(button, x, y);
274     else
275         _mgr->mouseButtonPress(button, x, y);
276        
277     glutPostRedisplay();
278 }
279
280 // react to mouse motions with pressed buttons
281 void motion(int x, int y)
282 {
283     _mgr->mouseMove(x, y);
284     glutPostRedisplay();
285 }
286
287 // react to keys
288 void keyboard(unsigned char k, int x, int y)
289 {
290     switch(k)
291     {
292         case 27:
293             delete _mgr;
294        
295             OSG::osgExit();
296             exit(0);
297         break;
298         case 'w':
299             SceneFileHandler::the()->write(_scene, "scene.osb.gz", true);
300             printf("wrote scene.\n");
301         break;
302
303         case 's':
304         {
305             _mgr->setStatistics(!_mgr->getStatistics());
306         }
307         break;
308     }
309 }
310
311 // setup the GLUT library which handles the windows for us
312 int setupGLUT(int *argc, char *argv[])
313 {
314     glutInit(argc, argv);
315     glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
316    
317     int winid = glutCreateWindow("OpenSG");
318    
319     glutReshapeFunc(reshape);
320     glutDisplayFunc(display);
321     glutMouseFunc(mouse);
322     glutMotionFunc(motion);
323     glutKeyboardFunc(keyboard);
324
325     // call the redraw function whenever there's nothing else to do
326     glutIdleFunc(display);
327
328     return winid;
329 }
Note: See TracBrowser for help on using the browser.