1 // OpenSG example: testSHL
3 // Demonstrates the use of the SHLChunk
4 // Implements a simple bumpmapping via vertex and fragment shader.
13 #include "OSGSimpleGeometry.h"
15 #include "OSGGLUTWindow.h"
16 #include "OSGSimpleSceneManager.h"
17 #include "OSGAction.h"
18 #include "OSGSceneFileHandler.h"
19 #include "OSGBaseFunctions.h"
23 #include "OSGTransform.h"
24 #include "OSGPointLight.h"
27 #include "OSGChunkMaterial.h"
28 #include "OSGMaterialChunk.h"
29 #include "OSGSHLChunk.h"
30 #include "OSGGLFuncProtos.h"
33 // vertex shader program for bump mapping in surface local coordinates
34 static std::string _vp_program
=
35 "uniform bool Light0Active;\n"
36 "uniform bool Light1Active;\n"
37 "uniform bool Light2Active;\n"
43 " void pointLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3)\n"
45 " float nDotVP; // normal . light direction\n"
46 " float nDotHV; // normal . light half vector\n"
47 " float pf; // power factor\n"
48 " float attenuation; // computed attenuation factor\n"
49 " float d; // distance from surface to light source\n"
50 " vec3 VP; // direction from surface to light position\n"
51 " vec3 halfVector; // direction of maximum highlights\n"
53 " // Compute vector from surface to light position\n"
54 " VP = vec3 (gl_LightSource[i].position) - ecPosition3;\n"
56 " // Compute distance between surface and light position\n"
59 " // Normalize the vector from surface to light position\n"
60 " VP = normalize(VP);\n"
62 " // Compute attenuation\n"
63 " attenuation = 1.0 / (gl_LightSource[i].constantAttenuation +\n"
64 " gl_LightSource[i].linearAttenuation * d +\n"
65 " gl_LightSource[i].quadraticAttenuation * d * d);\n"
66 " halfVector = normalize(VP + eye);\n"
67 " nDotVP = max(0.0, dot(normal, VP));\n"
68 " nDotHV = max(0.0, dot(normal, halfVector));\n"
70 " if (nDotVP == 0.0)\n"
73 " pf = pow(nDotHV, gl_FrontMaterial.shininess);\n"
75 " Ambient += gl_LightSource[i].ambient * attenuation;\n"
76 " Diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation;\n"
77 " Specular += gl_LightSource[i].specular * pf * attenuation;\n"
80 " vec3 fnormal(void)\n"
82 " //Compute the normal\n"
83 " vec3 normal = gl_NormalMatrix * gl_Normal;\n"
84 " normal = normalize(normal);\n"
88 " void flight(in vec3 normal, in vec4 ecPosition, float alphaFade)\n"
91 " vec3 ecPosition3;\n"
94 " ecPosition3 = (vec3 (ecPosition)) / ecPosition.w;\n"
95 " eye = vec3 (0.0, 0.0, 1.0);\n"
97 " // Clear the light intensity accumulators\n"
98 " Ambient = vec4 (0.0);\n"
99 " Diffuse = vec4 (0.0);\n"
100 " Specular = vec4 (0.0);\n"
102 " if(Light0Active)\n"
103 " pointLight(0, normal, eye, ecPosition3);\n"
105 " if(Light1Active)\n"
106 " pointLight(1, normal, eye, ecPosition3);\n"
108 " if(Light2Active)\n"
109 " pointLight(2, normal, eye, ecPosition3);\n"
111 " color = gl_FrontLightModelProduct.sceneColor +\n"
112 " Ambient * gl_FrontMaterial.ambient +\n"
113 " Diffuse * gl_FrontMaterial.diffuse;\n"
114 " color += Specular * gl_FrontMaterial.specular;\n"
115 " color = clamp( color, 0.0, 1.0 );\n"
116 " gl_FrontColor = color;\n"
117 " gl_FrontColor.a *= alphaFade;\n"
123 " vec3 transformedNormal;\n"
124 " float alphaFade = 1.0;\n"
126 " // Eye-coordinate position of vertex, needed in various calculations\n"
127 " vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;\n"
129 " // Do fixed functionality vertex transform\n"
130 " gl_Position = ftransform();\n"
131 " transformedNormal = fnormal();\n"
132 " flight(transformedNormal, ecPosition, alphaFade);\n"
135 // fragment shader program for bump mapping in surface local coordinates
136 static std::string _fp_program
=
140 " color = gl_Color;\n"
141 " gl_FragColor = color;\n"
145 // ------------------- global vars ----------------------
147 // The SimpleSceneManager to manage simple applications
148 static OSG::SimpleSceneManagerRefPtr _mgr
;
150 static OSG::NodeRecPtr _scene
;
151 static OSG::PointLightRecPtr _point1_core
;
152 static OSG::PointLightRecPtr _point2_core
;
153 static OSG::PointLightRecPtr _point3_core
;
155 OSG::NodeUnrecPtr point1_beacon
;
156 OSG::NodeUnrecPtr point2_beacon
;
157 OSG::NodeUnrecPtr point3_beacon
;
159 // forward declaration so we can have the interesting stuff upfront
160 int setupGLUT( int *argc
, char *argv
[] );
162 // Shows how to add your own parameter callbacks.
164 static void light0Active(OSG::SHLChunk::GetUniformLocProc fULoc
,
168 GLint iLoc
= fULoc(uiProg
, "Light0Active");
172 OSGGETGLFUNC_EXT(glUniform1i
,
174 OSG::ShaderProgram::getFuncIdUniform1i());
177 GLint(pEnv
->getLightState() & 0x0001));
181 static void light1Active(OSG::SHLChunk::GetUniformLocProc fULoc
,
185 GLint iLoc
= fULoc(uiProg
, "Light1Active");
189 OSGGETGLFUNC_EXT(glUniform1i
,
191 OSG::ShaderProgram::getFuncIdUniform1i());
194 GLint(pEnv
->getLightState() & 0x0002));
198 static void light2Active(OSG::SHLChunk::GetUniformLocProc fULoc
,
202 GLint iLoc
= fULoc(uiProg
, "Light2Active");
206 OSGGETGLFUNC_EXT(glUniform1i
,
208 OSG::ShaderProgram::getFuncIdUniform1i());
211 GLint(pEnv
->getLightState() & 0x0004));
215 // Initialize GLUT & OpenSG and set up the scene
216 int doMain(int argc
, char **argv
)
218 printf("Press key '1', '2', or '3' to toggle the light sources.\n");
220 OSG::osgInit(argc
,argv
);
223 int winid
= setupGLUT(&argc
, argv
);
225 // the connection between GLUT and OpenSG
226 OSG::GLUTWindowUnrecPtr gwin
= OSG::GLUTWindow::create();
228 gwin
->setGlutId(winid
);
229 gwin
->setSize( 800, 800 );
232 // Create the shader material
234 OSG::ChunkMaterialUnrecPtr cmat
= OSG::ChunkMaterial::create();
236 OSG::MaterialChunkUnrecPtr matc
= OSG::MaterialChunk::create();
238 matc
->setAmbient(OSG::Color4f(0.1, 0.1, 0.1, 1.0));
239 matc
->setDiffuse(OSG::Color4f(0.3, 0.3, 0.3, 1.0));
240 matc
->setSpecular(OSG::Color4f(0.8, 0.8, 0.8, 1.0));
241 matc
->setShininess(100);
244 OSG::SHLChunkUnrecPtr shl
= OSG::SHLChunk::create();
246 shl
->setVertexProgram(_vp_program
);
247 shl
->setFragmentProgram(_fp_program
);
248 shl
->addParameterCallback("Light0Active",
249 OSG::SHLChunk::ParamFunctor(&light0Active
));
250 shl
->addParameterCallback("Light1Active",
251 OSG::SHLChunk::ParamFunctor(&light1Active
));
252 shl
->addParameterCallback("Light2Active",
253 OSG::SHLChunk::ParamFunctor(&light2Active
));
255 cmat
->addChunk(matc
);
259 _scene
= OSG::Node::create();
261 // create two light sources.
263 OSG::TransformUnrecPtr point1_trans
;
265 OSG::NodeUnrecPtr point1
=
266 OSG::makeCoredNode
<OSG::PointLight
>(&_point1_core
);
267 point1_beacon
= OSG::makeCoredNode
<OSG::Transform
>(&point1_trans
);
269 point1_trans
->editMatrix().setTranslate(-10.0, 5.0, 5.0);
271 _point1_core
->setAmbient(0.0f
, 0.0f
, 0.0f
, 1.0f
);
272 _point1_core
->setDiffuse(1.0f
, 0.0f
, 0.0f
, 1.0f
);
273 _point1_core
->setSpecular(1.0f
, 1.0f
, 1.0f
, 1.0f
);
274 _point1_core
->setBeacon(point1_beacon
);
275 _point1_core
->setOn(true);
278 OSG::TransformUnrecPtr point2_trans
;
280 OSG::NodeUnrecPtr point2
=
281 OSG::makeCoredNode
<OSG::PointLight
>(&_point2_core
);
282 point2_beacon
= OSG::makeCoredNode
<OSG::Transform
>(&point2_trans
);
284 point2_trans
->editMatrix().setTranslate(10.0, 5.0, 5.0);
286 _point2_core
->setAmbient(0.0f
, 0.0f
, 0.0f
, 1.0f
);
287 _point2_core
->setDiffuse(0.0f
, 1.0f
, 0.0f
, 1.0f
);
288 _point2_core
->setSpecular(1.0f
, 1.0f
, 1.0f
, 1.0f
);
289 _point2_core
->setBeacon(point2_beacon
);
290 _point2_core
->setOn(true);
292 point1
->addChild(point2
);
294 OSG::TransformUnrecPtr point3_trans
;
296 OSG::NodeUnrecPtr point3
=
297 OSG::makeCoredNode
<OSG::PointLight
>(&_point3_core
);
299 point3_beacon
= OSG::makeCoredNode
<OSG::Transform
>(&point3_trans
);
301 point3_trans
->editMatrix().setTranslate(0.0, -12.0, 5.0);
303 _point3_core
->setAmbient(0.0f
, 0.0f
, 0.0f
, 1.0f
);
304 _point3_core
->setDiffuse(0.5f
, 0.0f
, 1.0f
, 1.0f
);
305 _point3_core
->setSpecular(1.0f
, 1.0f
, 1.0f
, 1.0f
);
306 _point3_core
->setBeacon(point3_beacon
);
307 _point3_core
->setOn(true);
309 point2
->addChild(point3
);
313 OSG::GeometryUnrecPtr geo
= OSG::makeLatLongSphereGeo (100, 100, 1.0);
315 geo
->setMaterial(cmat
);
318 OSG::NodeUnrecPtr sphere
= OSG::makeNodeFor(geo
);
320 point3
->addChild(sphere
);
323 _scene
->setCore(OSG::Group::create());
324 _scene
->addChild(point1
);
326 // create the SimpleSceneManager helper
327 _mgr
= OSG::SimpleSceneManager::create();
329 // tell the manager what to manage
330 _mgr
->setWindow(gwin
);
331 _mgr
->setRoot(_scene
);
333 _mgr
->turnHeadlightOff();
335 // show the whole scene
338 // enable local lights.
339 // OSG::RenderAction *ract =
340 // dynamic_cast<OSG::RenderAction *>(_mgr->getRenderAction());
342 // ract->setLocalLights(true);
347 // Initialize GLUT & OpenSG and set up the scene
348 int main(int argc
, char **argv
)
350 if(doMain(argc
, argv
) != 0)
360 // GLUT callback functions
370 // react to size changes
371 void reshape(int w
, int h
)
377 // react to mouse button presses
378 void mouse(int button
, int state
, int x
, int y
)
381 _mgr
->mouseButtonRelease(button
, x
, y
);
383 _mgr
->mouseButtonPress(button
, x
, y
);
388 // react to mouse motions with pressed buttons
389 void motion(int x
, int y
)
391 _mgr
->mouseMove(x
, y
);
396 void keyboard(unsigned char k
, int x
, int y
)
407 point1_beacon
= NULL
;
408 point2_beacon
= NULL
;
409 point3_beacon
= NULL
;
416 OSG::SceneFileHandler::the()->write(_scene
, "scene.osb.gz", true);
417 printf("wrote scene.osb.gz\n");
421 if(_point1_core
->getOn() == false)
422 _point1_core
->setOn(true);
424 _point1_core
->setOn(false);
430 if(_point2_core
->getOn() == false)
431 _point2_core
->setOn(true);
433 _point2_core
->setOn(false);
439 if(_point3_core
->getOn() == false)
440 _point3_core
->setOn(true);
442 _point3_core
->setOn(false);
450 // setup the GLUT library which handles the windows for us
451 int setupGLUT(int *argc
, char *argv
[])
453 glutInit(argc
, argv
);
454 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
456 int winid
= glutCreateWindow("OpenSG CG Shader");
458 glutReshapeFunc(reshape
);
459 glutDisplayFunc(display
);
460 glutMouseFunc(mouse
);
461 glutMotionFunc(motion
);
462 glutKeyboardFunc(keyboard
);
470 int main(int argc
, char **argv
)