11 #include "OSGFieldContainerFactory.h"
12 #include "OSGVector.h"
13 #include "OSGQuaternion.h"
14 #include "OSGMatrix.h"
15 #include "OSGMatrixUtility.h"
16 #include "OSGBoxVolume.h"
19 #include "OSGTransform.h"
20 #include "OSGSimpleGeometry.h"
21 #include "OSGAction.h"
22 #include "OSGRenderAction.h"
23 #include "OSGSceneFileHandler.h"
24 #include "OSGDirectionalLight.h"
26 #include "OSGViewport.h"
27 #include "OSGCamera.h"
28 #include "OSGWindow.h"
29 #include "OSGCarbonWindow.h"
30 #include "OSGCamera.h"
31 #include "OSGPerspectiveCamera.h"
32 #include "OSGSolidBackground.h"
34 #include "OSGTrackball.h"
36 OSG::CarbonWindowUnrecPtr win
;
38 OSG::RenderActionRefPtr ract
;
41 OSG::ViewportRecPtr vp
;
42 OSG::TransformRecPtr cam_trans
;
44 OSG::PerspectiveCameraRecPtr cam
;
49 #if !defined(__LP64__)
53 OSG::Matrix m1
, m2
, m3
;
56 tball
.getRotation().getValue(m3
);
59 m2
.setTranslate( tball
.getPosition() );
61 cam_trans
->editSFMatrix()->setValue( m1
);
63 OSG::Thread::getCurrentChangeList()->commitChanges();
68 static OSStatus
handleMouseEvent(EventHandlerCallRef nextHandler
, EventRef event
, void *userData
)
71 OSG::Real32 w
,h
,a
,b
,c
,d
;
75 err
= GetEventParameter(event
, kEventParamWindowRef
, typeWindowRef
, 0, sizeof(window
), 0, &window
);
79 // Get the window rectangle
81 GetWindowPortBounds(window
, &portRect
);
83 // Get the pressed mouse button
84 EventMouseButton mouseButton
;
85 err
= GetEventParameter(event
, kEventParamMouseButton
, typeMouseButton
, 0, sizeof(mouseButton
), 0, &mouseButton
);
89 // Get the modifier keys
90 ::UInt32 modifierKeys
;
91 err
= GetEventParameter(event
, kEventParamKeyModifiers
, typeUInt32
, 0, sizeof(modifierKeys
), 0, &modifierKeys
);
95 // Traditionally, Apple mice just have one button. It is common practice to simulate
96 // the middle and the right button by pressing the option or the control key.
97 if (mouseButton
== kEventMouseButtonPrimary
)
99 if (modifierKeys
& optionKey
)
100 mouseButton
= kEventMouseButtonTertiary
;
101 if (modifierKeys
& controlKey
)
102 mouseButton
= kEventMouseButtonSecondary
;
105 // Get the location of the mouse pointer
107 err
= GetEventParameter(event
, kEventParamMouseLocation
, typeQDPoint
, 0, sizeof(location
), 0, &location
);
111 // The location of the mouse pointer is in screen coordinates, so
112 // we have to transform it into the local coordinate system of the
113 // window content area.
114 SetPortWindowPort(window
);
115 GlobalToLocal(&location
);
117 // Handle the different kinds of events
118 ::UInt32 eventKind
= GetEventKind(event
);
121 // mouse button pressed
122 case kEventMouseDown
:
127 case kEventMouseButtonPrimary
: // left button
129 case kEventMouseButtonSecondary
: // right button
130 tball
.setAutoPositionNeg(true);
132 case kEventMouseButtonTertiary
: // middle button
133 tball
.setAutoPosition(true);
138 // mouse button released
142 case kEventMouseButtonPrimary
: // left button
144 case kEventMouseButtonSecondary
: // right button
145 tball
.setAutoPositionNeg(false);
147 case kEventMouseButtonTertiary
: // middle button
148 tball
.setAutoPosition(false);
153 // mouse moved while a button is pressed
154 case kEventMouseDragged
:
156 h
= win
->getHeight();
157 a
= -2. * ( lastx
/ w
- .5 );
158 b
= -2. * ( .5 - lasty
/ h
);
159 c
= -2. * ( location
.h
/ w
- .5 );
160 d
= -2. * ( .5 - location
.v
/ h
);
163 case kEventMouseButtonPrimary
: // left button
164 tball
.updateRotation( a
, b
, c
, d
);
166 case kEventMouseButtonSecondary
: // right button
167 tball
.updatePositionNeg( a
, b
, c
, d
);
169 case kEventMouseButtonTertiary
: // middle button
170 tball
.updatePosition( a
, b
, c
, d
);
176 // Redraw the whole window
177 InvalWindowRect(window
, &portRect
);
182 // We have to return eventNotHandledErr, otherwise the system is
183 // not able to operate the menu and the window border
184 return eventNotHandledErr
;
187 static OSStatus
handleKeyEvent(EventHandlerCallRef nextHandler
, EventRef event
, void *userData
)
191 // Try to determine the size of the text input
193 err
= GetEventParameter(event
, kEventParamTextInputSendText
, typeUnicodeText
, 0, 0, &actualSize
, 0);
197 // The input can actually consist of more than one character.
198 // We are only interested in single character input
199 if (actualSize
== sizeof(UniChar
))
201 // Get the character unicode
203 err
= GetEventParameter(event
, kEventParamTextInputSendText
, typeUnicodeText
, 0, sizeof(UniChar
), 0, &c
);
207 // Handle different keyboard commands
208 aglSetCurrentContext(win
->getContext());
211 case kEscapeCharCode
:
212 QuitApplicationEventLoop();
215 glDisable( GL_LIGHTING
);
219 glEnable( GL_LIGHTING
);
223 glPolygonMode( GL_FRONT_AND_BACK
, GL_POINT
);
227 glPolygonMode( GL_FRONT_AND_BACK
, GL_LINE
);
231 glPolygonMode( GL_FRONT_AND_BACK
, GL_FILL
);
240 static OSStatus
handleWindowEvent(EventHandlerCallRef nextHandler
, EventRef event
, void *userData
)
246 err
= GetEventParameter(event
, kEventParamDirectObject
, typeWindowRef
, 0, sizeof(window
), 0, &window
);
250 // Handle the different kinds of events
251 ::UInt32 eventKind
= GetEventKind(event
);
254 // Quit the application when the user closes the window
255 case kEventWindowClose
:
256 QuitApplicationEventLoop();
259 // Draw the contents of the window
260 case kEventWindowDrawContent
:
264 case kEventWindowBoundsChanged
:
266 // Update the GL context
267 aglUpdateContext(win
->getContext());
269 // Find out if we have a move or a resize situation
271 GetEventParameter(event
, kEventParamAttributes
, typeUInt32
, 0, sizeof(attributes
), 0, &attributes
);
273 if ((attributes
& kWindowBoundsChangeSizeChanged
) != 0)
275 // Get the new bounds of the window
277 GetEventParameter(event
, kEventParamCurrentBounds
, typeQDRectangle
, 0, sizeof(Rect
), 0, &bounds
);
279 // Resize the OpenSG Window
280 GLsizei width
= bounds
.right
- bounds
.left
;
281 GLsizei height
= bounds
.bottom
- bounds
.top
;
282 win
->resize(width
, height
);
284 // Redraw the whole window
286 GetWindowPortBounds(window
, &portRect
);
287 InvalWindowRect(window
, &portRect
);
294 return eventNotHandledErr
;
298 static pascal OSStatus
eventHandler(EventHandlerCallRef nextHandler
, EventRef event
, void *userData
)
300 ::UInt32 eventClass
= GetEventClass(event
);
304 case kEventClassMouse
:
305 return handleMouseEvent(nextHandler
, event
, userData
);
308 case kEventClassTextInput
:
309 return handleKeyEvent(nextHandler
, event
, userData
);
312 case kEventClassWindow
:
313 return handleWindowEvent(nextHandler
, event
, userData
);
316 return eventNotHandledErr
;
320 // A magic method that allows applications to react to events even
321 // when they are not organized in a bundle
322 void osx_AllowForeground()
324 ProcessSerialNumber psn
= { 0, kCurrentProcess
};
325 TransformProcessType(&psn
, kProcessTransformToForegroundApplication
);
326 SetFrontProcess(&psn
);
329 int doMain (int argc
, char **argv
)
331 osx_AllowForeground();
335 OSG::osgInit(argc
, argv
);
339 // beacon for camera and light
340 OSG::NodeUnrecPtr b1n
= OSG::Node::create();
341 OSG::GroupUnrecPtr b1
= OSG::Group::create();
345 OSG::NodeUnrecPtr t1n
= OSG::Node::create();
346 OSG::TransformUnrecPtr t1
= OSG::Transform::create();
348 t1n
->addChild( b1n
);
354 OSG::NodeUnrecPtr dlight
= OSG::Node::create();
355 OSG::DirectionalLightUnrecPtr dl
= OSG::DirectionalLight::create();
357 dlight
->setCore( dl
);
359 dl
->setAmbient( .0, .0, .0, 1 );
360 dl
->setDiffuse( .8, .8, .8, .8 );
361 dl
->setDirection(0,0,1);
365 root
= OSG::Node::create();
366 OSG::GroupUnrecPtr gr1
= OSG::Group::create();
368 root
->setCore( gr1
);
369 root
->addChild( t1n
);
370 root
->addChild( dlight
);
374 OSG::NodeUnrecPtr file
= NULL
;
377 file
= OSG::SceneFileHandler::the()->read(argv
[1]);
381 std::cerr
<< "Couldn't load file, ignoring" << std::endl
;
382 file
= OSG::makeTorus( .5, 2, 16, 16 );
385 OSG::Thread::getCurrentChangeList()->commitChanges();
386 file
->updateVolume();
389 file
->getVolume().getBounds( min
, max
);
391 std::cout
<< "Volume: from " << min
<< " to " << max
<< std::endl
;
393 dlight
->addChild( file
);
395 std::cerr
<< "Tree: " << std::endl
;
399 cam
= OSG::PerspectiveCamera::create();
401 cam
->setBeacon( b1n
);
402 cam
->setFov( OSG::osgDegree2Rad( 90 ) );
404 cam
->setFar( 100000 );
407 OSG::SolidBackgroundUnrecPtr bkgnd
= OSG::SolidBackground::create();
409 bkgnd
->setColor(OSG::Color3f(0,0,1));
413 vp
= OSG::Viewport::create();
414 vp
->setCamera( cam
);
415 vp
->setBackground( bkgnd
);
417 vp
->setSize( 0,0, 1,1 );
421 ract
= OSG::RenderAction::create();
426 pos
.setValues(min
[0] + ((max
[0] - min
[0]) * 0.5),
427 min
[1] + ((max
[1] - min
[1]) * 0.5),
428 max
[2] + ( max
[2] - min
[2] ) * 1.5 );
430 float scale
= (max
[2] - min
[2] + max
[1] - min
[1] + max
[0] - min
[0]) / 6;
432 OSG::Pnt3f
tCenter(min
[0] + (max
[0] - min
[0]) / 2,
433 min
[1] + (max
[1] - min
[1]) / 2,
434 min
[2] + (max
[2] - min
[2]) / 2);
436 tball
.setMode( OSG::Trackball::OSGObject
);
437 tball
.setStartPosition( pos
, true );
438 tball
.setSum( true );
439 tball
.setTranslationMode( OSG::Trackball::OSGFree
);
440 tball
.setTranslationScale(scale
);
441 tball
.setRotationCenter(tCenter
);
446 WindowAttributes windowAttrs
=
447 kWindowStandardDocumentAttributes
|
448 kWindowLiveResizeAttribute
|
449 kWindowStandardHandlerAttribute
;
451 SetRect(&contentRect
, 0, 0, 300, 300);
453 CreateNewWindow(kDocumentWindowClass
, windowAttrs
, &contentRect
, &window
);
454 SetWindowTitleWithCFString(window
, CFSTR("testWindowCarbon"));
456 // Install event handler
457 EventHandlerUPP eventHandlerUPP
= NewEventHandlerUPP(eventHandler
);
458 EventTypeSpec eventList
[] =
460 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
},
461 { kEventClassMouse
, kEventMouseDown
},
462 { kEventClassMouse
, kEventMouseUp
},
463 { kEventClassMouse
, kEventMouseDragged
},
464 { kEventClassWindow
, kEventWindowClose
},
465 { kEventClassWindow
, kEventWindowDrawContent
},
466 { kEventClassWindow
, kEventWindowBoundsChanged
}
468 InstallWindowEventHandler(window
, eventHandlerUPP
, GetEventTypeCount(eventList
), eventList
, /*this*/0, 0);
471 GLint attribs
[] = { AGL_RGBA
, AGL_DOUBLEBUFFER
, AGL_DEPTH_SIZE
, 16, AGL_NONE
};
472 AGLPixelFormat pixelFormat
= aglChoosePixelFormat(0, 0, attribs
);
473 if (pixelFormat
== 0)
474 std::cerr
<< "Cannot choose pixel format" << std::endl
;
475 AGLContext context
= aglCreateContext(pixelFormat
, 0);
476 aglDestroyPixelFormat(pixelFormat
);
478 std::cerr
<< "Cannot create context" << std::endl
;
479 aglSetDrawable(context
, GetWindowPort(window
));
481 // Create OpenSG window
482 win
= OSG::CarbonWindow::create();
484 win
->setContext ( context
);
486 win
->resize( 300, 300 );
489 RepositionWindow(window
, 0, kWindowCascadeOnMainScreen
);
494 // do some OpenGL init. Will move into State Chunks later.
496 glEnable( GL_DEPTH_TEST
);
497 glEnable( GL_LIGHTING
);
498 glEnable( GL_LIGHT0
);
501 // Main loop ( event dispatching )
502 RunApplicationEventLoop();
505 aglDestroyContext(context
);
506 DisposeWindow(window
);
507 DisposeEventHandlerUPP(eventHandlerUPP
);
520 int main (int argc
, char **argv
)
530 int main (int argc
, char **argv
)
533 fprintf(stderr
, "Carbon not available in 64bit\n");