changed: gcc8 base update
[opensg.git] / Examples / Simple / phongshaderwithglmaterials.cpp
bloba43b0ed42b1033afa8cd4497792c59f2b4046e6a
1 // OpenSG Tutorial Example: Phong Shader with OpenGL Materials
2 //
3 // This example shows how to use a GLSL Phong shader with materials brought
4 // along with the Model.
5 // It shows how to add/remove the phong shader chunk and how to use the
6 // OpenGL Materials though built-in variables like gl_FrontMaterial.
8 #ifdef OSG_BUILD_ACTIVE
9 // Headers
10 #include <OSGGLUT.h>
11 #include <OSGConfig.h>
12 #include <OSGGLUTWindow.h>
13 #include <OSGSimpleSceneManager.h>
14 #include <OSGSimpleGeometry.h>
15 #include <OSGSceneFileHandler.h>
16 #include <OSGSimpleSHLChunk.h>
17 #include <OSGMaterialGroup.h>
18 #include <OSGGradientBackground.h>
19 #else
20 // Headers
21 #include <OpenSG/OSGGLUT.h>
22 #include <OpenSG/OSGConfig.h>
23 #include <OpenSG/OSGGLUTWindow.h>
24 #include <OpenSG/OSGSimpleSceneManager.h>
25 #include <OpenSG/OSGSimpleGeometry.h>
26 #include <OpenSG/OSGSceneFileHandler.h>
27 #include <OpenSG/OSGSimpleSHLChunk.h>
28 #include <OpenSG/OSGMaterialGroup.h>
29 #include <OpenSG/OSGGradientBackground.h>
30 #endif
32 using namespace OSG;
34 // The SimpleSceneManager to manage simple applications
35 SimpleSceneManagerRefPtr _mgr = NULL;
37 bool phong_active = false;
38 std::vector<ChunkMaterialRefPtr> materials;
39 SimpleSHLChunkRefPtr phong_chunk;
41 NodeRefPtr scene;
44 //----------------------------------------------------
45 //phong_chunk Shader
46 //----------------------------------------------------
47 // vertex shader program.
48 static std::string _vp_program =
49 "\n"
50 "varying vec3 ViewDirection;\n"
51 "varying vec3 fvObjectPosition;\n"
52 "varying vec3 Normal;\n"
53 " \n"
54 "void main( void )\n"
55 "{\n"
56 " gl_Position = ftransform();\n"
57 " \n"
58 " fvObjectPosition = vec3(gl_ModelViewMatrix * gl_Vertex);\n"
59 " \n"
60 " ViewDirection = - fvObjectPosition.xyz;\n"
61 " Normal = gl_NormalMatrix * gl_Normal;\n"
62 " gl_FrontColor = gl_FrontMaterial.diffuse;\n"
63 " \n"
64 "}\n";
66 // fragment shader program for bump mapping in surface local coordinates
67 static std::string _fp_program =
68 "vec4 fvAmbient = vec4(0.36, 0.36, 0.36, 1.0);\n"
69 "vec4 fvSpecular = vec4(0.7, 0.7, 0.7, 1.0);\n"
70 "vec4 fvDiffuse = vec4(0.5, 0.5, 0.5, 1.0);\n"
71 "float fSpecularPower = 25.0;\n"
72 "\n"
73 "uniform sampler2D baseMap;\n"
74 "uniform int useTexture;\n"
75 "\n"
76 "varying vec2 Texcoord;\n"
77 "varying vec3 ViewDirection;\n"
78 "varying vec3 fvObjectPosition;\n"
79 "varying vec3 Normal;\n"
80 "\n"
81 "void main( void )\n"
82 "{\n"
83 " vec3 fvLightDirection = normalize( gl_LightSource[0].position.xyz - fvObjectPosition.xyz);\n"
84 " vec3 fvNormal = normalize( Normal );\n"
85 " float fNDotL = dot( fvNormal, fvLightDirection ); \n"
86 " \n"
87 " vec3 fvReflection = normalize( ( ( 2.0 * fvNormal ) * fNDotL ) - fvLightDirection ); \n"
88 " vec3 fvViewDirection = normalize( ViewDirection );\n"
89 " float fRDotV = max( 0.0, dot( fvReflection, fvViewDirection ) );\n"
90 " \n"
91 " vec4 fvBaseColor = gl_Color;\n"
92 " \n"
93 " vec4 fvTotalAmbient = fvAmbient * fvBaseColor; \n"
94 " vec4 fvTotalDiffuse = fvDiffuse * fNDotL * fvBaseColor; \n"
95 " vec4 fvTotalSpecular = fvSpecular * ( pow( fRDotV, fSpecularPower ) );\n"
96 " \n"
97 " gl_FragColor = ( fvTotalAmbient + fvTotalDiffuse + fvTotalSpecular );\n"
98 "}\n";
100 // forward declaration so we can have the interesting stuff upfront
101 int setupGLUT(int *argc, char *argv[]);
104 // ---------------------------------------------------------------------------------
106 // redraw the window
107 void display(void)
109 _mgr->redraw();
112 // ---------------------------------------------------------------------------------
114 void update(void)
116 glutPostRedisplay();
119 // ---------------------------------------------------------------------------------
121 SimpleSHLChunkTransitPtr createPhongShaderMaterial(void)
123 SimpleSHLChunkRefPtr _shl = SimpleSHLChunk::create();
125 _shl->setVertexProgram(_vp_program);
126 _shl->setFragmentProgram(_fp_program);
128 return SimpleSHLChunkTransitPtr(_shl);
131 // ---------------------------------------------------------------------------------
133 ChunkMaterial *getChunkMaterial(Node *node)
135 NodeCore *pCore = node->getCore();
136 ChunkMaterialRefPtr cm;
138 if((pCore != NULL) &&
139 (pCore->getType().isDerivedFrom(MaterialGroup::getClassType())))
141 MaterialGroupRefPtr g = dynamic_cast<MaterialGroup *>(pCore);
142 cm = dynamic_cast<ChunkMaterial *>(g->getMaterial());
144 else if((pCore != NULL) &&
145 (pCore->getType().isDerivedFrom(Geometry::getClassType())))
147 GeometryRefPtr g = dynamic_cast<Geometry *>(pCore);
148 cm = dynamic_cast<ChunkMaterial *>(g->getMaterial());
151 return cm;
154 // ---------------------------------------------------------------------------------
156 void getAllMaterials(Node *node, std::vector<ChunkMaterialRefPtr> &mats)
158 ChunkMaterial *cm = getChunkMaterial(node);
160 if(cm != NULL)
162 mats.push_back(cm);
165 for(UInt32 i = 0; i < node->getNChildren(); ++i)
166 getAllMaterials(node->getChild(i), mats);
169 // ---------------------------------------------------------------------------------
171 // Initialize GLUT & OpenSG and set up the scene
172 int main(int argc, char **argv)
174 // OSG init
175 osgInit(argc,argv);
177 // GLUT init
178 int winid = setupGLUT(&argc, argv);
180 if(argc >= 2)
181 scene = SceneFileHandler::the()->read(argv[1]);
182 else
183 scene = SceneFileHandler::the()->read("Data/tie.wrl");
185 if(scene == NULL)
186 scene = makeTorus(0.3f, 4.0f, 16, 64);
188 // init material
189 phong_chunk = createPhongShaderMaterial();
191 // get all the Materials of the current scene
192 getAllMaterials(scene, materials);
194 // add the phong material chunk to every found material
195 for(int i = 0; i < materials.size(); ++i)
197 (materials[i])->addChunk(phong_chunk);
199 phong_active = true;
201 // open a new scope, because the pointers below should go out of scope
202 // before entering glutMainLoop.
203 // Otherwise OpenSG will complain about objects being alive after shutdown.
205 // the connection between GLUT and OpenSG
206 GLUTWindowRefPtr gwin = GLUTWindow::create();
207 gwin->setGlutId(winid);
208 gwin->init ( );
210 // create the SimpleSceneManager helper
211 _mgr = SimpleSceneManager::create();
213 // tell the manager what to manage
214 _mgr->setWindow (gwin );
215 _mgr->setRoot (scene);
216 _mgr->turnHeadlightOn( );
218 commitChanges();
220 // show the whole scene
221 _mgr->showAll();
223 // create a gradient background.
224 GradientBackgroundRefPtr gbg = GradientBackground::create();
225 gbg->clearLines();
226 gbg->addLine(Color3f(0.7f, 0.7f, 0.8f), 0.f);
227 gbg->addLine(Color3f(0.0f, 0.1f, 0.3f), 1.f);
229 //set gradient background
230 ViewportRefPtr vp = gwin->getPort(0);
231 vp->setBackground(gbg);
233 commitChanges();
236 // GLUT main loop
237 glutMainLoop();
239 return 0;
243 // GLUT callback functions
246 // react to size changes
247 void reshape(int w, int h)
249 _mgr->resize(w, h);
250 glutPostRedisplay();
253 // ---------------------------------------------------------------------------------
255 // react to mouse button presses
256 void mouse(int button, int state, int x, int y)
258 if (state)
259 _mgr->mouseButtonRelease(button, x, y);
260 else
261 _mgr->mouseButtonPress(button, x, y);
263 glutPostRedisplay();
266 // ---------------------------------------------------------------------------------
268 // react to mouse motions with pressed buttons
269 void motion(int x, int y)
271 _mgr->mouseMove(x, y);
272 glutPostRedisplay();
275 // ---------------------------------------------------------------------------------
277 // react to keys
278 void keyboard(unsigned char k, int x, int y)
280 switch(k)
282 case '1':
284 if(phong_active == false)
286 for (int i = 0; i < materials.size(); ++i)
288 (materials[i])->addChunk(phong_chunk);
290 phong_active = true;
291 std::cout << "Phong Shader" << std::endl;
293 break;
295 case '2':
297 if(phong_active == true)
299 for (int i = 0; i < materials.size(); ++i)
301 (materials[i])->subChunk(phong_chunk);
303 phong_active = false;
304 std::cout << "Standard OpenGL" << std::endl;
306 break;
308 case 27:
309 // clean up global variables
310 _mgr = NULL;
312 materials.clear();
313 phong_chunk = NULL;
314 scene = NULL;
316 OSG::osgExit();
317 exit(0);
318 break;
319 case 'x':
320 SceneFileHandler::the()->write(_mgr->getRoot(), "scene.osb.gz", true);
321 printf("wrote scene.\n");
322 break;
326 // ---------------------------------------------------------------------------------
328 int setupGLUT(int *argc, char *argv[])
330 glutInit(argc, argv);
331 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
333 int winid = glutCreateWindow("OpenSG Shader Material");
335 std::cout << "OpenSG Tutorial Example: Phong Shader with OpenGL Materials"
336 << std::endl;
337 std::cout << "Press Keys 1/2 to switch between Standard OpenGL "
338 << "and Phong Shader visualization"
339 << std::endl;
341 glutReshapeFunc(reshape);
342 glutDisplayFunc(display);
343 glutMouseFunc(mouse);
344 glutMotionFunc(motion);
345 glutKeyboardFunc(keyboard);
347 glutIdleFunc(update);
349 return winid;