changed: auto add updateData callback to stages so that stagedata can be updated...
[opensg.git] / Source / WindowSystem / EAGL / testWindowCocoa.mm
blob4e7cd4808c5628013c6686c0ea64a310389389b9
1 #include "OSGConfig.h"
3 #include <iostream>
5 #import <Cocoa/Cocoa.h>
7 #include "OSGFieldContainerFactory.h"
8 #include "OSGVector.h"
9 #include "OSGQuaternion.h"
10 #include "OSGMatrix.h"
11 #include "OSGMatrixUtility.h"
12 #include "OSGBoxVolume.h"
13 #include "OSGNode.h"
14 #include "OSGGroup.h"
15 #include "OSGTransform.h"
16 #include "OSGSimpleGeometry.h"
17 #include "OSGAction.h"
18 #include "OSGRenderAction.h"
19 #include "OSGSceneFileHandler.h"
20 #include "OSGDirectionalLight.h"
22 #include "OSGViewport.h"
23 #include "OSGCamera.h"
24 #include "OSGWindow.h"
25 #include "OSGCocoaWindow.h"
26 #include "OSGCamera.h"
27 #include "OSGPerspectiveCamera.h"
28 #include "OSGSolidBackground.h"
30 #include "OSGTrackball.h"
32 // This prevents warnings that "NSApplication might not
33 // respond to setAppleMenu" on OS X 10.4
34 @interface NSApplication(OpenSG)
35 - (void)setAppleMenu:(NSMenu *)menu;
36 @end
38 using namespace OSG;
40 CocoaWindowUnrecPtr    win;
42 RenderAction    *ract;
43 NodeRecPtr           root;
44 NodeRecPtr           file;
45 ViewportRecPtr   vp;
46 TransformRecPtr  cam_trans;
47 Trackball     tball;
48 PerspectiveCameraRecPtr cam;
50 bool          stopIt = false;
51 int           lastx=0, lasty=0;
53 void redraw ( void )
55     fprintf(stderr, "redraw\n");
56     Matrix m1, m2, m3;
57     Quaternion q1;
59     tball.getRotation().getValue(m3);
60     q1.setValue(m3);
61     m1.setRotate(q1);
62     m2.setTranslate( tball.getPosition() );
63     m1.mult( m2 );
64     cam_trans->editSFMatrix()->setValue( m1 );
66     Thread::getCurrentChangeList()->commitChanges();
68     win->render(ract);
71 @interface MyOpenGLView: NSOpenGLView
74 - (BOOL) acceptsFirstResponder;
76 - (void) handleMouseEvent: (NSEvent*) event;
78 - (void) mouseDown: (NSEvent*) event;
79 - (void) mouseDragged: (NSEvent*) event;
80 - (void) mouseUp: (NSEvent*) event;
81 - (void) rightMouseDown: (NSEvent*) event;
82 - (void) rightMouseDragged: (NSEvent*) event;
83 - (void) rightMouseUp: (NSEvent*) event;
84 - (void) otherMouseDown: (NSEvent*) event;
85 - (void) otherMouseDragged: (NSEvent*) event;
86 - (void) otherMouseUp: (NSEvent*) event;
88 - (void) keyDown: (NSEvent*) event;
90 - (void) reshape;
91 - (void) drawRect: (NSRect) bounds;
92 @end
94 @implementation MyOpenGLView
96 - (BOOL) acceptsFirstResponder
98     return YES;
101 - (void) handleMouseEvent: (NSEvent*) event
103     Real32 w,h,a,b,c,d;
105     int buttonNumber = [event buttonNumber];
106     unsigned int modifierFlags = [event modifierFlags];
108     // Traditionally, Apple mice just have one button. It is common practice to simulate
109     // the middle and the right button by pressing the option or the control key.
110     if (buttonNumber == 0)
111     {
112         if (modifierFlags & NSAlternateKeyMask)
113             buttonNumber = 2;
114         if (modifierFlags & NSControlKeyMask)
115             buttonNumber = 1;
116     }
118     NSPoint location = [event locationInWindow];
120     switch ([event type])
121     {
122     case NSLeftMouseDown:
123     case NSRightMouseDown:
124     case NSOtherMouseDown:
125         lastx = static_cast<int>(location.x);
126         lasty = static_cast<int>(location.y);
127         switch (buttonNumber)
128         {
129         case 0: // left button
130             break;
131         case 1: // right button
132             tball.setAutoPositionNeg(true);
133             break;
134         case 2: // middle button
135             tball.setAutoPosition(true);
136             break;
137         }
138         break;
140     case NSLeftMouseUp:
141     case NSRightMouseUp:
142     case NSOtherMouseUp:
143         switch (buttonNumber)
144         {
145         case 0: // left button
146             break;
147         case 1: // right button
148             tball.setAutoPositionNeg(false);
149             break;
150         case 2: // middle button
151             tball.setAutoPosition(false);
152             break;
153         }
154         break;
156     case NSLeftMouseDragged:
157     case NSRightMouseDragged:
158     case NSOtherMouseDragged:
159         w = win->getWidth();
160         h = win->getHeight();
161         a = -2. * ( lastx / w - .5 );
162         b = -2. * ( lasty / h - .5);
163         c = -2. * ( location.x / w - .5 );
164         d = -2. * ( location.y / h - .5 );
165         switch (buttonNumber)
166         {
167         case 0: // left button
168             tball.updateRotation( a, b, c, d );
169             break;
170         case 1: // right button
171             tball.updatePositionNeg( a, b, c, d );
172             break;
173         case 2: // middle button
174             tball.updatePosition( a, b, c, d );
175             break;
176         }
177         lastx = static_cast<int>(location.x);
178         lasty = static_cast<int>(location.y);
179         redraw();
180         break;
182     default:
183         break;
184     }
187 - (void) mouseDown: (NSEvent*) event
189     [self handleMouseEvent: event];
192 - (void) mouseDragged: (NSEvent*) event
194     [self handleMouseEvent: event];
197 - (void) mouseUp: (NSEvent*) event
199     [self handleMouseEvent: event];
202 - (void) rightMouseDown: (NSEvent*) event
204     [self handleMouseEvent: event];
207 - (void) rightMouseDragged: (NSEvent*) event
209     [self handleMouseEvent: event];
212 - (void) rightMouseUp: (NSEvent*) event
214     [self handleMouseEvent: event];
217 - (void) otherMouseDown: (NSEvent*) event
219     [self handleMouseEvent: event];
222 - (void) otherMouseDragged: (NSEvent*) event
224     [self handleMouseEvent: event];
227 - (void) otherMouseUp: (NSEvent*) event
229     [self handleMouseEvent: event];
232 - (void) keyDown: (NSEvent*) event
234     if ([[event characters] length] != 1)
235         return;
236     switch ([[event characters] characterAtIndex: 0])
237     {
238     case 27:
239 //        [NSApp terminate:nil];
240         [NSApp stop:nil];
241         break;
242     case 'a':
243         glDisable( GL_LIGHTING );
244         redraw();
245         break;
246     case 's':
247         glEnable( GL_LIGHTING );
248         redraw();
249         break;
250     case 'z':
251         glPolygonMode( GL_FRONT_AND_BACK, GL_POINT);
252         redraw();
253         break;
254     case 'x':
255         glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
256         redraw();
257         break;
258     case 'c':
259         glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
260         redraw();
261         break;
262     default:
263         break;
264     }
267 - (void) reshape
269     [self update];
270     NSRect frame = [self bounds];
271     win->resize(static_cast<int>(frame.size.width), static_cast<int>(frame.size.height));
274 - (void) drawRect: (NSRect) bounds
276     redraw();
279 @end
281 @interface MyDelegate : NSObject
284     NSWindow *window;
285     MyOpenGLView *glView;
288 - (void) applicationWillFinishLaunching: (NSNotification*) notification;
290 - (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*) application;
292 - (void) performer: (id) userInfo;
294 @end
296 @implementation MyDelegate
298 - (void) performer: (id) userInfo
300     fprintf(stderr, "perform\n");
304 - (void) dealloc
306     [window release];
307     [super dealloc];
310 - (void) applicationWillFinishLaunching: (NSNotification*) notification
312     /* Set up the menubar */
313     [NSApp setMainMenu:[[NSMenu alloc] init]];
315     NSString *appName = @"testWindowCocoa";
316     NSMenu *appleMenu = [[NSMenu alloc] initWithTitle:@""];
318     /* Add menu items */
320     NSMenu *servicesMenu = [[NSMenu alloc] initWithTitle:@""];
321     NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:@"Services" action:nil keyEquivalent:@""];
322     [menuItem setSubmenu:servicesMenu];
323     [appleMenu addItem:menuItem];
324     [NSApp setServicesMenu: servicesMenu];
326     [appleMenu addItem:[NSMenuItem separatorItem]];
328     NSString *title = [@"Hide " stringByAppendingString:appName];
329     [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
331     menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
332     [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
334     [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
336     [appleMenu addItem:[NSMenuItem separatorItem]];
338     title = [@"Quit " stringByAppendingString:appName];
339     [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
341     /* Put menu into the menubar */
342     menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
343     [menuItem setSubmenu:appleMenu];
344     [[NSApp mainMenu] addItem:menuItem];
346     /* Tell the application object that this is now the application menu */
347     [NSApp setAppleMenu:appleMenu];
349     /* Finally give up our references to the objects */
350     [appleMenu release];
351     [menuItem release];
353     // Create the window
354     window = [NSWindow alloc];
355     NSRect rect = { { 0, 0 }, { 300, 300 } };
356     [window initWithContentRect: rect styleMask: (NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask) backing: NSBackingStoreBuffered defer: YES];
357     [window setTitle: @"testWindowCocoa"];
358     [window setReleasedWhenClosed: NO];
360     glView = [[MyOpenGLView alloc] autorelease];
361     [glView initWithFrame: rect];
362     [glView setAutoresizingMask: NSViewMaxXMargin | NSViewWidthSizable | NSViewMaxYMargin | NSViewHeightSizable];
363     [[window contentView] addSubview: glView];
365     NSOpenGLPixelFormatAttribute attrs[] =
366     {
367         NSOpenGLPFAWindow,
368         NSOpenGLPFADoubleBuffer,
369         NSOpenGLPFADepthSize, NSOpenGLPixelFormatAttribute(16),
370         NSOpenGLPixelFormatAttribute(0)
371     };
372     NSOpenGLPixelFormat *pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: attrs];
373     [glView setPixelFormat: pixFmt];
375     // Create OpenSG window
376     win = CocoaWindow::create();
377     win->addPort( vp );
378     win->setContext ( [glView openGLContext] );
379     win->init();
380     win->resize( 300, 300 );
382     win->activate();
384     // do some OpenGL init. Will move into State Chunks later.
386     glEnable( GL_DEPTH_TEST );
387     glEnable( GL_LIGHTING );
388     glEnable( GL_LIGHT0 );
390         // Show the window
391     [window makeKeyAndOrderFront: nil];
392     [window makeFirstResponder:glView];
395 - (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*) application
397     return YES;
400 @end
402 void doPerform(id userInfo)
404     fprintf(stderr, "perform\n");
407 // A magic method that allows applications to react to events even
408 // when they are not organized in a bundle
409 void osx_AllowForeground()
411     ProcessSerialNumber psn = { 0, kCurrentProcess };
412     TransformProcessType(&psn, kProcessTransformToForegroundApplication);
413     SetFrontProcess(&psn);
416 int doMain(int argc, char *argv[])
418     osx_AllowForeground();
420     // OSG init
421     osgInit(argc, argv);
423     // create the graph
425     // beacon for camera and light
426     NodeUnrecPtr b1n = Node::create();
427     GroupUnrecPtr b1 = Group::create();
428     b1n->setCore( b1 );
430     // transformation
431     NodeUnrecPtr t1n = Node::create();
432     TransformUnrecPtr t1 = Transform::create();
433     t1n->setCore( t1 );
434     t1n->addChild( b1n );
436     cam_trans = t1;
438     // light
440     NodeUnrecPtr dlight = Node::create();
441     DirectionalLightUnrecPtr dl = DirectionalLight::create();
443     dlight->setCore( dl );
445     dl->setAmbient( .3, .3, .3, 1 );
446     dl->setDiffuse( 1, 1, 1, 1 );
447     dl->setDirection(0,0,1);
448     dl->setBeacon( b1n);
450     // root
451     root = Node::create();
452     GroupUnrecPtr gr1 = Group::create();
454     root->setCore( gr1 );
455     root->addChild( t1n );
456     root->addChild( dlight );
458     // Load the file
460     NodeUnrecPtr file = NULL;
462     if ( argc > 1 )
463         file = SceneFileHandler::the()->read(argv[1]);
465     if ( file == NULL )
466     {
467         std::cerr << "Couldn't load file, ignoring" << std::endl;
468         file = makeTorus( .5, 2, 16, 16 );
469     }
471     Thread::getCurrentChangeList()->commitChanges();
472     file->updateVolume();
474     Vec3f min,max;
475     file->getVolume().getBounds( min, max );
477     std::cout << "Volume: from " << min << " to " << max << std::endl;
479     dlight->addChild( file );
481     std::cerr << "Tree: " << std::endl;
482     //root->dump();
484     // Camera
485     cam = PerspectiveCamera::create();
487     cam->setBeacon( b1n );
488     cam->setFov( osgDegree2Rad( 90 ) );
489     cam->setNear( 0.1 );
490     cam->setFar( 100000 );
492     // Background
493     SolidBackgroundUnrecPtr bkgnd = SolidBackground::create();
495     bkgnd->setColor(Color3f(0,0,1));
497     // Viewport
499     vp = Viewport::create();
500     vp->setCamera( cam );
501     vp->setBackground( bkgnd );
502     vp->setRoot( root );
503     vp->setSize( 0,0, 1,1 );
505     // Action
507     ract = RenderAction::create();
509     // tball
511     Vec3f pos;
512     pos.setValues(min[0] + ((max[0] - min[0]) * 0.5), 
513                   min[1] + ((max[1] - min[1]) * 0.5), 
514                   max[2] + ( max[2] - min[2] ) * 1.5 );
515     
516     float scale = (max[2] - min[2] + max[1] - min[1] + max[0] - min[0]) / 6;
518     Pnt3f tCenter(min[0] + (max[0] - min[0]) / 2,
519                   min[1] + (max[1] - min[1]) / 2,
520                   min[2] + (max[2] - min[2]) / 2);
522     tball.setMode( Trackball::OSGObject );
523     tball.setStartPosition( pos, true );
524     tball.setSum( true );
525     tball.setTranslationMode( Trackball::OSGFree );
526     tball.setTranslationScale(scale);
527     tball.setRotationCenter(tCenter);
529     // Create application
530     [NSApplication sharedApplication];
532     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
534     MyDelegate *delegate =  [[MyDelegate new] autorelease];
536     [NSApp setDelegate: delegate];
538     [[NSRunLoop currentRunLoop] performSelector: @selector(performer:) target:delegate argument:nil order:0 modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
540 //    NSTimer *timer = [NSTimer timerWithTimeInterval: 0.0f
541 //                     target: delegate
542 //                     selector: @selector( performer: )
543 //                     userInfo: nil
544 //                     repeats: YES];
546 //    [[NSRunLoop currentRunLoop] addTimer: timer
547 //                                forMode: NSDefaultRunLoopMode];
549     // Run the message loop
550     [NSApp run];
552     fprintf(stderr, "exit\n");
554     delete ract;
556     win       = NULL;
557     root      = NULL;
558     file      = NULL;
559     vp        = NULL;
560     cam_trans = NULL;
561     cam       = NULL;
563     [pool release];
565     return EXIT_SUCCESS;
568 int main(int argc, char *argv[])
570     doMain(argc, argv);
572     osgExit();
574     return EXIT_SUCCESS;