changed: auto add updateData callback to stages so that stagedata can be updated...
[opensg.git] / Source / WindowSystem / CoreGL / testWindowCoreGL.cpp
blob74221ed0980775b69eb4b1d3d755f1b51fb40b97
1 #include "OSGConfig.h"
3 #include <iostream>
5 #include "OSGFieldContainerFactory.h"
6 #include "OSGVector.h"
7 #include "OSGQuaternion.h"
8 #include "OSGMatrix.h"
9 #include "OSGMatrixUtility.h"
10 #include "OSGBoxVolume.h"
11 #include "OSGNode.h"
12 #include "OSGGroup.h"
13 #include "OSGTransform.h"
14 #include "OSGSimpleGeometry.h"
15 #include "OSGAction.h"
16 #include "OSGRenderAction.h"
17 #include "OSGSceneFileHandler.h"
18 #include "OSGDirectionalLight.h"
20 #include "OSGViewport.h"
21 #include "OSGCamera.h"
22 #include "OSGWindow.h"
23 #include "OSGCoreGLWindow.h"
24 #include "OSGCamera.h"
25 #include "OSGPerspectiveCamera.h"
26 #include "OSGSolidBackground.h"
28 #include "OSGTrackball.h"
30 #include <Carbon/Carbon.h>
31 #include <ApplicationServices/ApplicationServices.h>
33 #ifdef check
34 # undef check
35 #endif
37 OSG::CoreGLWindowUnrecPtr win;
39 OSG::RenderActionRefPtr ract;
40 OSG::NodeRecPtr root;
41 OSG::NodeRecPtr file;
42 OSG::ViewportRecPtr vp;
43 OSG::TransformRecPtr cam_trans;
44 OSG::Trackball tball;
45 OSG::PerspectiveCameraRecPtr cam;
47 bool stopIt = false;
48 int lastx=0, lasty=0;
50 #if !defined(__LP64__)
52 void redraw ( void )
54 OSG::Matrix m1, m2, m3;
55 OSG::Quaternion q1;
57 tball.getRotation().getValue(m3);
58 q1.setValue(m3);
59 m1.setRotate(q1);
60 m2.setTranslate( tball.getPosition() );
61 m1.mult( m2 );
62 cam_trans->editSFMatrix()->setValue( m1 );
64 OSG::Thread::getCurrentChangeList()->commitChanges();
66 win->render(ract);
69 static OSStatus handleMouseEvent(EventHandlerCallRef nextHandler, EventRef event, void *userData)
71 OSStatus err;
72 OSG::Real32 w,h,a,b,c,d;
74 // Get the pressed mouse button
75 EventMouseButton mouseButton;
76 err = GetEventParameter(event, kEventParamMouseButton, typeMouseButton, 0, sizeof(mouseButton), 0, &mouseButton);
77 if (err != noErr)
78 return err;
80 // Get the modifier keys
81 ::UInt32 modifierKeys;
82 err = GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0, sizeof(modifierKeys), 0, &modifierKeys);
83 if (err != noErr)
84 return err;
86 // Traditionally, Apple mice just have one button. It is common practice to simulate
87 // the middle and the right button by pressing the option or the control key.
88 if (mouseButton == kEventMouseButtonPrimary)
90 if (modifierKeys & optionKey)
91 mouseButton = kEventMouseButtonTertiary;
92 if (modifierKeys & controlKey)
93 mouseButton = kEventMouseButtonSecondary;
96 // Get the location of the mouse pointer
97 ::Point location;
98 err = GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, 0, sizeof(location), 0, &location);
99 if (err != noErr)
100 return err;
102 // Handle the different kinds of events
103 ::UInt32 eventKind = GetEventKind(event);
104 switch (eventKind)
106 // mouse button pressed
107 case kEventMouseDown:
108 lastx = location.h;
109 lasty = location.v;
110 switch (mouseButton)
112 case kEventMouseButtonPrimary: // left button
113 break;
114 case kEventMouseButtonSecondary: // right button
115 tball.setAutoPositionNeg(true);
116 break;
117 case kEventMouseButtonTertiary: // middle button
118 tball.setAutoPosition(true);
119 break;
121 break;
123 // mouse button released
124 case kEventMouseUp:
125 switch (mouseButton)
127 case kEventMouseButtonPrimary: // left button
128 break;
129 case kEventMouseButtonSecondary: // right button
130 tball.setAutoPositionNeg(false);
131 break;
132 case kEventMouseButtonTertiary: // middle button
133 tball.setAutoPosition(false);
134 break;
136 break;
138 // mouse moved while a button is pressed
139 case kEventMouseDragged:
140 w = win->getWidth();
141 h = win->getHeight();
142 a = -2. * ( lastx / w - .5 );
143 b = -2. * ( .5 - lasty / h );
144 c = -2. * ( location.h / w - .5 );
145 d = -2. * ( .5 - location.v / h );
146 switch (mouseButton)
148 case kEventMouseButtonPrimary: // left button
149 tball.updateRotation( a, b, c, d );
150 break;
151 case kEventMouseButtonSecondary: // right button
152 tball.updatePositionNeg( a, b, c, d );
153 break;
154 case kEventMouseButtonTertiary: // middle button
155 tball.updatePosition( a, b, c, d );
156 break;
158 lastx = location.h;
159 lasty = location.v;
161 // Redraw the whole window
162 redraw();
164 break;
167 // We have to return eventNotHandledErr, otherwise the system is
168 // not able to operate the menu and the window border
169 return eventNotHandledErr;
172 static OSStatus handleKeyEvent(EventHandlerCallRef nextHandler, EventRef event, void *userData)
174 OSStatus err;
176 // Try to determine the size of the text input
177 ::UInt32 actualSize;
178 err = GetEventParameter(event, kEventParamTextInputSendText, typeUnicodeText, 0, 0, &actualSize, 0);
179 if (err != noErr)
180 return err;
182 // The input can actually consist of more than one character.
183 // We are only interested in single character input
184 if (actualSize == sizeof(UniChar))
186 // Get the character unicode
187 UniChar c;
188 err = GetEventParameter(event, kEventParamTextInputSendText, typeUnicodeText, 0, sizeof(UniChar), 0, &c);
189 if (err != noErr)
190 return err;
192 // Handle different keyboard commands
193 CGLSetCurrentContext(win->getContext());
194 switch (c)
196 case kEscapeCharCode:
197 QuitApplicationEventLoop();
198 break;
199 case 'a':
200 glDisable( GL_LIGHTING );
201 redraw();
202 break;
203 case 's':
204 glEnable( GL_LIGHTING );
205 redraw();
206 break;
207 case 'z':
208 glPolygonMode( GL_FRONT_AND_BACK, GL_POINT);
209 redraw();
210 break;
211 case 'x':
212 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
213 redraw();
214 break;
215 case 'c':
216 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
217 redraw();
218 break;
222 return noErr;
225 static pascal OSStatus eventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData)
227 ::UInt32 eventClass = GetEventClass(event);
228 switch (eventClass)
230 // Mouse events
231 case kEventClassMouse:
232 return handleMouseEvent(nextHandler, event, userData);
234 // Key press events
235 case kEventClassTextInput:
236 return handleKeyEvent(nextHandler, event, userData);
238 default:
239 return eventNotHandledErr;
243 int doMain (int argc, char **argv)
245 int dummy;
247 // OSG init
249 OSG::osgInit(argc, argv);
251 // create the graph
253 // beacon for camera and light
254 OSG::NodeUnrecPtr b1n = OSG::Node::create();
255 OSG::GroupUnrecPtr b1 = OSG::Group::create();
256 b1n->setCore( b1 );
258 // transformation
259 OSG::NodeUnrecPtr t1n = OSG::Node::create();
260 OSG::TransformUnrecPtr t1 = OSG::Transform::create();
261 t1n->setCore( t1 );
262 t1n->addChild( b1n );
264 cam_trans = t1;
266 // light
268 OSG::NodeUnrecPtr dlight = OSG::Node::create();
269 OSG::DirectionalLightUnrecPtr dl = OSG::DirectionalLight::create();
271 dlight->setCore( dl );
273 dl->setAmbient( .3, .3, .3, 1 );
274 dl->setDiffuse( 1, 1, 1, 1 );
275 dl->setDirection(0,0,1);
276 dl->setBeacon( b1n);
278 // root
279 root = OSG::Node::create();
280 OSG::GroupUnrecPtr gr1 = OSG::Group::create();
282 root->setCore( gr1 );
283 root->addChild( t1n );
284 root->addChild( dlight );
286 // Load the file
288 OSG::NodeUnrecPtr file = NULL;
290 if ( argc > 1 )
291 file = OSG::SceneFileHandler::the()->read(argv[1]);
293 if ( file == NULL )
295 std::cerr << "Couldn't load file, ignoring" << std::endl;
296 file = OSG::makeTorus( .5, 2, 16, 16 );
299 OSG::Thread::getCurrentChangeList()->commitChanges();
300 file->updateVolume();
302 OSG::Vec3f min,max;
303 file->getVolume().getBounds( min, max );
305 std::cout << "Volume: from " << min << " to " << max << std::endl;
307 dlight->addChild( file );
309 std::cerr << "Tree: " << std::endl;
310 //root->dump();
312 // Camera
313 cam = OSG::PerspectiveCamera::create();
315 cam->setBeacon( b1n );
316 cam->setFov( OSG::osgDegree2Rad( 90 ) );
317 cam->setNear( 0.1 );
318 cam->setFar( 100000 );
320 // Background
321 OSG::SolidBackgroundUnrecPtr bkgnd = OSG::SolidBackground::create();
323 bkgnd->setColor(OSG::Color3f(0,0,1));
325 // Viewport
327 vp = OSG::Viewport::create();
328 vp->setCamera( cam );
329 vp->setBackground( bkgnd );
330 vp->setRoot( root );
331 vp->setSize( 0,0, 1,1 );
333 // Action
335 ract = OSG::RenderAction::create();
337 // tball
339 OSG::Vec3f pos;
340 pos.setValues(min[0] + ((max[0] - min[0]) * 0.5),
341 min[1] + ((max[1] - min[1]) * 0.5),
342 max[2] + ( max[2] - min[2] ) * 1.5 );
344 float scale = (max[2] - min[2] + max[1] - min[1] + max[0] - min[0]) / 6;
346 OSG::Pnt3f tCenter(min[0] + (max[0] - min[0]) / 2,
347 min[1] + (max[1] - min[1]) / 2,
348 min[2] + (max[2] - min[2]) / 2);
350 tball.setMode( OSG::Trackball::OSGObject );
351 tball.setStartPosition( pos, true );
352 tball.setSum( true );
353 tball.setTranslationMode( OSG::Trackball::OSGFree );
354 tball.setTranslationScale(scale);
355 tball.setRotationCenter(tCenter);
357 // CoreGL init
359 // Install event handler
360 EventHandlerUPP eventHandlerUPP = NewEventHandlerUPP(eventHandler);
361 EventTypeSpec eventList[] =
363 { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
364 { kEventClassMouse, kEventMouseDown },
365 { kEventClassMouse, kEventMouseUp },
366 { kEventClassMouse, kEventMouseDragged }
368 InstallApplicationEventHandler(eventHandlerUPP, GetEventTypeCount(eventList), eventList, 0, 0);
370 CGDisplayCapture(kCGDirectMainDisplay);
371 CGLPixelFormatAttribute attribs[] =
373 kCGLPFADoubleBuffer,
374 kCGLPFAFullScreen,
375 kCGLPFADepthSize,
376 (CGLPixelFormatAttribute)16,
377 kCGLPFADisplayMask,
378 (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
379 (CGLPixelFormatAttribute)0
381 CGLPixelFormatObj pixelFormatObj;
382 GLint numPixelFormats;
383 CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats);
385 CGLContextObj contextObj;
386 CGLCreateContext(pixelFormatObj, 0, &contextObj);
388 CGLDestroyPixelFormat(pixelFormatObj);
390 CGLSetCurrentContext(contextObj);
391 CGLSetFullScreen(contextObj);
393 // Create OpenSG window
394 win = OSG::CoreGLWindow::create();
395 win->addPort( vp );
396 win->setContext ( contextObj );
397 win->init();
398 win->resize( CGDisplayPixelsWide(kCGDirectMainDisplay), CGDisplayPixelsHigh(kCGDirectMainDisplay) );
400 win->activate();
402 // do some OpenGL init. Will move into State Chunks later.
404 glEnable( GL_DEPTH_TEST );
405 glEnable( GL_LIGHTING );
406 glEnable( GL_LIGHT0 );
407 redraw();
409 // Main loop ( event dispatching )
410 RunApplicationEventLoop();
412 // Cleanup
413 CGLSetCurrentContext(0);
414 CGLClearDrawable(contextObj);
415 CGLDestroyContext(contextObj);
416 CGReleaseAllDisplays();
417 DisposeEventHandlerUPP(eventHandlerUPP);
419 ract = NULL;
420 win = NULL;
421 root = NULL;
422 file = NULL;
423 vp = NULL;
424 cam_trans = NULL;
425 cam = NULL;
427 return 0;
430 int main (int argc, char **argv)
432 doMain(argc, argv);
434 OSG::osgExit();
436 return 0;
439 #else
441 int main (int argc, char **argv)
443 fprintf(stderr, "CoreGL not available in 64bit\n");
446 #endif