1 // OpenSG Tutorial Example: Phong Shader with OpenGL Materials
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
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>
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>
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
;
44 //----------------------------------------------------
46 //----------------------------------------------------
47 // vertex shader program.
48 static std::string _vp_program
=
50 "varying vec3 ViewDirection;\n"
51 "varying vec3 fvObjectPosition;\n"
52 "varying vec3 Normal;\n"
56 " gl_Position = ftransform();\n"
58 " fvObjectPosition = vec3(gl_ModelViewMatrix * gl_Vertex);\n"
60 " ViewDirection = - fvObjectPosition.xyz;\n"
61 " Normal = gl_NormalMatrix * gl_Normal;\n"
62 " gl_FrontColor = gl_FrontMaterial.diffuse;\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"
73 "uniform sampler2D baseMap;\n"
74 "uniform int useTexture;\n"
76 "varying vec2 Texcoord;\n"
77 "varying vec3 ViewDirection;\n"
78 "varying vec3 fvObjectPosition;\n"
79 "varying vec3 Normal;\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"
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"
91 " vec4 fvBaseColor = gl_Color;\n"
93 " vec4 fvTotalAmbient = fvAmbient * fvBaseColor; \n"
94 " vec4 fvTotalDiffuse = fvDiffuse * fNDotL * fvBaseColor; \n"
95 " vec4 fvTotalSpecular = fvSpecular * ( pow( fRDotV, fSpecularPower ) );\n"
97 " gl_FragColor = ( fvTotalAmbient + fvTotalDiffuse + fvTotalSpecular );\n"
100 // forward declaration so we can have the interesting stuff upfront
101 int setupGLUT(int *argc
, char *argv
[]);
104 // ---------------------------------------------------------------------------------
112 // ---------------------------------------------------------------------------------
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());
154 // ---------------------------------------------------------------------------------
156 void getAllMaterials(Node
*node
, std::vector
<ChunkMaterialRefPtr
> &mats
)
158 ChunkMaterial
*cm
= getChunkMaterial(node
);
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
)
178 int winid
= setupGLUT(&argc
, argv
);
181 scene
= SceneFileHandler::the()->read(argv
[1]);
183 scene
= SceneFileHandler::the()->read("Data/tie.wrl");
186 scene
= makeTorus(0.3f
, 4.0f
, 16, 64);
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
);
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
);
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( );
220 // show the whole scene
223 // create a gradient background.
224 GradientBackgroundRefPtr gbg
= GradientBackground::create();
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
);
243 // GLUT callback functions
246 // react to size changes
247 void reshape(int w
, int h
)
253 // ---------------------------------------------------------------------------------
255 // react to mouse button presses
256 void mouse(int button
, int state
, int x
, int y
)
259 _mgr
->mouseButtonRelease(button
, x
, y
);
261 _mgr
->mouseButtonPress(button
, x
, y
);
266 // ---------------------------------------------------------------------------------
268 // react to mouse motions with pressed buttons
269 void motion(int x
, int y
)
271 _mgr
->mouseMove(x
, y
);
275 // ---------------------------------------------------------------------------------
278 void keyboard(unsigned char k
, int x
, int y
)
284 if(phong_active
== false)
286 for (int i
= 0; i
< materials
.size(); ++i
)
288 (materials
[i
])->addChunk(phong_chunk
);
291 std::cout
<< "Phong Shader" << std::endl
;
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
;
309 // clean up global variables
320 SceneFileHandler::the()->write(_mgr
->getRoot(), "scene.osb.gz", true);
321 printf("wrote scene.\n");
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"
337 std::cout
<< "Press Keys 1/2 to switch between Standard OpenGL "
338 << "and Phong Shader visualization"
341 glutReshapeFunc(reshape
);
342 glutDisplayFunc(display
);
343 glutMouseFunc(mouse
);
344 glutMotionFunc(motion
);
345 glutKeyboardFunc(keyboard
);
347 glutIdleFunc(update
);