fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / State / Shader / Chunks / testSHLProcLights_shaderprog.cpp
blobbcc344b0dc278e7b696036748f22ebc51fccb864
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 "OSGShaderProgramChunk.h"
26 #include "OSGGLFuncProtos.h"
27 #include "OSGShaderProgram.h"
29 // vertex shader program for bump mapping in surface local coordinates
30 static std::string _vp_program =
31 "uniform bool Light0Active;\n"
32 "uniform bool Light1Active;\n"
33 "uniform bool Light2Active;\n"
34 "vec4 Ambient;\n"
35 "vec4 Diffuse;\n"
36 "vec4 Specular;\n"
37 "\n"
38 "\n"
39 " void pointLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3)\n"
40 " {\n"
41 " float nDotVP; // normal . light direction\n"
42 " float nDotHV; // normal . light half vector\n"
43 " float pf; // power factor\n"
44 " float attenuation; // computed attenuation factor\n"
45 " float d; // distance from surface to light source\n"
46 " vec3 VP; // direction from surface to light position\n"
47 " vec3 halfVector; // direction of maximum highlights\n"
48 "\n"
49 " // Compute vector from surface to light position\n"
50 " VP = vec3 (gl_LightSource[i].position) - ecPosition3;\n"
51 "\n"
52 " // Compute distance between surface and light position\n"
53 " d = length(VP);\n"
54 "\n"
55 " // Normalize the vector from surface to light position\n"
56 " VP = normalize(VP);\n"
57 "\n"
58 " // Compute attenuation\n"
59 " attenuation = 1.0 / (gl_LightSource[i].constantAttenuation +\n"
60 " gl_LightSource[i].linearAttenuation * d +\n"
61 " gl_LightSource[i].quadraticAttenuation * d * d);\n"
62 " halfVector = normalize(VP + eye);\n"
63 " nDotVP = max(0.0, dot(normal, VP));\n"
64 " nDotHV = max(0.0, dot(normal, halfVector));\n"
65 "\n"
66 " if (nDotVP == 0.0)\n"
67 " pf = 0.0;\n"
68 " else\n"
69 " pf = pow(nDotHV, gl_FrontMaterial.shininess);\n"
70 "\n"
71 " Ambient += gl_LightSource[i].ambient * attenuation;\n"
72 " Diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation;\n"
73 " Specular += gl_LightSource[i].specular * pf * attenuation;\n"
74 " }\n"
75 "\n"
76 " vec3 fnormal(void)\n"
77 " {\n"
78 " //Compute the normal\n"
79 " vec3 normal = gl_NormalMatrix * gl_Normal;\n"
80 " normal = normalize(normal);\n"
81 " return normal;\n"
82 " }\n"
83 "\n"
84 " void flight(in vec3 normal, in vec4 ecPosition, float alphaFade)\n"
85 " {\n"
86 " vec4 color;\n"
87 " vec3 ecPosition3;\n"
88 " vec3 eye;\n"
89 "\n"
90 " ecPosition3 = (vec3 (ecPosition)) / ecPosition.w;\n"
91 " eye = vec3 (0.0, 0.0, 1.0);\n"
92 "\n"
93 " // Clear the light intensity accumulators\n"
94 " Ambient = vec4 (0.0);\n"
95 " Diffuse = vec4 (0.0);\n"
96 " Specular = vec4 (0.0);\n"
97 "\n"
98 " if(Light0Active)\n"
99 " pointLight(0, normal, eye, ecPosition3);\n"
100 "\n"
101 " if(Light1Active)\n"
102 " pointLight(1, normal, eye, ecPosition3);\n"
103 "\n"
104 " if(Light2Active)\n"
105 " pointLight(2, normal, eye, ecPosition3);\n"
106 "\n"
107 " color = gl_FrontLightModelProduct.sceneColor +\n"
108 " Ambient * gl_FrontMaterial.ambient +\n"
109 " Diffuse * gl_FrontMaterial.diffuse;\n"
110 " color += Specular * gl_FrontMaterial.specular;\n"
111 " color = clamp( color, 0.0, 1.0 );\n"
112 " gl_FrontColor = color;\n"
113 " gl_FrontColor.a *= alphaFade;\n"
114 "\n"
115 " }\n"
116 "\n"
117 " void main(void)\n"
118 " {\n"
119 " vec3 transformedNormal;\n"
120 " float alphaFade = 1.0;\n"
121 "\n"
122 " // Eye-coordinate position of vertex, needed in various calculations\n"
123 " vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;\n"
124 "\n"
125 " // Do fixed functionality vertex transform\n"
126 " gl_Position = ftransform();\n"
127 " transformedNormal = fnormal();\n"
128 " flight(transformedNormal, ecPosition, alphaFade);\n"
129 " }\n";
131 // fragment shader program for bump mapping in surface local coordinates
132 static std::string _fp_program =
133 "void main (void)\n"
134 "{\n"
135 " vec4 color;\n"
136 " color = gl_Color;\n"
137 " gl_FragColor = color;\n"
138 "}\n";
141 // ------------------- global vars ----------------------
143 // The SimpleSceneManager to manage simple applications
144 static OSG::SimpleSceneManagerRefPtr _mgr;
145 // The scene
146 static OSG::NodeRecPtr _scene;
147 static OSG::PointLightRecPtr _point1_core;
148 static OSG::PointLightRecPtr _point2_core;
149 static OSG::PointLightRecPtr _point3_core;
151 OSG::NodeUnrecPtr point1_beacon;
152 OSG::NodeUnrecPtr point2_beacon;
153 OSG::NodeUnrecPtr point3_beacon;
155 // forward declaration so we can have the interesting stuff upfront
156 int setupGLUT( int *argc, char *argv[] );
158 // Shows how to add your own parameter callbacks.
160 static void light0Active(OSG::DrawEnv *pEnv, OSG::Int32 iLoc)
162 if(iLoc != -1)
164 OSGGETGLFUNC_EXT(glUniform1i,
165 osgGlUniform1i,
166 OSG::ShaderProgram::getFuncIdUniform1i());
168 osgGlUniform1i(iLoc,
169 GLint(pEnv->getLightState() & 0x0001));
173 static void light1Active(OSG::DrawEnv *pEnv, OSG::Int32 iLoc)
175 if(iLoc != -1)
177 OSGGETGLFUNC_EXT(glUniform1i,
178 osgGlUniform1i,
179 OSG::ShaderProgram::getFuncIdUniform1i());
181 osgGlUniform1i(iLoc,
182 GLint(pEnv->getLightState() & 0x0002));
186 static void light2Active(OSG::DrawEnv *pEnv, OSG::Int32 iLoc, OSG::Node *pNode)
188 if(iLoc != -1)
190 OSGGETGLFUNC_EXT(glUniform1i,
191 osgGlUniform1i,
192 OSG::ShaderProgram::getFuncIdUniform1i());
194 osgGlUniform1i(iLoc,
195 GLint(pEnv->getLightState() & 0x0004));
199 // Initialize GLUT & OpenSG and set up the scene
200 int doMain(int argc, char **argv)
202 printf("Press key '1', '2', or '3' to toggle the light sources.\n");
203 // OSG init
204 OSG::osgInit(argc,argv);
206 // GLUT init
207 int winid = setupGLUT(&argc, argv);
209 // the connection between GLUT and OpenSG
210 OSG::GLUTWindowUnrecPtr gwin= OSG::GLUTWindow::create();
212 gwin->setGlutId(winid);
213 gwin->setSize( 800, 800 );
214 gwin->init();
216 // Create the shader material
218 OSG::ChunkMaterialUnrecPtr cmat = OSG::ChunkMaterial::create();
220 OSG::MaterialChunkUnrecPtr matc = OSG::MaterialChunk::create();
222 matc->setAmbient(OSG::Color4f(0.1f, 0.1f, 0.1f, 1.0f));
223 matc->setDiffuse(OSG::Color4f(0.3f, 0.3f, 0.3f, 1.0f));
224 matc->setSpecular(OSG::Color4f(0.8f, 0.8f, 0.8f, 1.0f));
225 matc->setShininess(100);
226 matc->setLit(true);
228 OSG::ShaderProgramChunkUnrecPtr shl = OSG::ShaderProgramChunk::create();
230 OSG::ShaderProgramUnrecPtr shl_vp =
231 OSG::ShaderProgram::createVertexShader();
233 shl_vp->setProgram(_vp_program);
235 shl->addShader(shl_vp);
237 OSG::ShaderProgramUnrecPtr shl_fp =
238 OSG::ShaderProgram::createFragmentShader();
240 shl_fp->setProgram(_fp_program);
242 shl->addShader(shl_fp);
244 shl_vp->addProceduralVariable ("Light0Active", &light0Active);
245 shl_vp->addProceduralVariable ("Light1Active", &light1Active);
246 shl_vp->addNodeProceduralVariable("Light2Active", &light2Active);
248 cmat->addChunk(matc);
249 cmat->addChunk(shl);
251 // create root node
252 _scene = OSG::Node::create();
254 // create two light sources.
256 OSG::TransformUnrecPtr point1_trans;
258 OSG::NodeUnrecPtr point1 =
259 OSG::makeCoredNode<OSG::PointLight>(&_point1_core);
260 point1_beacon = OSG::makeCoredNode<OSG::Transform >(&point1_trans);
262 point1_trans->editMatrix().setTranslate(-10.0, 5.0, 5.0);
264 _point1_core->setAmbient(0.0f, 0.0f, 0.0f , 1.0f);
265 _point1_core->setDiffuse(1.0f, 0.0f, 0.0f, 1.0f);
266 _point1_core->setSpecular(1.0f, 1.0f, 1.0f, 1.0f);
267 _point1_core->setBeacon(point1_beacon);
268 _point1_core->setOn(true);
271 OSG::TransformUnrecPtr point2_trans;
273 OSG::NodeUnrecPtr point2 =
274 OSG::makeCoredNode<OSG::PointLight>(&_point2_core);
275 point2_beacon = OSG::makeCoredNode<OSG::Transform >(&point2_trans);
277 point2_trans->editMatrix().setTranslate(10.0, 5.0, 5.0);
279 _point2_core->setAmbient(0.0f, 0.0f, 0.0f, 1.0f);
280 _point2_core->setDiffuse(0.0f, 1.0f, 0.0f, 1.0f);
281 _point2_core->setSpecular(1.0f, 1.0f, 1.0f, 1.0f);
282 _point2_core->setBeacon(point2_beacon);
283 _point2_core->setOn(true);
285 point1->addChild(point2);
287 OSG::TransformUnrecPtr point3_trans;
289 OSG::NodeUnrecPtr point3 =
290 OSG::makeCoredNode<OSG::PointLight>(&_point3_core);
292 point3_beacon = OSG::makeCoredNode<OSG::Transform >(&point3_trans);
294 point3_trans->editMatrix().setTranslate(0.0, -12.0, 5.0);
296 _point3_core->setAmbient(0.0f, 0.0f, 0.0f, 1.0f);
297 _point3_core->setDiffuse(0.5f, 0.0f, 1.0f, 1.0f);
298 _point3_core->setSpecular(1.0f, 1.0f, 1.0f, 1.0f);
299 _point3_core->setBeacon(point3_beacon);
300 _point3_core->setOn(true);
302 point2->addChild(point3);
305 // create a sphere.
306 OSG::GeometryUnrecPtr geo = OSG::makeLatLongSphereGeo (100, 100, 1.0);
308 geo->setMaterial(cmat);
311 OSG::NodeUnrecPtr sphere = OSG::makeNodeFor(geo);
313 point3->addChild(sphere);
316 _scene->setCore(OSG::Group::create());
317 _scene->addChild(point1);
319 // create the SimpleSceneManager helper
320 _mgr = OSG::SimpleSceneManager::create();
322 // tell the manager what to manage
323 _mgr->setWindow(gwin );
324 _mgr->setRoot(_scene);
326 _mgr->turnHeadlightOff();
328 // show the whole scene
329 _mgr->showAll();
331 // enable local lights.
332 // OSG::RenderAction *ract =
333 // dynamic_cast<OSG::RenderAction *>(_mgr->getRenderAction());
335 // ract->setLocalLights(true);
337 return 0;
340 // Initialize GLUT & OpenSG and set up the scene
341 int main(int argc, char **argv)
343 if(doMain(argc, argv) != 0)
344 return 1;
346 // GLUT main loop
347 glutMainLoop();
349 return 0;
353 // GLUT callback functions
356 // redraw the window
357 void display(void)
359 // render scene
360 _mgr->redraw();
363 // react to size changes
364 void reshape(int w, int h)
366 _mgr->resize(w, h);
367 glutPostRedisplay();
370 // react to mouse button presses
371 void mouse(int button, int state, int x, int y)
373 if (state)
374 _mgr->mouseButtonRelease(button, x, y);
375 else
376 _mgr->mouseButtonPress(button, x, y);
378 glutPostRedisplay();
381 // react to mouse motions with pressed buttons
382 void motion(int x, int y)
384 _mgr->mouseMove(x, y);
385 glutPostRedisplay();
388 // react to keys
389 void keyboard(unsigned char k, int x, int y)
391 switch(k)
393 case 27:
394 case 'q':
395 _scene = NULL;
396 _point1_core = NULL;
397 _point2_core = NULL;
398 _point3_core = NULL;
400 point1_beacon = NULL;
401 point2_beacon = NULL;
402 point3_beacon = NULL;
404 _mgr = NULL;
406 OSG::osgExit();
408 exit(1);
409 break;
410 case 'w':
411 OSG::SceneFileHandler::the()->write(_scene, "scene.osb.gz", true);
412 printf("wrote scene.osb.gz\n");
413 break;
414 case '1':
416 if(_point1_core->getOn() == false)
417 _point1_core->setOn(true);
418 else
419 _point1_core->setOn(false);
420 break;
423 case '2':
425 if(_point2_core->getOn() == false)
426 _point2_core->setOn(true);
427 else
428 _point2_core->setOn(false);
429 break;
432 case '3':
434 if(_point3_core->getOn() == false)
435 _point3_core->setOn(true);
436 else
437 _point3_core->setOn(false);
438 break;
442 glutPostRedisplay();
445 // setup the GLUT library which handles the windows for us
446 int setupGLUT(int *argc, char *argv[])
448 glutInit(argc, argv);
449 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
451 int winid = glutCreateWindow("OpenSG CG Shader");
453 glutReshapeFunc(reshape);
454 glutDisplayFunc(display);
455 glutMouseFunc(mouse);
456 glutMotionFunc(motion);
457 glutKeyboardFunc(keyboard);
459 return winid;