1 // OpenSG example: testSHL
3 // Demonstrates the use of the SHLChunk
4 // Implements a simple bumpmapping via vertex and fragment shader.
9 #include "OSGSimpleGeometry.h"
11 #include "OSGGLUTWindow.h"
12 #include "OSGSimpleSceneManager.h"
13 #include "OSGAction.h"
14 #include "OSGSceneFileHandler.h"
15 #include "OSGBaseFunctions.h"
19 #include "OSGTransform.h"
20 #include "OSGPointLight.h"
23 #include "OSGChunkMaterial.h"
24 #include "OSGMaterialChunk.h"
25 #include "OSGShaderProgramChunk.h"
26 #include "OSGShaderProgram.h"
28 // vertex shader program for bump mapping in surface local coordinates
29 static std::string _vp_program
=
30 "uniform bool OSGLight0Active;\n"
31 "uniform bool OSGLight1Active;\n"
32 "uniform bool OSGLight2Active;\n"
38 " void pointLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3)\n"
40 " float nDotVP; // normal . light direction\n"
41 " float nDotHV; // normal . light half vector\n"
42 " float pf; // power factor\n"
43 " float attenuation; // computed attenuation factor\n"
44 " float d; // distance from surface to light source\n"
45 " vec3 VP; // direction from surface to light position\n"
46 " vec3 halfVector; // direction of maximum highlights\n"
48 " // Compute vector from surface to light position\n"
49 " VP = vec3 (gl_LightSource[i].position) - ecPosition3;\n"
51 " // Compute distance between surface and light position\n"
54 " // Normalize the vector from surface to light position\n"
55 " VP = normalize(VP);\n"
57 " // Compute attenuation\n"
58 " attenuation = 1.0 / (gl_LightSource[i].constantAttenuation +\n"
59 " gl_LightSource[i].linearAttenuation * d +\n"
60 " gl_LightSource[i].quadraticAttenuation * d * d);\n"
61 " halfVector = normalize(VP + eye);\n"
62 " nDotVP = max(0.0, dot(normal, VP));\n"
63 " nDotHV = max(0.0, dot(normal, halfVector));\n"
65 " if (nDotVP == 0.0)\n"
68 " pf = pow(nDotHV, gl_FrontMaterial.shininess);\n"
70 " Ambient += gl_LightSource[i].ambient * attenuation;\n"
71 " Diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation;\n"
72 " Specular += gl_LightSource[i].specular * pf * attenuation;\n"
75 " vec3 fnormal(void)\n"
77 " //Compute the normal\n"
78 " vec3 normal = gl_NormalMatrix * gl_Normal;\n"
79 " normal = normalize(normal);\n"
83 " void flight(in vec3 normal, in vec4 ecPosition, float alphaFade)\n"
86 " vec3 ecPosition3;\n"
89 " ecPosition3 = (vec3 (ecPosition)) / ecPosition.w;\n"
90 " eye = vec3 (0.0, 0.0, 1.0);\n"
92 " // Clear the light intensity accumulators\n"
93 " Ambient = vec4 (0.0);\n"
94 " Diffuse = vec4 (0.0);\n"
95 " Specular = vec4 (0.0);\n"
97 " if(OSGLight0Active)\n"
98 " pointLight(0, normal, eye, ecPosition3);\n"
100 " if(OSGLight1Active)\n"
101 " pointLight(1, normal, eye, ecPosition3);\n"
103 " if(OSGLight2Active)\n"
104 " pointLight(2, normal, eye, ecPosition3);\n"
106 " color = gl_FrontLightModelProduct.sceneColor +\n"
107 " Ambient * gl_FrontMaterial.ambient +\n"
108 " Diffuse * gl_FrontMaterial.diffuse;\n"
109 " color += Specular * gl_FrontMaterial.specular;\n"
110 " color = clamp( color, 0.0, 1.0 );\n"
111 " gl_FrontColor = color;\n"
112 " gl_FrontColor.a *= alphaFade;\n"
118 " vec3 transformedNormal;\n"
119 " float alphaFade = 1.0;\n"
121 " // Eye-coordinate position of vertex, needed in various calculations\n"
122 " vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;\n"
124 " // Do fixed functionality vertex transform\n"
125 " gl_Position = ftransform();\n"
126 " transformedNormal = fnormal();\n"
127 " flight(transformedNormal, ecPosition, alphaFade);\n"
130 // fragment shader program for bump mapping in surface local coordinates
131 static std::string _fp_program
=
135 " color = gl_Color;\n"
136 " gl_FragColor = color;\n"
140 // ------------------- global vars ----------------------
142 // The SimpleSceneManager to manage simple applications
143 static OSG::SimpleSceneManagerRefPtr _mgr
;
145 static OSG::NodeRecPtr _scene
;
146 static OSG::PointLightRecPtr _point1_core
;
147 static OSG::PointLightRecPtr _point2_core
;
148 static OSG::PointLightRecPtr _point3_core
;
150 OSG::NodeUnrecPtr point1_beacon
;
151 OSG::NodeUnrecPtr point2_beacon
;
152 OSG::NodeUnrecPtr point3_beacon
;
154 // forward declaration so we can have the interesting stuff upfront
155 int setupGLUT( int *argc
, char *argv
[] );
157 // Shows how to add your own parameter callbacks.
160 // Initialize GLUT & OpenSG and set up the scene
161 int doMain(int argc
, char **argv
)
163 printf("Press key '1', '2', or '3' to toggle the light sources.\n");
165 OSG::osgInit(argc
,argv
);
168 int winid
= setupGLUT(&argc
, argv
);
170 // the connection between GLUT and OpenSG
171 OSG::GLUTWindowUnrecPtr gwin
= OSG::GLUTWindow::create();
173 gwin
->setGlutId(winid
);
174 gwin
->setSize( 800, 800 );
177 // Create the shader material
179 OSG::ChunkMaterialUnrecPtr cmat
= OSG::ChunkMaterial::create();
181 OSG::MaterialChunkUnrecPtr matc
= OSG::MaterialChunk::create();
183 matc
->setAmbient(OSG::Color4f(0.1f
, 0.1f
, 0.1f
, 1.0f
));
184 matc
->setDiffuse(OSG::Color4f(0.3f
, 0.3f
, 0.3f
, 1.0f
));
185 matc
->setSpecular(OSG::Color4f(0.8f
, 0.8f
, 0.8f
, 1.0f
));
186 matc
->setShininess(100);
189 OSG::ShaderProgramChunkUnrecPtr shl
= OSG::ShaderProgramChunk::create();
191 OSG::ShaderProgramUnrecPtr shl_vp
=
192 OSG::ShaderProgram::createVertexShader();
194 shl_vp
->setProgram(_vp_program
);
196 shl
->addShader(shl_vp
);
198 OSG::ShaderProgramUnrecPtr shl_fp
=
199 OSG::ShaderProgram::createFragmentShader();
201 shl_fp
->setProgram(_fp_program
);
203 shl
->addShader(shl_fp
);
205 shl_vp
->addUniformVariable("OSGLight0Active", 0);
206 shl_vp
->addUniformVariable("OSGLight1Active", 0);
207 shl_vp
->addUniformVariable("OSGLight2Active", 0);
208 shl_vp
->addUniformVariable("OSGViewMatrix", 0);
210 cmat
->addChunk(matc
);
214 _scene
= OSG::Node::create();
216 // create two light sources.
218 OSG::TransformUnrecPtr point1_trans
;
220 OSG::NodeUnrecPtr point1
=
221 OSG::makeCoredNode
<OSG::PointLight
>(&_point1_core
);
222 point1_beacon
= OSG::makeCoredNode
<OSG::Transform
>(&point1_trans
);
224 point1_trans
->editMatrix().setTranslate(-10.0, 5.0, 5.0);
226 _point1_core
->setAmbient(0.0f
, 0.0f
, 0.0f
, 1.0f
);
227 _point1_core
->setDiffuse(1.0f
, 0.0f
, 0.0f
, 1.0f
);
228 _point1_core
->setSpecular(1.0f
, 1.0f
, 1.0f
, 1.0f
);
229 _point1_core
->setBeacon(point1_beacon
);
230 _point1_core
->setOn(true);
233 OSG::TransformUnrecPtr point2_trans
;
235 OSG::NodeUnrecPtr point2
=
236 OSG::makeCoredNode
<OSG::PointLight
>(&_point2_core
);
237 point2_beacon
= OSG::makeCoredNode
<OSG::Transform
>(&point2_trans
);
239 point2_trans
->editMatrix().setTranslate(10.0, 5.0, 5.0);
241 _point2_core
->setAmbient(0.0f
, 0.0f
, 0.0f
, 1.0f
);
242 _point2_core
->setDiffuse(0.0f
, 1.0f
, 0.0f
, 1.0f
);
243 _point2_core
->setSpecular(1.0f
, 1.0f
, 1.0f
, 1.0f
);
244 _point2_core
->setBeacon(point2_beacon
);
245 _point2_core
->setOn(true);
247 point1
->addChild(point2
);
249 OSG::TransformUnrecPtr point3_trans
;
251 OSG::NodeUnrecPtr point3
=
252 OSG::makeCoredNode
<OSG::PointLight
>(&_point3_core
);
254 point3_beacon
= OSG::makeCoredNode
<OSG::Transform
>(&point3_trans
);
256 point3_trans
->editMatrix().setTranslate(0.0, -12.0, 5.0);
258 _point3_core
->setAmbient(0.0f
, 0.0f
, 0.0f
, 1.0f
);
259 _point3_core
->setDiffuse(0.5f
, 0.0f
, 1.0f
, 1.0f
);
260 _point3_core
->setSpecular(1.0f
, 1.0f
, 1.0f
, 1.0f
);
261 _point3_core
->setBeacon(point3_beacon
);
262 _point3_core
->setOn(true);
264 point2
->addChild(point3
);
268 OSG::GeometryUnrecPtr geo
= OSG::makeLatLongSphereGeo (100, 100, 1.0);
270 geo
->setMaterial(cmat
);
273 OSG::NodeUnrecPtr sphere
= OSG::makeNodeFor(geo
);
275 point3
->addChild(sphere
);
278 _scene
->setCore(OSG::Group::create());
279 _scene
->addChild(point1
);
281 // create the SimpleSceneManager helper
282 _mgr
= OSG::SimpleSceneManager::create();
284 // tell the manager what to manage
285 _mgr
->setWindow(gwin
);
286 _mgr
->setRoot(_scene
);
288 _mgr
->turnHeadlightOff();
290 // show the whole scene
293 // enable local lights.
294 // OSG::RenderAction *ract =
295 // dynamic_cast<OSG::RenderAction *>(_mgr->getRenderAction());
297 // ract->setLocalLights(true);
302 // Initialize GLUT & OpenSG and set up the scene
303 int main(int argc
, char **argv
)
305 if(doMain(argc
, argv
) != 0)
315 // GLUT callback functions
325 // react to size changes
326 void reshape(int w
, int h
)
332 // react to mouse button presses
333 void mouse(int button
, int state
, int x
, int y
)
336 _mgr
->mouseButtonRelease(button
, x
, y
);
338 _mgr
->mouseButtonPress(button
, x
, y
);
343 // react to mouse motions with pressed buttons
344 void motion(int x
, int y
)
346 _mgr
->mouseMove(x
, y
);
351 void keyboard(unsigned char k
, int x
, int y
)
362 point1_beacon
= NULL
;
363 point2_beacon
= NULL
;
364 point3_beacon
= NULL
;
373 OSG::SceneFileHandler::the()->write(_scene
, "scene.osb.gz", true);
374 printf("wrote scene.osb.gz\n");
378 if(_point1_core
->getOn() == false)
379 _point1_core
->setOn(true);
381 _point1_core
->setOn(false);
387 if(_point2_core
->getOn() == false)
388 _point2_core
->setOn(true);
390 _point2_core
->setOn(false);
396 if(_point3_core
->getOn() == false)
397 _point3_core
->setOn(true);
399 _point3_core
->setOn(false);
407 // setup the GLUT library which handles the windows for us
408 int setupGLUT(int *argc
, char *argv
[])
410 glutInit(argc
, argv
);
411 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
413 int winid
= glutCreateWindow("OpenSG CG Shader");
415 glutReshapeFunc(reshape
);
416 glutDisplayFunc(display
);
417 glutMouseFunc(mouse
);
418 glutMotionFunc(motion
);
419 glutKeyboardFunc(keyboard
);