fixed: compile issue
[opensg.git] / Examples / Simple / shader.cpp
blob318a590b97434d2e0a61521aac6905cd4df1bdaf
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.
8 #ifdef OSG_BUILD_ACTIVE
9 // Headers
10 #include <OSGGLUT.h>
11 #include <OSGConfig.h>
12 #include <OSGSimpleGeometry.h>
13 #include <OSGGLUTWindow.h>
14 #include <OSGSimpleSceneManager.h>
15 #include <OSGBaseFunctions.h>
16 #include <OSGTransform.h>
17 #include <OSGGroup.h>
18 #include <OSGPointLight.h>
19 #include <OSGRenderAction.h>
20 #include <OSGSceneFileHandler.h>
22 #include <OSGSimpleMaterial.h>
23 #include <OSGImage.h>
24 #include <OSGTextureObjChunk.h>
25 #include <OSGTextureEnvChunk.h>
26 #include <OSGGradientBackground.h>
27 #include <OSGSimpleSHLChunk.h>
28 #else
29 // Headers
30 #include <OpenSG/OSGGLUT.h>
31 #include <OpenSG/OSGConfig.h>
32 #include <OpenSG/OSGSimpleGeometry.h>
33 #include <OpenSG/OSGGLUTWindow.h>
34 #include <OpenSG/OSGSimpleSceneManager.h>
35 #include <OpenSG/OSGBaseFunctions.h>
36 #include <OpenSG/OSGTransform.h>
37 #include <OpenSG/OSGGroup.h>
38 #include <OpenSG/OSGPointLight.h>
39 #include <OpenSG/OSGRenderAction.h>
40 #include <OpenSG/OSGSceneFileHandler.h>
42 #include <OpenSG/OSGSimpleMaterial.h>
43 #include <OpenSG/OSGImage.h>
44 #include <OpenSG/OSGTextureObjChunk.h>
45 #include <OpenSG/OSGTextureEnvChunk.h>
46 #include <OpenSG/OSGGradientBackground.h>
47 #include <OpenSG/OSGSimpleSHLChunk.h>
48 #endif
50 using namespace OSG;
52 // The SimpleSceneManager to manage simple applications
53 SimpleSceneManagerRefPtr _mgr = NULL;
54 NodeRefPtr _scene;
55 SimpleSHLChunkRefPtr _shl;
57 // vertex shader program.
58 static std::string _vp_program =
59 "uniform float groundHeight;\n"
60 "uniform float bounceMin;\n"
61 "uniform float bounceHeight;\n"
62 "uniform float bounceSpeed;\n"
63 "uniform float time;\n"
64 "uniform float squeezeHeight;\n"
65 "\n"
66 "// output variables to the fragment program.\n"
67 "varying vec3 vNormal;\n"
68 "varying vec3 vViewVec;\n"
69 "\n"
70 "void main(void)\n"
71 "{\n"
72 " // Normalize and scale, just because the source\n"
73 " // model is not a perfect sphere around origin\n"
74 " vec3 pos = 5.0 * normalize(vec3(gl_Vertex));\n"
75 "\n"
76 " // Basic Bounce\n"
77 " float t = fract( time * bounceSpeed ) ;\n"
78 " float center = bounceHeight * t * (1.0 - t);\n"
79 "\n"
80 " pos.y += center + bounceMin;\n"
81 "\n"
82 " // Squeeze\n"
83 " if (pos.y < groundHeight)\n"
84 " {\n"
85 " // Squeeze in Z direction\n"
86 " float squeeze = (1.0 - exp2(1.0 * (pos.y - groundHeight)));\n"
87 " pos.y = groundHeight - squeeze * squeezeHeight;\n"
88 "\n"
89 " // Flatten in XZ direcion\n"
90 " vec2 xyNorm = vec2(normalize(vec3(gl_Normal.xy,1.0)));\n"
91 " pos.xz += squeeze * xyNorm * squeezeHeight;\n"
92 "\n"
93 " }\n"
94 "\n"
95 " gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1.0);\n"
96 "\n"
97 " // gl_NormalMatrix the inverse of the upper 3x3 of the view matrix.\n"
98 " vNormal = gl_NormalMatrix * gl_Normal;\n"
99 "\n"
100 " vViewVec = -vec3((gl_ModelViewMatrix * vec4(pos, 1.0)));\n"
101 "}\n";
103 // fragment shader program for bump mapping in surface local coordinates
104 static std::string _fp_program =
105 "uniform vec3 ballColor;\n"
106 "const vec4 lightDir = vec4(0.43644,-0.43644,-0.87287,1.0);\n"
107 "\n"
108 "// input variables from the vertex program.\n"
109 "varying vec3 vNormal;\n"
110 "varying vec3 vViewVec;\n"
111 "\n"
112 "void main(void)\n"
113 "{\n"
114 " vec3 nLightVec = normalize(vec3(lightDir.x, lightDir.y, -lightDir.z));\n"
115 " // Simple diffuse and specular\n"
116 " vec3 nNormal = normalize(vNormal); // nNormal = normalized normal\n"
117 "\n"
118 " float diffuse = clamp( (dot(vNormal, nLightVec)) ,0.0 ,1.0 );\n"
119 " vec3 reflectVec = reflect(-normalize(vViewVec), nNormal);\n"
120 "\n"
121 " float specular = pow(clamp( dot(reflectVec, vec3(nLightVec)) ,0.0 ,1.0 ),32.0);\n"
122 "\n"
123 "\n"
124 " gl_FragColor = vec4(ballColor, 1.0) * diffuse + 0.8 * specular;\n"
125 "}\n";
127 // forward declaration so we can have the interesting stuff upfront
128 int setupGLUT(int *argc, char *argv[]);
130 // redraw the window
131 void display(void)
133 static Real32 t = glutGet(GLUT_ELAPSED_TIME);
135 Real32 td = (glutGet(GLUT_ELAPSED_TIME) - t) / 100.0f;
136 _shl->updateUniformVariable("time", td);
138 _mgr->redraw();
142 // Initialize GLUT & OpenSG and set up the scene
143 int main(int argc, char **argv)
145 // OSG init
146 osgInit(argc,argv);
148 // GLUT init
149 int winid = setupGLUT(&argc, argv);
151 // open a new scope, because the pointers below should go out of scope
152 // before entering glutMainLoop.
153 // Otherwise OpenSG will complain about objects being alive after shutdown.
155 // create the scene
156 _scene = makeCoredNode<Group>();
158 // create light
159 TransformRefPtr point1_trans;
160 PointLightRefPtr point1_core;
161 NodeRefPtr point1 = makeCoredNode<PointLight>(&point1_core );
162 NodeRefPtr point1_beacon = makeCoredNode<Transform >(&point1_trans);
163 point1_trans->editMatrix().setTranslate(0.0, 100.0, 0.0);
165 point1_core->setAmbient (0.15f,0.15f,0.15f,1.f);
166 point1_core->setDiffuse (0.8f, 0.8f, 0.8f, 1.f);
167 point1_core->setSpecular(0.0f, 0.0f, 0.0f, 1.f);
168 point1_core->setBeacon(point1_beacon);
169 point1_core->setOn(true);
171 // create bottom
172 NodeRefPtr bottom = makePlane(50.0, 50.0, 128, 128);
174 UChar8 imgdata[] =
175 { 255,0,0, 0,255,0, 0,0,255, 255,255,0 };
176 ImageRefPtr bottom_img = Image::create();
177 bottom_img->set(Image::OSG_RGB_PF, 2, 2, 1, 1, 1, 0, imgdata);
179 TextureObjChunkRefPtr bottom_tex = TextureObjChunk::create();
180 TextureEnvChunkRefPtr bottom_tex_env = TextureEnvChunk::create();
182 bottom_tex->setImage(bottom_img);
183 bottom_tex->setMinFilter(GL_LINEAR);
184 bottom_tex->setMagFilter(GL_LINEAR);
185 bottom_tex->setWrapS(GL_REPEAT);
186 bottom_tex->setWrapT(GL_REPEAT);
187 bottom_tex_env->setEnvMode(GL_MODULATE);
189 SimpleMaterialRefPtr bottom_mat = SimpleMaterial::create();
190 bottom_mat->setAmbient(Color3f(0.3f,0.3f,0.3f));
191 bottom_mat->setDiffuse(Color3f(1.0f,1.0f,1.0f));
192 bottom_mat->addChunk(bottom_tex);
193 bottom_mat->addChunk(bottom_tex_env);
195 GeometryRefPtr bottom_geo = dynamic_cast<Geometry *>(bottom->getCore());
196 bottom_geo->setMaterial(bottom_mat);
198 // rotate the bottom about 90 degree.
199 TransformRefPtr bottom_trans_core;
200 NodeRefPtr bottom_trans = makeCoredNode<Transform>(&bottom_trans_core);
201 Quaternion q;
202 q.setValueAsAxisDeg(1, 0, 0, -90);
203 bottom_trans_core->editMatrix().setRotate(q);
204 bottom_trans->addChild(bottom);
206 // create a sphere.
207 NodeRefPtr sphere = makeLatLongSphere(50, 50, 1.0);
209 // create the shader material
210 ChunkMaterialRefPtr cmat = ChunkMaterial::create();
211 _shl = SimpleSHLChunk::create();
212 _shl->setVertexProgram (_vp_program);
213 _shl->setFragmentProgram(_fp_program);
214 _shl->addUniformVariable("groundHeight", 1.0f);
215 _shl->addUniformVariable("bounceMin", -0.1f);
216 _shl->addUniformVariable("bounceHeight", 75.0f);
217 _shl->addUniformVariable("bounceSpeed", 0.05f);
218 _shl->addUniformVariable("time", 0.0f);
219 _shl->addUniformVariable("squeezeHeight", 1.0f);
220 _shl->addUniformVariable("ballColor", Vec3f(1.0f, 0.0f, 0.0f));
222 cmat->addChunk(_shl);
224 GeometryRefPtr spheregeo = dynamic_cast<Geometry *>(sphere->getCore());
225 spheregeo->setMaterial(cmat);
227 point1->addChild(bottom_trans);
228 point1->addChild(sphere);
230 _scene->addChild(point1_beacon);
231 _scene->addChild(point1);
233 // the connection between GLUT and OpenSG
234 GLUTWindowRefPtr gwin = GLUTWindow::create();
235 gwin->setGlutId(winid);
236 gwin->init();
238 commitChanges();
240 // create the SimpleSceneManager helper
241 _mgr = SimpleSceneManager::create();
243 // tell the manager what to manage
244 _mgr->setWindow(gwin );
245 _mgr->setRoot (_scene);
247 //svp->setCamera(_mgr->getCamera());
249 _mgr->turnHeadlightOff();
251 // show the whole scene
252 _mgr->showAll();
253 _mgr->getNavigator()->setFrom(Pnt3f(0.0, 31, 47));
256 // GLUT main loop
257 glutMainLoop();
259 return 0;
263 // GLUT callback functions
266 // react to size changes
267 void reshape(int w, int h)
269 _mgr->resize(w, h);
270 glutPostRedisplay();
273 // react to mouse button presses
274 void mouse(int button, int state, int x, int y)
276 if (state)
277 _mgr->mouseButtonRelease(button, x, y);
278 else
279 _mgr->mouseButtonPress(button, x, y);
281 glutPostRedisplay();
284 // react to mouse motions with pressed buttons
285 void motion(int x, int y)
287 _mgr->mouseMove(x, y);
288 glutPostRedisplay();
291 // react to keys
292 void keyboard(unsigned char k, int x, int y)
294 switch(k)
296 case 27:
297 // clean up global variables
298 _mgr = NULL;
299 _scene = NULL;
300 _shl = NULL;
302 OSG::osgExit();
303 exit(0);
304 break;
305 case 'w':
306 SceneFileHandler::the()->write(_scene, "scene.osb.gz", true);
307 printf("wrote scene.\n");
308 break;
310 case 's':
312 _mgr->setStatistics(!_mgr->getStatistics());
314 break;
318 // setup the GLUT library which handles the windows for us
319 int setupGLUT(int *argc, char *argv[])
321 glutInit(argc, argv);
322 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
324 int winid = glutCreateWindow("OpenSG");
326 glutReshapeFunc(reshape);
327 glutDisplayFunc(display);
328 glutMouseFunc(mouse);
329 glutMotionFunc(motion);
330 glutKeyboardFunc(keyboard);
332 // call the redraw function whenever there's nothing else to do
333 glutIdleFunc(display);
335 return winid;