fixed: compile issue
[opensg.git] / Examples / Simple / videotexturebackground.cpp
blob74a8305079830446d575b4c34ff3884e1c13ade6
1 // OpenSG Tutorial Example: Changing Texture on Background
3 // This example shows how to change the texture displayed on a
4 // TextureBackground in each frame. This could be used to play back a video.
6 #ifdef OSG_BUILD_ACTIVE
8 #include <OSGConfig.h>
9 #include <OSGGLUT.h>
10 #include <OSGSimpleGeometry.h>
11 #include <OSGGLUTWindow.h>
12 #include <OSGSimpleSceneManager.h>
14 #include <OSGTextureObjChunk.h>
15 #include <OSGBaseFunctions.h>
17 #include <OSGTextureBackground.h>
18 #include <OSGImage.h>
20 #else
22 #include <OpenSG/OSGConfig.h>
23 #include <OpenSG/OSGGLUT.h>
24 #include <OpenSG/OSGSimpleGeometry.h>
25 #include <OpenSG/OSGGLUTWindow.h>
26 #include <OpenSG/OSGSimpleSceneManager.h>
28 #include <OpenSG/OSGTextureObjChunk.h>
29 #include <OpenSG/OSGBaseFunctions.h>
31 #include <OpenSG/OSGTextureBackground.h>
32 #include <OpenSG/OSGImage.h>
34 #endif // OSG_BUILD_ACTIVE
36 // The pointer to the transformation
38 OSG::TransformRefPtr trans;
40 // The pointer to the dynamic image and the texture
42 OSG::ImageRefPtr image;
43 OSG::TextureObjChunkRefPtr texObj;
45 // Some helper flags for different code pathes
46 // flag to indicate whether the images are power-of-two (POT) in size or not
48 bool isPOT = false;
50 // flag to indicate whether NPOT textures are available
51 // Purely informative, the code doesn't really care.
53 bool hasNPOT = false;
56 // flag to indicate that only a small part of the image should be changed
57 // per frame. The random image generation can get slow for large
58 // images.
60 bool changeOnlyPart = false;
62 // The SimpleSceneManager to manage simple applications
64 OSG::SimpleSceneManagerRefPtr mgr;
66 // forward declaration so we can have the interesting stuff upfront
68 int setupGLUT(int *argc, char *argv[]);
69 void cleanup (void );
71 // Grab/update the image
72 // This just update the image's data and tells the texture that it changed.
73 // For a video this would grab the next frame
75 void grabImage(OSG::Image *img)
77 OSG::UInt8* data = img->editData();
79 // for this example, just fill it with random junk
80 if(changeOnlyPart)
82 // Just change a small rectangular area
83 OSG::UInt32 x = rand() % (img->getWidth() - 100);
84 OSG::UInt32 y = rand() % (img->getHeight() - 100);
85 OSG::UInt32 w = rand() % 100;
86 OSG::UInt32 h = rand() % 100;
87 OSG::UInt32 bpp = img->getBpp();
88 OSG::UInt32 bpl = img->getWidth() * bpp;
89 OSG::UInt32 bytes = w * bpp;
91 data += y * bpl + x * bpp;
93 OSG::UInt8 val = ((rand() & 0x7f) + 0x80);
95 for(OSG::UInt32 i = h; i > 0; --i, data += bpl)
97 OSG::UInt8 *d = data;
99 for(OSG::UInt32 j = bytes; j > 0; --j)
100 *d++ = val;
103 // If only a part of the image changed, only that part needs to
104 // be updated. The speed of the update operation is pretty
105 // directly dependent on the amount of data changed.
106 texObj->imageContentChanged(x, x + w, y, y + h);
108 else
111 // Fill the whole picture
113 for(OSG::UInt32 i = img->getHeight(); i > 0; --i)
115 OSG::UInt8 val = ((rand() & 0x3f) + 0x80);
117 for(OSG::UInt32 j = img->getWidth() * img->getBpp(); j > 0; --j)
118 *data++ = val;
121 // Everything changed
122 texObj->imageContentChanged();
128 // redraw the window
129 void display( void )
131 // update the geometry
132 OSG::Matrix m;
134 OSG::Real32 t = glutGet(GLUT_ELAPSED_TIME );
136 m.setTransform(OSG::Vec3f(OSG::osgSin(t / 1000.f),
137 OSG::osgCos(t / 1000.f),
138 OSG::osgSin(t / 1000.f)),
140 OSG::Quaternion( OSG::Vec3f(0,1,0), t / 1000.f));
142 trans->setMatrix(m);
144 // update the image
146 grabImage(image);
148 // redraw the screen
150 mgr->redraw();
153 void update(void)
155 glutPostRedisplay();
158 // Initialize GLUT & OpenSG and set up the scene
159 int main(int argc, char **argv)
161 // OSG init
162 OSG::osgInit(argc,argv);
164 // GLUT init
165 int winid = setupGLUT(&argc, argv);
168 // the connection between GLUT and OpenSG
169 OSG::GLUTWindowRefPtr gwin = OSG::GLUTWindow::create();
171 gwin->setGlutId(winid);
172 gwin->init();
174 // create the scene
175 OSG::NodeRefPtr torus = OSG::makeTorus( .5, 2, 16, 32 );
176 OSG::NodeRefPtr scene = OSG::Node::create();
178 trans = OSG::Transform::create();
180 scene->setCore(trans);
181 scene->addChild(torus);
183 // Create the parts needed for the video background
184 OSG::UInt32 width = 640;
185 OSG::UInt32 height = 480;
187 // get the desired size from the command line
188 if(argc >= 3)
190 width = atoi(argv[1]);
191 height = atoi(argv[2]);
194 // To check OpenGL extensions, the Window needs to have run through
195 // frameInit at least once. This automatically happens when rendering,
196 // but we can't wait for that here.
198 gwin->activate ();
199 gwin->frameInit();
201 // Now we can check for OpenGL extensions
202 hasNPOT = gwin->hasExtension("GL_ARB_texture_non_power_of_two");
204 // Print what we've got
205 SLOG << "Got " << (isPOT?"":"non-") << "power-of-two images and "
206 << (hasNPOT?"can":"cannot") << " use NPOT textures, changing "
207 << (changeOnlyPart?"part":"all")
208 << " of the screen"
209 << std::endl;
211 // Ok, now for the meat of the code...
212 // first we need an Image to hold the picture(s) to show
213 image = OSG::Image::create();
215 // set the image's size and type, and allocate memory
216 // this example uses RGB. On some systems (e.g. Windows) BGR
217 // or BGRA might be faster, it depends on how the images are
218 // acquired
220 image->set(OSG::Image::OSG_RGB_PF, width, height);
224 // Now create the texture to be used for the background
225 texObj = OSG::TextureObjChunk::create();
227 // Associate image and texture
228 texObj->setImage(image);
230 // Set filtering modes. LINEAR is cheap and good if the image size
231 // changes very little (i.e. the window is about the same size as
232 // the images).
234 texObj->setMinFilter(GL_LINEAR);
235 texObj->setMagFilter(GL_LINEAR);
237 // Set the wrapping modes. We don't need repetition, it might actually
238 // introduce artifactes at the borders, so switch it off.
240 texObj->setWrapS(GL_CLAMP_TO_EDGE);
241 texObj->setWrapT(GL_CLAMP_TO_EDGE);
243 // Newer versions of OpenGL can handle NPOT textures directly.
244 // OpenSG will do that internally automatically.
246 // Older versions need POT textures. By default OpenSG
247 // will scale an NPOT texture to POT while defining it.
248 // For changing textures that's too slow.
249 // So tell OpenSG not to scale the image and adjust the texture
250 // coordinates used by the TextureBackground (see below).
252 texObj->setScale(false);
254 // Create the background
256 OSG::TextureBackgroundRefPtr back = OSG::TextureBackground::create();
258 // Set the texture to use
259 back->setTexture(texObj);
261 // if the image is NPOT and we don't have hardware support for it
262 // adjust the texture coordinates.
263 if(isPOT == false && hasNPOT == false)
265 OSG::UInt32 potWidth = OSG::osgNextPower2(width );
266 OSG::UInt32 potHeight = OSG::osgNextPower2(height);
268 OSG::Real32 tcRight = OSG::Real32(width ) / OSG::Real32(potWidth );
269 OSG::Real32 tcTop = OSG::Real32(height) / OSG::Real32(potHeight);
271 back->editMFTexCoords()->push_back(OSG::Vec2f( 0.f, 0.f));
272 back->editMFTexCoords()->push_back(OSG::Vec2f(tcRight, 0.f));
273 back->editMFTexCoords()->push_back(OSG::Vec2f(tcRight, tcTop));
274 back->editMFTexCoords()->push_back(OSG::Vec2f( 0.f, tcTop));
277 OSG::commitChanges();
279 // create the SimpleSceneManager helper
280 mgr = OSG::SimpleSceneManager::create();
282 // tell the manager what to manage
283 mgr->setWindow(gwin );
284 mgr->setRoot (scene);
285 mgr->setStatistics(true);
287 // replace the background
288 // This has to be done after the viewport has been created, which the
289 // SSM does in setRoot().
291 OSG::ViewportRefPtr vp = gwin->getPort(0);
293 vp->setBackground(back);
296 // show the whole scene
297 mgr->showAll();
299 // GLUT main loop
300 glutMainLoop();
302 return 0;
307 // GLUT callback functions
310 // react to size changes
311 void reshape(int w, int h)
313 mgr->resize(w, h);
315 glutPostRedisplay();
318 // react to mouse button presses
319 void mouse(int button, int state, int x, int y)
321 if (state)
322 mgr->mouseButtonRelease(button, x, y);
323 else
324 mgr->mouseButtonPress(button, x, y);
326 glutPostRedisplay();
329 // react to mouse motions with pressed buttons
330 void motion(int x, int y)
332 mgr->mouseMove(x, y);
334 glutPostRedisplay();
337 // react to keys
338 void keyboard(unsigned char k, int x, int y)
340 switch(k)
342 case 27:
344 cleanup();
345 OSG::osgExit();
346 exit(0);
348 break;
352 // setup the GLUT library which handles the windows for us
353 int setupGLUT(int *argc, char *argv[])
355 glutInit(argc, argv);
357 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
358 int winid = glutCreateWindow("OpenSG");
360 glutReshapeFunc(reshape);
361 glutDisplayFunc(display);
362 glutMouseFunc(mouse);
363 glutMotionFunc(motion);
365 glutKeyboardFunc(keyboard);
367 // call the redraw function whenever there's nothing else to do
368 glutIdleFunc(update);
370 return winid;
373 void cleanup(void)
375 mgr = NULL;
377 trans = NULL;
378 image = NULL;
379 texObj = NULL;
381 OSG::commitChanges();