1 // OpenSG Tutorial Example: Materials
3 // This example shows how to create a material. Materials define the surface
4 // properties of the geometry, and change how they look.
6 // This example shows the usage of SimpleMaterial and SimpleTexturedMaterial.
7 // Call it with an image filename as a parameter.
10 #ifdef OSG_BUILD_ACTIVE
13 #include <OSGConfig.h>
14 #include <OSGSimpleGeometry.h>
15 #include <OSGGLUTWindow.h>
16 #include <OSGSimpleSceneManager.h>
17 #include <OSGBaseFunctions.h>
18 #include <OSGTransform.h>
23 // the headers for the SimpleMaterials
24 #include <OSGSimpleMaterial.h>
25 #include <OSGSimpleTexturedMaterial.h>
29 #include <OpenSG/OSGGLUT.h>
30 #include <OpenSG/OSGConfig.h>
31 #include <OpenSG/OSGSimpleGeometry.h>
32 #include <OpenSG/OSGGLUTWindow.h>
33 #include <OpenSG/OSGSimpleSceneManager.h>
34 #include <OpenSG/OSGBaseFunctions.h>
35 #include <OpenSG/OSGTransform.h>
36 #include <OpenSG/OSGGroup.h>
40 // the headers for the SimpleMaterials
41 #include <OpenSG/OSGSimpleMaterial.h>
42 #include <OpenSG/OSGSimpleTexturedMaterial.h>
43 #include <OpenSG/OSGImage.h>
46 // a separate transformation for every object
47 OSG::TransformRefPtr cyltrans
, tortrans
;
50 // The SimpleSceneManager to manage simple applications
51 OSG::SimpleSceneManagerRefPtr mgr
;
53 // forward declaration so we can have the interesting stuff upfront
54 int setupGLUT(int *argc
, char *argv
[]);
61 OSG::Real32 t
= glutGet(GLUT_ELAPSED_TIME
);
63 // set the transforms' matrices
64 m
.setTransform(OSG::Vec3f(0, 0, OSG::osgSin(t
/ 1000.f
) * 1.5),
65 OSG::Quaternion( OSG::Vec3f (1, 0, 0), t
/ 500.f
));
67 cyltrans
->setMatrix(m
);
69 m
.setTransform(OSG::Vec3f(OSG::osgSin(t
/ 1000.f
), 0, 0),
70 OSG::Quaternion( OSG::Vec3f (0, 0, 1), t
/ 1000.f
));
72 tortrans
->setMatrix(m
);
80 // Initialize GLUT & OpenSG and set up the scene
81 int main(int argc
, char **argv
)
84 OSG::osgInit(argc
,argv
);
87 int winid
= setupGLUT(&argc
, argv
);
89 // open a new scope, because the pointers below should go out of scope
90 // before entering glutMainLoop.
91 // Otherwise OpenSG will complain about objects being alive after shutdown.
93 // the connection between GLUT and OpenSG
94 OSG::GLUTWindowRefPtr gwin
= OSG::GLUTWindow::create();
95 gwin
->setGlutId(winid
);
100 // create a pretty simple graph: a Group with two Transforms as children,
101 // each of which carries a single Geometry.
105 OSG::NodeRefPtr scene
= OSG::Node::create();
106 OSG::GroupRefPtr g
= OSG::Group::create();
110 // The cylinder and its transformation
111 OSG::NodeRefPtr cyl
= OSG::Node::create();
112 OSG::GeometryRefPtr cylgeo
= OSG::makeCylinderGeo( 1.4f
, .3f
, 8,
115 cyl
->setCore(cylgeo
);
117 cyltrans
= OSG::Transform::create();
119 OSG::NodeRefPtr cyltransnode
= OSG::Node::create();
120 cyltransnode
->setCore (cyltrans
);
121 cyltransnode
->addChild(cyl
);
123 // add it to the scene
124 scene
->addChild(cyltransnode
);
126 // The torus and its transformation
127 OSG::NodeRefPtr torus
= OSG::Node::create();
128 OSG::GeometryRefPtr torusgeo
= OSG::makeTorusGeo( .2f
, 1, 8, 12 );
130 torus
->setCore(torusgeo
);
132 tortrans
= OSG::Transform::create();
134 OSG::NodeRefPtr tortransnode
= OSG::Node::create();
135 tortransnode
->setCore (tortrans
);
136 tortransnode
->addChild(torus
);
138 // add it to the scene
139 scene
->addChild(tortransnode
);
141 // now create and assign the materials
144 Materials in OpenSG are associated with the Geometry NodeCores, i.e.
145 every Geometry knows its material.
147 Right now there are two kinds of Materials: SimpleMaterial and
148 SimpleTexturedMaterial.
150 SimpleMaterial is a pretty direct wrapper of the OpenGL material
151 characteristics. It has an ambient, diffuse, emission and specular
152 color together with a shininess. It also defines the transparency of
153 the material. Finally there are two flags. Lit defines if the material
154 is influenced by light sources and the lighting calculation. If lit is
155 false, only the diffuse color is used. ColorMaterial defines if and
156 how the colors given in the object influence the lighting calculation.
157 Possible values are GL_NONE, GL_EMISSION, GL_AMBIENT, GL_DIFFUSE,
158 GL_SPECULAR and GL_AMBIENT_AND_DIFFUSE.
161 OSG::SimpleMaterialRefPtr m1
= OSG::SimpleMaterial::create();
163 // when everything is changed, not setting the mask is ok
164 m1
->setAmbient (OSG::Color3f(0.2f
,0.2f
,0.2f
));
165 m1
->setDiffuse (OSG::Color3f(0.8f
,0.5f
,0.2f
));
166 m1
->setEmission (OSG::Color3f(0.0f
,0.0f
,0.0f
));
167 m1
->setSpecular (OSG::Color3f(1.0f
,1.0f
,1.0f
));
168 m1
->setShininess (10);
171 Transparent objects are rendered last and sorted from back to
172 front, but only objectwise. Thus transparecy within an object is
173 not handled correctly.
175 m1
->setTransparency (0);
178 The SimpleGeometry objects do not contain colors, turn
181 m1
->setColorMaterial(GL_NONE
);
184 // assign the material to the geometry
185 cylgeo
->setMaterial(m1
);
189 SimpleTexturedMaterial is a SimpleMaterial with a texture.
191 The texture is specified using an Image, which can be created on the
192 fly or loaded from a file.
194 Additionally the texture filters can be changed via the
195 minFilter/magFilter fields. Possible values are taken from OpenGL's
196 glTexParameter() function. MinFilter can be GL_NEAREST, GL_LINEAR, and
197 the mipmap modes, the most common being GL_LINEAR_MIPMAP_LINEAR.
198 MagFilter can be GL_NEAREST or GL_LINEAR.
200 Textures are independent from the normal lighting calculations. How the
201 texture is combined with the lighting color is define by the envMode.
202 The possible values are taken from glTexEnv(). GL_MODULATE just
203 multiplies the two, GL_REPLACE ignores the lighting color and just uses
206 The option that the SimpleTexturedMaterial has is the ability to use
207 spherical environment maps. These can be used to simulate reflective
212 Images can be created directly from the data or loaded from disk.
214 The Image can handle a variety of data formats, including 1, 2, 3 or 4
215 component images, and 1, 2 or 3 dimensional data. It can load and save
216 a variety of formats, exactly which depends on the configured
220 OSG::ImageRefPtr image
= OSG::Image::create();
224 image
->read(argv
[1]);
228 OSG::UChar8 data
[] = { 0xff, 0xff, 0xff, 0x80, 0x00, 0x00,
229 0x80, 0x00, 0x00, 0xff, 0xff, 0xff };
231 image
->set( OSG::Image::OSG_RGB_PF
, 2, 2, 1, 1, 1, 0, data
);
234 OSG::SimpleTexturedMaterialRefPtr m2
=
235 OSG::SimpleTexturedMaterial::create();
237 m2
->setAmbient (OSG::Color3f(0.3f
,0.3f
,0.3f
));
238 m2
->setDiffuse (OSG::Color3f(0.2f
,0.8f
,0.8f
));
239 m2
->setEmission (OSG::Color3f(0.0f
,0.0f
,0.0f
));
240 m2
->setSpecular (OSG::Color3f(1.0f
,1.0f
,1.0f
));
241 m2
->setShininess (20);
242 m2
->setTransparency (0);
243 m2
->setColorMaterial(GL_NONE
);
245 m2
->setImage (image
);
246 m2
->setMinFilter (GL_LINEAR_MIPMAP_LINEAR
);
247 m2
->setMagFilter (GL_NEAREST
);
248 m2
->setEnvMode (GL_MODULATE
);
249 m2
->setEnvMap (false);
251 // assign the material to the geometry
252 torusgeo
->setMaterial(m2
);
254 OSG::commitChanges();
256 // create the SimpleSceneManager helper
257 mgr
= OSG::SimpleSceneManager::create();
259 // tell the manager what to manage
260 mgr
->setWindow(gwin
);
261 mgr
->setRoot (scene
);
263 // show the whole scene
274 // GLUT callback functions
277 // react to size changes
278 void reshape(int w
, int h
)
284 // react to mouse button presses
285 void mouse(int button
, int state
, int x
, int y
)
288 mgr
->mouseButtonRelease(button
, x
, y
);
290 mgr
->mouseButtonPress(button
, x
, y
);
295 // react to mouse motions with pressed buttons
296 void motion(int x
, int y
)
298 mgr
->mouseMove(x
, y
);
303 void keyboard(unsigned char k
, int x
, int y
)
309 // clean up global variables
321 mgr
->setStatistics(!mgr
->getStatistics());
327 // setup the GLUT library which handles the windows for us
328 int setupGLUT(int *argc
, char *argv
[])
330 glutInit(argc
, argv
);
331 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
333 int winid
= glutCreateWindow("OpenSG");
335 glutReshapeFunc(reshape
);
336 glutDisplayFunc(display
);
337 glutMouseFunc(mouse
);
338 glutMotionFunc(motion
);
339 glutKeyboardFunc(keyboard
);
341 // call the redraw function whenever there's nothing else to do
342 glutIdleFunc(display
);