changed: gcc8 base update
[opensg.git] / Source / System / State / Shader / SHL / testSHLOSGLights.cpp
blob59e84218bf9e727c8535eb773e436e7a0ed62276
1 // OpenSG example: testSHL
2 //
3 // Demonstrates the use of the SHLChunk
4 // Implements a simple bumpmapping via vertex and fragment shader.
6 // Headers
7 #include "OSGGLUT.h"
8 #include "OSGConfig.h"
9 #include "OSGSimpleGeometry.h"
10 #include "OSGGLUT.h"
11 #include "OSGGLUTWindow.h"
12 #include "OSGSimpleSceneManager.h"
13 #include "OSGAction.h"
14 #include "OSGSceneFileHandler.h"
15 #include "OSGBaseFunctions.h"
17 #include "OSGNode.h"
18 #include "OSGGroup.h"
19 #include "OSGTransform.h"
20 #include "OSGPointLight.h"
22 #include "OSGImage.h"
23 #include "OSGChunkMaterial.h"
24 #include "OSGMaterialChunk.h"
25 #include "OSGSimpleSHLChunk.h"
27 // vertex shader program for bump mapping in surface local coordinates
28 static std::string _vp_program =
29 "uniform bool OSGLight0Active;\n"
30 "uniform bool OSGLight1Active;\n"
31 "uniform bool OSGLight2Active;\n"
32 "vec4 Ambient;\n"
33 "vec4 Diffuse;\n"
34 "vec4 Specular;\n"
35 "\n"
36 "\n"
37 " void pointLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3)\n"
38 " {\n"
39 " float nDotVP; // normal . light direction\n"
40 " float nDotHV; // normal . light half vector\n"
41 " float pf; // power factor\n"
42 " float attenuation; // computed attenuation factor\n"
43 " float d; // distance from surface to light source\n"
44 " vec3 VP; // direction from surface to light position\n"
45 " vec3 halfVector; // direction of maximum highlights\n"
46 "\n"
47 " // Compute vector from surface to light position\n"
48 " VP = vec3 (gl_LightSource[i].position) - ecPosition3;\n"
49 "\n"
50 " // Compute distance between surface and light position\n"
51 " d = length(VP);\n"
52 "\n"
53 " // Normalize the vector from surface to light position\n"
54 " VP = normalize(VP);\n"
55 "\n"
56 " // Compute attenuation\n"
57 " attenuation = 1.0 / (gl_LightSource[i].constantAttenuation +\n"
58 " gl_LightSource[i].linearAttenuation * d +\n"
59 " gl_LightSource[i].quadraticAttenuation * d * d);\n"
60 " halfVector = normalize(VP + eye);\n"
61 " nDotVP = max(0.0, dot(normal, VP));\n"
62 " nDotHV = max(0.0, dot(normal, halfVector));\n"
63 "\n"
64 " if (nDotVP == 0.0)\n"
65 " pf = 0.0;\n"
66 " else\n"
67 " pf = pow(nDotHV, gl_FrontMaterial.shininess);\n"
68 "\n"
69 " Ambient += gl_LightSource[i].ambient * attenuation;\n"
70 " Diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation;\n"
71 " Specular += gl_LightSource[i].specular * pf * attenuation;\n"
72 " }\n"
73 "\n"
74 " vec3 fnormal(void)\n"
75 " {\n"
76 " //Compute the normal\n"
77 " vec3 normal = gl_NormalMatrix * gl_Normal;\n"
78 " normal = normalize(normal);\n"
79 " return normal;\n"
80 " }\n"
81 "\n"
82 " void flight(in vec3 normal, in vec4 ecPosition, float alphaFade)\n"
83 " {\n"
84 " vec4 color;\n"
85 " vec3 ecPosition3;\n"
86 " vec3 eye;\n"
87 "\n"
88 " ecPosition3 = (vec3 (ecPosition)) / ecPosition.w;\n"
89 " eye = vec3 (0.0, 0.0, 1.0);\n"
90 "\n"
91 " // Clear the light intensity accumulators\n"
92 " Ambient = vec4 (0.0);\n"
93 " Diffuse = vec4 (0.0);\n"
94 " Specular = vec4 (0.0);\n"
95 "\n"
96 " if(OSGLight0Active)\n"
97 " pointLight(0, normal, eye, ecPosition3);\n"
98 "\n"
99 " if(OSGLight1Active)\n"
100 " pointLight(1, normal, eye, ecPosition3);\n"
101 "\n"
102 " if(OSGLight2Active)\n"
103 " pointLight(2, normal, eye, ecPosition3);\n"
104 "\n"
105 " color = gl_FrontLightModelProduct.sceneColor +\n"
106 " Ambient * gl_FrontMaterial.ambient +\n"
107 " Diffuse * gl_FrontMaterial.diffuse;\n"
108 " color += Specular * gl_FrontMaterial.specular;\n"
109 " color = clamp( color, 0.0, 1.0 );\n"
110 " gl_FrontColor = color;\n"
111 " gl_FrontColor.a *= alphaFade;\n"
112 "\n"
113 " }\n"
114 "\n"
115 " void main(void)\n"
116 " {\n"
117 " vec3 transformedNormal;\n"
118 " float alphaFade = 1.0;\n"
119 "\n"
120 " // Eye-coordinate position of vertex, needed in various calculations\n"
121 " vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;\n"
122 "\n"
123 " // Do fixed functionality vertex transform\n"
124 " gl_Position = ftransform();\n"
125 " transformedNormal = fnormal();\n"
126 " flight(transformedNormal, ecPosition, alphaFade);\n"
127 " }\n";
129 // fragment shader program for bump mapping in surface local coordinates
130 static std::string _fp_program =
131 "void main (void)\n"
132 "{\n"
133 " vec4 color;\n"
134 " color = gl_Color;\n"
135 " gl_FragColor = color;\n"
136 "}\n";
139 // ------------------- global vars ----------------------
141 // The SimpleSceneManager to manage simple applications
142 static OSG::SimpleSceneManagerRefPtr _mgr;
143 // The scene
144 static OSG::NodeRecPtr _scene;
145 static OSG::PointLightRecPtr _point1_core;
146 static OSG::PointLightRecPtr _point2_core;
147 static OSG::PointLightRecPtr _point3_core;
149 OSG::NodeUnrecPtr point1_beacon;
150 OSG::NodeUnrecPtr point2_beacon;
151 OSG::NodeUnrecPtr point3_beacon;
153 // forward declaration so we can have the interesting stuff upfront
154 int setupGLUT( int *argc, char *argv[] );
156 // Shows how to add your own parameter callbacks.
158 typedef void (OSG_APIENTRY *OSGGLUNIFORMMATRIXFVARBPROC)(GLint location,
159 GLsizei count,
160 GLboolean transpose,
161 GLfloat *value);
163 #if 0
164 static
165 void updateSpecialParameter(
166 OSG::SimpleSHLChunk::GetUniformLocProc getUniformLocation,
167 OSG::DrawEnv *action,
168 GLuint program )
170 if(action->getCamera() == NULL || action->getViewport() == NULL)
172 FWARNING(("updateSpecialParameter : Can't update OSGSpecialParameter"
173 "parameter, camera or viewport is NULL!\n"));
174 return;
177 // uploads the camera orientation.
178 Matrix m;
179 action->getCamera()->getViewing(m,
180 action->getViewport()->getPixelWidth(),
181 action->getViewport()->getPixelHeight());
182 m.invert();
183 m[3].setValues(0, 0, 0, 1);
185 //std::cout << "uploading matrix " << m << std::endl;
187 // get "glUniformMatrix4fvARB" function pointer
188 OSGGLUNIFORMMATRIXFVARBPROC uniformMatrix4fv =
189 reinterpret_cast<OSGGLUNIFORMMATRIXFVARBPROC>(
190 action->getWindow()->getFunction(
191 SimpleSHLChunk::getFuncUniformMatrix4fv()));
193 GLint location = getUniformLocation(program, "OSGSpecialParameter");
195 if(location != -1)
196 uniformMatrix4fv(location, 1, GL_FALSE, m.getValues());
198 #endif
200 // Initialize GLUT & OpenSG and set up the scene
201 int doMain(int argc, char **argv)
203 printf("Press key '1', '2', or '3' to toggle the light sources.\n");
204 // OSG init
205 OSG::osgInit(argc,argv);
207 // GLUT init
208 int winid = setupGLUT(&argc, argv);
210 // the connection between GLUT and OpenSG
211 OSG::GLUTWindowUnrecPtr gwin= OSG::GLUTWindow::create();
213 gwin->setGlutId(winid);
214 gwin->setSize( 800, 800 );
215 gwin->init();
217 // Create the shader material
219 OSG::ChunkMaterialUnrecPtr cmat = OSG::ChunkMaterial::create();
221 OSG::MaterialChunkUnrecPtr matc = OSG::MaterialChunk::create();
223 matc->setAmbient(OSG::Color4f(0.1f, 0.1f, 0.1f, 1.0f));
224 matc->setDiffuse(OSG::Color4f(0.3f, 0.3f, 0.3f, 1.0f));
225 matc->setSpecular(OSG::Color4f(0.8f, 0.8f, 0.8f, 1.0f));
226 matc->setShininess(100);
227 matc->setLit(true);
229 OSG::SimpleSHLChunkUnrecPtr shl = OSG::SimpleSHLChunk::create();
231 shl->setVertexProgram(_vp_program);
232 shl->setFragmentProgram(_fp_program);
233 shl->addOSGVariable("OSGLight0Active");
234 shl->addOSGVariable("OSGLight1Active");
235 shl->addOSGVariable("OSGLight2Active");
236 // shl->setUniformVariable("OSGViewMatrix", 0);
237 // The OSGSpecialParameter is not used in the shader just shows
238 // how to add your own parameter callbacks!
239 // shl->addParameterCallback("OSGSpecialParameter", updateSpecialParameter);
241 cmat->addChunk(matc);
242 cmat->addChunk(shl);
244 // create root node
245 _scene = OSG::Node::create();
247 // create two light sources.
249 OSG::TransformUnrecPtr point1_trans;
251 OSG::NodeUnrecPtr point1 =
252 OSG::makeCoredNode<OSG::PointLight>(&_point1_core);
253 point1_beacon = OSG::makeCoredNode<OSG::Transform >(&point1_trans);
255 point1_trans->editMatrix().setTranslate(-10.0, 5.0, 5.0);
257 _point1_core->setAmbient(0.0f, 0.0f, 0.0f , 1.0f);
258 _point1_core->setDiffuse(1.0f, 0.0f, 0.0f, 1.0f);
259 _point1_core->setSpecular(1.0f, 1.0f, 1.0f, 1.0f);
260 _point1_core->setBeacon(point1_beacon);
261 _point1_core->setOn(true);
264 OSG::TransformUnrecPtr point2_trans;
266 OSG::NodeUnrecPtr point2 =
267 OSG::makeCoredNode<OSG::PointLight>(&_point2_core);
268 point2_beacon = OSG::makeCoredNode<OSG::Transform >(&point2_trans);
270 point2_trans->editMatrix().setTranslate(10.0, 5.0, 5.0);
272 _point2_core->setAmbient(0.0f, 0.0f, 0.0f, 1.0f);
273 _point2_core->setDiffuse(0.0f, 1.0f, 0.0f, 1.0f);
274 _point2_core->setSpecular(1.0f, 1.0f, 1.0f, 1.0f);
275 _point2_core->setBeacon(point2_beacon);
276 _point2_core->setOn(true);
278 point1->addChild(point2);
280 OSG::TransformUnrecPtr point3_trans;
282 OSG::NodeUnrecPtr point3 =
283 OSG::makeCoredNode<OSG::PointLight>(&_point3_core);
285 point3_beacon = OSG::makeCoredNode<OSG::Transform >(&point3_trans);
287 point3_trans->editMatrix().setTranslate(0.0, -12.0, 5.0);
289 _point3_core->setAmbient(0.0f, 0.0f, 0.0f, 1.0f);
290 _point3_core->setDiffuse(0.5f, 0.0f, 1.0f, 1.0f);
291 _point3_core->setSpecular(1.0f, 1.0f, 1.0f, 1.0f);
292 _point3_core->setBeacon(point3_beacon);
293 _point3_core->setOn(true);
295 point2->addChild(point3);
298 // create a sphere.
299 OSG::GeometryUnrecPtr geo = OSG::makeLatLongSphereGeo (100, 100, 1.0);
301 geo->setMaterial(cmat);
304 OSG::NodeUnrecPtr sphere = OSG::makeNodeFor(geo);
306 point3->addChild(sphere);
309 _scene->setCore(OSG::Group::create());
310 _scene->addChild(point1);
312 // create the SimpleSceneManager helper
313 _mgr = OSG::SimpleSceneManager::create();
315 // tell the manager what to manage
316 _mgr->setWindow(gwin );
317 _mgr->setRoot(_scene);
319 _mgr->turnHeadlightOff();
321 // show the whole scene
322 _mgr->showAll();
324 // enable local lights.
325 // OSG::RenderAction *ract =
326 // dynamic_cast<OSG::RenderAction *>(_mgr->getRenderAction());
328 // ract->setLocalLights(true);
330 return 0;
333 // Initialize GLUT & OpenSG and set up the scene
334 int main(int argc, char **argv)
336 if(doMain(argc, argv) != 0)
337 return 1;
339 // GLUT main loop
340 glutMainLoop();
342 return 0;
346 // GLUT callback functions
349 // redraw the window
350 void display(void)
352 // render scene
353 _mgr->redraw();
356 // react to size changes
357 void reshape(int w, int h)
359 _mgr->resize(w, h);
360 glutPostRedisplay();
363 // react to mouse button presses
364 void mouse(int button, int state, int x, int y)
366 if (state)
367 _mgr->mouseButtonRelease(button, x, y);
368 else
369 _mgr->mouseButtonPress(button, x, y);
371 glutPostRedisplay();
374 // react to mouse motions with pressed buttons
375 void motion(int x, int y)
377 _mgr->mouseMove(x, y);
378 glutPostRedisplay();
381 // react to keys
382 void keyboard(unsigned char k, int x, int y)
384 switch(k)
386 case 27:
387 case 'q':
388 _scene = NULL;
389 _point1_core = NULL;
390 _point2_core = NULL;
391 _point3_core = NULL;
393 point1_beacon = NULL;
394 point2_beacon = NULL;
395 point3_beacon = NULL;
397 _mgr = NULL;
399 OSG::osgExit();
401 exit(1);
402 break;
403 case 'w':
404 OSG::SceneFileHandler::the()->write(_scene, "scene.osb.gz", true);
405 printf("wrote scene.osb.gz\n");
406 break;
407 case '1':
409 if(_point1_core->getOn() == false)
410 _point1_core->setOn(true);
411 else
412 _point1_core->setOn(false);
413 break;
416 case '2':
418 if(_point2_core->getOn() == false)
419 _point2_core->setOn(true);
420 else
421 _point2_core->setOn(false);
422 break;
425 case '3':
427 if(_point3_core->getOn() == false)
428 _point3_core->setOn(true);
429 else
430 _point3_core->setOn(false);
431 break;
435 glutPostRedisplay();
438 // setup the GLUT library which handles the windows for us
439 int setupGLUT(int *argc, char *argv[])
441 glutInit(argc, argv);
442 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
444 int winid = glutCreateWindow("OpenSG CG Shader");
446 glutReshapeFunc(reshape);
447 glutDisplayFunc(display);
448 glutMouseFunc(mouse);
449 glutMotionFunc(motion);
450 glutKeyboardFunc(keyboard);
452 return winid;