fixed: compile issue
[opensg.git] / Examples / Simple / openglslave.cpp
blob625cd2df61c3ba7df626518676e2c9b0f06ba8f9
1 // OpenSG Tutorial Example: OpenGL slave
2 //
3 // Many thanks to Gernot Ziegler <gz@lysator.liu.se> for distributing this example.
4 //
5 // It is often necessary to mix non-OpenSG code with OpenSG.
6 // This is a quick way to melt such code-bases together.
7 // But remember that transparencies will be handled incorrectly
8 // as no polygon sorting happens between OpenSG and OpenGL.
9 // And since the OpenGL part will be never be culled like the OpenSG
10 // scenegraph, it can easily happen that large OpenGL objects significantly
11 // affect performance.
13 // Thanks to nehe.gamedev.net for the BMP image loading routines
14 // The mouse code is based on a tutorial from Dennis Gustavsson (dennis@meqon.com)
16 #ifdef OSG_BUILD_ACTIVE
17 // Headers
18 #include <OSGConfig.h>
19 #include <OSGGL.h>
20 #include <OSGGLU.h>
21 #include <OSGGLUT.h>
22 #include <OSGSimpleGeometry.h>
23 #include <OSGCamera.h>
24 #include <OSGMatrixCamera.h>
25 #include <OSGPerspectiveCamera.h>
26 #include <OSGViewport.h>
27 #include <OSGPassiveWindow.h>
28 #include <OSGPassiveBackground.h>
29 #include <OSGSimpleSceneManager.h>
30 #include <OSGSceneFileHandler.h>
31 #include <OSGComponentTransform.h>
32 #include <OSGImage.h>
33 #include <OSGFileSystem.h>
34 #else
35 // Headers
36 #include <OpenSG/OSGConfig.h>
37 #include <OpenSG/OSGGL.h>
38 #include <OpenSG/OSGGLU.h>
39 #include <OpenSG/OSGGLUT.h>
40 #include <OpenSG/OSGSimpleGeometry.h>
41 #include <OpenSG/OSGCamera.h>
42 #include <OpenSG/OSGMatrixCamera.h>
43 #include <OpenSG/OSGPerspectiveCamera.h>
44 #include <OpenSG/OSGViewport.h>
45 #include <OpenSG/OSGPassiveWindow.h>
46 #include <OpenSG/OSGPassiveBackground.h>
47 #include <OpenSG/OSGSimpleSceneManager.h>
48 #include <OpenSG/OSGSceneFileHandler.h>
49 #include <OpenSG/OSGComponentTransform.h>
50 #include <OpenSG/OSGImage.h>
51 #include <OpenSG/OSGFileSystem.h>
52 #endif
54 OSG::PassiveWindowRefPtr pwin;
55 OSG::SimpleSceneManagerRefPtr mgr;
57 int window; // The number of our GLUT window
58 GLuint texture[3]; // Storage for 3 textures.
60 int Width = 640, Height = 480;
62 GLUquadricObj *quadric; // Storage For Our Quadric Objects
64 // The pointer to the transformation
65 OSG::TransformRefPtr trans;
66 OSG::ViewportRefPtr vp;
67 OSG::PerspectiveCameraRefPtr cam;
68 OSG::MatrixCameraRefPtr newcam;
69 OSG::NodeRefPtr scene;
70 OSG::NodeRefPtr world;
72 int m_mouseX;
73 int m_mouseY;
74 float m_tiltAngle;
75 float m_twistAngle;
76 float m_distance;
77 bool m_bLeftMouseButtonDown;
78 bool m_bRightMouseButtonDown;
79 unsigned int m_lastTick; // last idle calc timestamp
80 unsigned int m_lastRenderTick; // last rendering timestamp
81 bool m_bPaused;
82 bool m_bFullscreen, m_bCalibrate = false;
84 // Load texture into memory
85 void LoadGLTextures(void)
87 OSG::ImageRefPtr image = OSG::Image::create();
88 if(!image->read("./worldground.jpg"))
90 printf("Could not read worldground.jpg!!\n");
91 exit(1);
94 // create Texture
95 glGenTextures(1, &texture[0]);
97 // texture 2 (linear scaling)
98 glBindTexture(GL_TEXTURE_2D, texture[0]); // 2d texture (x and y size)
99 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // scale linearly when image bigger than texture
100 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // scale linearly when image smalled than texture
101 glTexImage2D(GL_TEXTURE_2D, 0, 3, image->getWidth(), image->getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, image->getData());
104 /* A general OpenGL initialization function. Sets all of the initial parameters. */
105 GLvoid InitGL(GLsizei sWidth, GLsizei sHeight) // We call this right after our OpenGL window is created.
107 LoadGLTextures(); // Load the textures
109 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
110 glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
111 glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
112 glEnable(GL_DEPTH_TEST); // Enables Depth Testing
113 glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
115 glMatrixMode(GL_PROJECTION);
116 glLoadIdentity(); // Reset The Projection Matrix
118 gluPerspective(45.0, GLfloat(sWidth)/GLfloat(sHeight),0.1f,100.0f); // Calculate The Aspect Ratio Of The Window
119 quadric=gluNewQuadric(); // Create A Pointer To The Quadric Object ( NEW )
121 // Can also use GLU_NONE, GLU_FLAT
122 gluQuadricNormals(quadric, GLU_SMOOTH); // Create Smooth Normals
123 gluQuadricTexture(quadric, GL_TRUE); // Create Texture Coords ( NEW )
125 m_bFullscreen = false;
126 m_mouseX = 0;
127 m_mouseY = 0;
128 m_tiltAngle = -70.0f;
129 m_twistAngle = -45.0f;
130 m_distance = 270.0f;
131 m_bLeftMouseButtonDown = false;
132 m_bRightMouseButtonDown = false;
133 m_lastTick = 0;
134 m_lastRenderTick = 0;
135 m_bPaused = false;
138 //----------------------------------------------------------------------------//
139 // Handle an idle event
140 // does all the animation calculations //
141 //----------------------------------------------------------------------------//
142 void idleFunc()
144 // update the screen
145 glutPostRedisplay();
148 //----------------------------------------------------------------------------//
149 // Render the cursor //
150 //----------------------------------------------------------------------------//
152 void renderCursor()
154 //printf("Cursor redraw\n");
155 // switch to orthogonal projection for the cursor
156 glMatrixMode(GL_PROJECTION);
157 glPushMatrix();
158 glLoadIdentity();
159 glOrtho(0, GLdouble(Width), 0, GLdouble(Height), -1.0f, 1.0f);
161 glMatrixMode(GL_MODELVIEW);
162 glLoadIdentity();
164 // render the cursor
165 glEnable(GL_BLEND);
166 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
168 glBegin(GL_TRIANGLES);
169 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
170 glVertex2i(m_mouseX, m_mouseY);
171 glColor4f(1.0f, 1.0f, 1.0f, 0.2f);
172 glVertex2i(m_mouseX + 16, m_mouseY - 32);
173 glColor4f(1.0f, 1.0f, 1.0f, 0.2f);
174 glVertex2i(m_mouseX + 32, m_mouseY - 16);
175 glEnd();
177 glDisable(GL_BLEND);
179 glMatrixMode(GL_PROJECTION);
180 glPopMatrix();
182 glMatrixMode(GL_MODELVIEW);
185 /* ascii code for various keys */
186 #define ESCAPE 27
187 #define PAGE_UP 73
188 #define PAGE_DOWN 81
189 #define UP_ARROW 72
190 #define DOWN_ARROW 80
191 #define LEFT_ARROW 75
192 #define RIGHT_ARROW 77
195 /* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
196 void ReSizeGLScene(int mWidth, int mHeight)
198 Height = mHeight;
199 Width = mWidth;
201 if (Height==0) // Prevent A Divide By Zero If The Window Is Too Small
202 Height=1;
204 glViewport(0, 0, Width, Height); // Reset The Current Viewport And Perspective Transformation
206 glMatrixMode(GL_PROJECTION);
207 glLoadIdentity();
208 gluPerspective(45.0, GLfloat(Width) / GLfloat(Height), 1, 1000.0f);
209 glMatrixMode(GL_MODELVIEW);
211 mgr->resize(mWidth,mHeight);
214 void onMouseMove(int x, int y)
216 // update twist/tilt angles
217 if(m_bLeftMouseButtonDown)
219 // calculate new angles
220 m_twistAngle += static_cast<float>(x - m_mouseX);
221 m_tiltAngle -= static_cast<float>(y - m_mouseY);
224 // update distance
225 if(m_bRightMouseButtonDown)
227 // calculate new distance
228 m_distance -= static_cast<float>(y - m_mouseY) / 3.0f;
229 if(m_distance < 0.0f)
230 m_distance = 0.0f;
233 // update internal mouse position
234 m_mouseX = x;
235 m_mouseY = y;
238 void motionFunc(int x, int y)
240 // redirect the message to the viewer instance
241 onMouseMove(x, Height - y - 1);
243 //mgr->mouseMove(x, y);
246 //----------------------------------------------------------------------------//
247 // Handle a mouse button down event //
248 //----------------------------------------------------------------------------//
250 void onMouseButtonDown(int button, int x, int y)
252 // update mouse button states
253 if(button == GLUT_LEFT_BUTTON)
254 m_bLeftMouseButtonDown = true;
256 if(button == GLUT_RIGHT_BUTTON)
257 m_bRightMouseButtonDown = true;
259 // update internal mouse position
260 m_mouseX = x;
261 m_mouseY = y;
264 //----------------------------------------------------------------------------//
265 // Handle a mouse button up event //
266 //----------------------------------------------------------------------------//
268 void onMouseButtonUp(int button, int x, int y)
270 // update mouse button states
271 if(button == GLUT_LEFT_BUTTON)
272 m_bLeftMouseButtonDown = false;
274 if(button == GLUT_RIGHT_BUTTON)
275 m_bRightMouseButtonDown = false;
277 // update internal mouse position
278 m_mouseX = x;
279 m_mouseY = y;
282 void mouseFunc(int button, int state, int x, int y)
284 #if 0
285 if (state)
286 mgr->mouseButtonRelease(button, x, y);
287 else
288 mgr->mouseButtonPress(button, x, y);
289 #endif
291 // redirect the message to the viewer instance
292 if(state == GLUT_DOWN)
294 onMouseButtonDown(button, x, Height - y - 1);
296 else if(state == GLUT_UP)
298 onMouseButtonUp(button, x, Height - y - 1);
302 /* The function called whenever a key is pressed. */
303 void keyPressed(unsigned char key, int x, int y)
305 /* avoid thrashing this procedure */
306 OSG::osgSleep(100);
308 switch (key)
310 case ESCAPE:
311 // clean up gobal variables
312 mgr = NULL;
313 pwin = NULL;
314 trans = NULL;
315 vp = NULL;
316 cam = NULL;
317 newcam = NULL;
318 scene = NULL;
319 world = NULL;
321 /* shut down our window */
322 //glutDestroyWindow(window);
324 /* exit the program...normal termination. */
326 exit(1);
327 break; // redundant.
329 default:
330 printf ("Key %d pressed. No action there yet.\n", key);
331 break;
335 /* The main drawing function. */
336 void DrawGLScene(void)
338 glMatrixMode(GL_MODELVIEW);
340 // clear all the buffers - gives OpenGL full control
341 // OpenSG doesn't clear the background because of the PassiveBackground object
342 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
343 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
345 // set the model transformation
346 glMatrixMode(GL_MODELVIEW);
347 glLoadIdentity();
349 // set camera position from mouse movement
350 glTranslatef(0.0f, 0.0f, -m_distance);
351 glRotatef(m_tiltAngle, 1.0f, 0.0f, 0.0f);
352 glRotatef(m_twistAngle, 0.0f, 0.0f, 1.0f);
353 //glTranslatef(0.0f, 0.0f, -90.0f);
355 glPushMatrix(); // OpenSG will overwrite
357 OSG::Real32 proj_matrix[16], model_matrix[16];
358 glGetFloatv(GL_PROJECTION_MATRIX, proj_matrix);
359 glGetFloatv(GL_MODELVIEW_MATRIX, model_matrix);
361 // retrieve OpenGL's matrices
362 OSG::Matrix proj, model;
363 proj.setValue(proj_matrix);
364 model.setValue(model_matrix);
366 newcam->setProjectionMatrix(proj);
368 // transform the world just like the OpenGL content
369 // necessary since OpenSG's modelview transforms start from the unity matrix.
370 newcam->setModelviewMatrix(model);
372 // setup an initial transformation
373 OSG::Matrix m1;
374 OSG::Quaternion q1;
376 // mind that the VRML base coordinate system has different meanings for X, Y, Z, hence the rotation for 90 degrees.
377 // this, together with the MatrixCamera code above hooks OpenSG to OpenGL !
378 m1.setIdentity();
379 q1.setValueAsAxisDeg(1, 0, 0., 90); // rotation
380 m1.setRotate(q1);
381 trans->setMatrix(m1);
383 OSG::commitChanges();
385 // redraw the OpenSG window content - the calls are a bit after one's own taste
386 pwin->render(mgr->getRenderAction());
387 //pwin->frameInit();
388 //pwin->frameExit();
389 //mgr->redraw();
391 glMatrixMode(GL_MODELVIEW);
392 glPopMatrix();
393 //################ START FOR OPENGL STUFF
395 // light attributes
396 const GLfloat light_ambient[] = { 0.3f, 0.3f, 0.3f, 1.0f };
397 const GLfloat light_diffuse[] = { 0.52f, 0.5f, 0.5f, 1.0f };
398 const GLfloat light_specular[] = { 0.1f, 0.1f, 0.1f, 1.0f };
400 // setup the light attributes
401 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
402 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
403 glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
405 glEnable(GL_LIGHT0);
406 glEnable(GL_LIGHTING);
408 // set the light position
409 GLfloat lightPosition[] = { 0.0f, -10.0f, 10.0f, 0.0f };
410 glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
412 glEnable(GL_NORMALIZE);
414 glDisable(GL_NORMALIZE);
415 //glDisable(GL_BLEND);
417 glEnable(GL_LIGHTING);
418 glEnable(GL_TEXTURE_2D);
419 glBindTexture(GL_TEXTURE_2D, texture[0]); // choose the texture to use.
421 GLfloat TableDiffuse[] = { 0.3f, 0.0f, 1.0f, 0.5f };
422 GLfloat TableSpecular[] = { 0.6f, 0.0f, 0.8f, 0.5f };
423 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, TableDiffuse);
424 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, TableSpecular);
425 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.4f);
426 glEnable(GL_BLEND);
428 gluPartialDisk(quadric,0,12.0f,32,16, 0, 360); // A Disk Like The One Before
429 #if 1
430 glDisable(GL_TEXTURE_2D);
431 glDisable(GL_LIGHTING);
433 // X axis on table
434 glColor3f(1,0,0);
435 glBegin(GL_LINES);
436 glVertex3f(0,0,0.1f);
437 glVertex3f(120,0,0.1f);
438 glEnd();
440 // Y axis on table
441 glColor3f(0,1,0);
442 glBegin(GL_LINES);
443 glVertex3f(0,0,0.1f);
444 glVertex3f(0,120,0.1f);
445 glEnd();
447 glEnable(GL_LIGHTING);
448 #endif
450 glDisable(GL_TEXTURE_2D);
451 glDisable(GL_BLEND);
453 glDisable(GL_LIGHTING);
455 // render the cursor
456 renderCursor();
458 // swap the front- and back-buffer
459 glutSwapBuffers();
462 int main(int argc, char **argv)
464 // we need to load some relative images and geometry files.
465 // to make this work reliable (e.g. starting the tutorial via link)
466 // we use the argv[0] parameter.
467 #ifdef WIN32
468 std::string sep("\\");
469 #else
470 std::string sep("/");
471 #endif
472 std::string path = argv[0];
473 // remove app name
474 std::string::size_type i = path.rfind(sep);
475 if(i != std::string::npos)
476 path = path.substr(0, i);
477 // set the current dir to the application dir.
478 OSG::Directory::setCurrent(path.c_str());
480 // OSG init
481 OSG::osgInit(argc, argv);
483 /* Initialize GLUT state - glut will take any command line arguments that pertain to it or
484 X Windows - look at its documentation at http://reality.sgi.com/mjk/spec3/spec3.html */
485 glutInit(&argc, argv);
487 /* Select type of Display mode:
488 Double buffer
489 RGBA color
490 Alpha components supported (use GLUT_ALPHA)
491 Depth buffer */
492 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
494 /* get a 640 x 480 window */
495 //glutInitWindowSize(640, 480);
496 glutInitWindowSize(Width, Height);
498 /* the window starts at the upper left corner of the screen */
499 glutInitWindowPosition(300, 0);
501 /* Open a window */
502 window = glutCreateWindow("Oz, Mouse Control");
504 if (m_bFullscreen)
505 glutFullScreen();
506 glutSetCursor(GLUT_CURSOR_NONE);
508 glutDisplayFunc(&DrawGLScene);
510 // register all GLUT callback functions
511 glutIdleFunc(idleFunc);
513 /* Register the function called when our window is resized. */
514 glutReshapeFunc(ReSizeGLScene);
516 /* Register the function called when the keyboard is pressed. */
517 glutKeyboardFunc(keyPressed);
519 /* Register the function called when special keys (arrows, page down, etc) are pressed. */
520 //glutSpecialFunc(&specialKeyPressed);
522 glutMouseFunc(mouseFunc);
523 glutMotionFunc(motionFunc);
524 glutPassiveMotionFunc(motionFunc);
526 /* Initialize our window. */
527 InitGL(640, 480);
529 pwin = OSG::PassiveWindow::create();
530 pwin->init();
533 All scene file loading is handled via the SceneFileHandler.
535 world = OSG::SceneFileHandler::the()->read("Data/tie.wrl");
536 // create the main scene transformation node
538 // 1. create the Node
539 scene =OSG:: Node::create();
541 // 2. create the core
542 trans = OSG::Transform::create();
544 // 3. associate the core with the node
545 scene->setCore(trans);
546 scene->addChild(world); // add the world as a child
548 // create the SimpleSceneManager helper - it will be only partially used
549 mgr = OSG::SimpleSceneManager::create();
551 // tell the manager what to manage
552 mgr->setWindow(pwin );
553 mgr->setRoot (scene);
555 if (pwin->getMFPort()->size() != 0)
557 OSG::PassiveBackgroundRefPtr bg = OSG::PassiveBackground::create();
559 vp = pwin->getPort(0);
560 cam = dynamic_cast<OSG::PerspectiveCamera *>(vp->getCamera());
561 newcam = OSG::MatrixCamera::create(); // the MatrixCamera will only be a slave to the OpenGL matrices
562 vp->setCamera(newcam); // replace the cam
563 vp->setBackground(bg); // keep OpenSG from deleting the background, we will do that ourselves
564 if(cam == NULL)
565 exit(1);
567 else
569 printf("Could not acquire pointer to camera !!\n");
570 exit(1);
573 OSG::commitChanges();
575 /* Start Event Processing Engine */
576 glutMainLoop();
578 return 1;