Added Mac OSX XCode project with Cocoa userinterface (wrapping GLUT) for Bullet demos
Thanks to TomorrowPlus for the constribution!
This commit is contained in:
25
Extras/AllBulletDemosOSX/src/toolkit/BTFullscreenWindow.h
Normal file
25
Extras/AllBulletDemosOSX/src/toolkit/BTFullscreenWindow.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface BTFullScreenWindow : NSWindow {
|
||||
|
||||
}
|
||||
|
||||
- (id) initForScreen: (NSScreen *) screen;
|
||||
|
||||
@end
|
||||
48
Extras/AllBulletDemosOSX/src/toolkit/BTFullscreenWindow.m
Normal file
48
Extras/AllBulletDemosOSX/src/toolkit/BTFullscreenWindow.m
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#import "BTFullScreenWindow.h"
|
||||
|
||||
|
||||
@implementation BTFullScreenWindow
|
||||
|
||||
- (id) initForScreen: (NSScreen *) screen
|
||||
{
|
||||
NSRect frame = [screen frame];
|
||||
frame.size.height -= [NSMenuView menuBarHeight];
|
||||
|
||||
self = [self initWithContentRect: frame
|
||||
styleMask: NSBorderlessWindowMask
|
||||
backing: NSBackingStoreBuffered
|
||||
defer: YES
|
||||
screen: screen ];
|
||||
if ( self )
|
||||
{
|
||||
/*
|
||||
For some reason, without this
|
||||
we lose mouse moved events in fullscreen
|
||||
*/
|
||||
[self setAcceptsMouseMovedEvents: YES];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeKeyWindow
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
46
Extras/AllBulletDemosOSX/src/toolkit/BTGLUTKeyAdapter.h
Normal file
46
Extras/AllBulletDemosOSX/src/toolkit/BTGLUTKeyAdapter.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef __BT_KEY_CODE_H__
|
||||
#define __BT_KEY_CODE_H__
|
||||
|
||||
#include <GLUT/glut.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
@brief Determine if a key is a letter.
|
||||
@return true if @a keycode is a letter, and not a control
|
||||
or modifier key. E.g., the letter 'b' is, where the Esc key ( BTKey_Escape ) is not.
|
||||
*/
|
||||
extern BOOL BTKeyIsAlpha( int );
|
||||
|
||||
/**
|
||||
@brief Determine if a key is a GLUT special key. ( arrow, F-Keys, etc )
|
||||
*/
|
||||
extern BOOL BTKeyIsSpecial( int keycode );
|
||||
|
||||
/**
|
||||
@brief Convert an OS X keycode to GLUT Special key representation
|
||||
*/
|
||||
extern int BTKeyTranslateKeyCodeToSpecial( int );
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
128
Extras/AllBulletDemosOSX/src/toolkit/BTGLUTKeyAdapter.m
Normal file
128
Extras/AllBulletDemosOSX/src/toolkit/BTGLUTKeyAdapter.m
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#import "BTGLUTKeyAdapter.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
BOOL BTKeyIsAlpha( int key )
|
||||
{
|
||||
return !BTKeyIsSpecial( key );
|
||||
}
|
||||
|
||||
BOOL BTKeyIsSpecial( int keycode )
|
||||
{
|
||||
BOOL ret = NO;
|
||||
switch( keycode )
|
||||
{
|
||||
case NSUpArrowFunctionKey:
|
||||
case NSDownArrowFunctionKey:
|
||||
case NSLeftArrowFunctionKey:
|
||||
case NSRightArrowFunctionKey:
|
||||
case NSF1FunctionKey:
|
||||
case NSF2FunctionKey:
|
||||
case NSF3FunctionKey:
|
||||
case NSF4FunctionKey:
|
||||
case NSF5FunctionKey:
|
||||
case NSF6FunctionKey:
|
||||
case NSF7FunctionKey:
|
||||
case NSF8FunctionKey:
|
||||
case NSF9FunctionKey:
|
||||
case NSF10FunctionKey:
|
||||
case NSF11FunctionKey:
|
||||
case NSF12FunctionKey:
|
||||
ret = YES;
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int BTKeyTranslateKeyCodeToSpecial( int kc )
|
||||
{
|
||||
int ret = kc;
|
||||
switch( kc )
|
||||
{
|
||||
case NSUpArrowFunctionKey:
|
||||
ret = GLUT_KEY_UP;
|
||||
break;
|
||||
|
||||
case NSDownArrowFunctionKey:
|
||||
ret = GLUT_KEY_DOWN;
|
||||
break;
|
||||
|
||||
case NSLeftArrowFunctionKey:
|
||||
ret = GLUT_KEY_LEFT;
|
||||
break;
|
||||
|
||||
case NSRightArrowFunctionKey:
|
||||
ret = GLUT_KEY_RIGHT;
|
||||
break;
|
||||
|
||||
case NSF1FunctionKey:
|
||||
ret = GLUT_KEY_F1;
|
||||
break;
|
||||
|
||||
case NSF2FunctionKey:
|
||||
ret = GLUT_KEY_F2;
|
||||
break;
|
||||
|
||||
case NSF3FunctionKey:
|
||||
ret = GLUT_KEY_F3;
|
||||
break;
|
||||
|
||||
case NSF4FunctionKey:
|
||||
ret = GLUT_KEY_F4;
|
||||
break;
|
||||
|
||||
case NSF5FunctionKey:
|
||||
ret = GLUT_KEY_F5;
|
||||
break;
|
||||
|
||||
case NSF6FunctionKey:
|
||||
ret = GLUT_KEY_F6;
|
||||
break;
|
||||
|
||||
case NSF7FunctionKey:
|
||||
ret = GLUT_KEY_F7;
|
||||
break;
|
||||
|
||||
case NSF8FunctionKey:
|
||||
ret = GLUT_KEY_F8;
|
||||
break;
|
||||
|
||||
case NSF9FunctionKey:
|
||||
ret = GLUT_KEY_F9;
|
||||
break;
|
||||
|
||||
case NSF10FunctionKey:
|
||||
ret = GLUT_KEY_F10;
|
||||
break;
|
||||
|
||||
case NSF11FunctionKey:
|
||||
ret = GLUT_KEY_F11;
|
||||
break;
|
||||
|
||||
case NSF12FunctionKey:
|
||||
ret = GLUT_KEY_F12;
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@protocol BTOpenGLDisplayDelegate
|
||||
|
||||
- (void) contextCreated;
|
||||
- (void) contextWillBeDestroyed;
|
||||
- (void) contextWillResize;
|
||||
- (void) contextResized: (NSSize) newSize;
|
||||
- (void) contextDidResize;
|
||||
- (void) contextStateInvalidated;
|
||||
|
||||
- (void) display: (float) deltaT;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// ASCII keypresses
|
||||
|
||||
- (void) keyPressed: (unsigned char) key;
|
||||
- (void) keyReleased: (unsigned char) key;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// GLUT Special Keys, such as GLUT_KEY_LEFT ( "left arrow key" )
|
||||
|
||||
- (void) specialKeyPressed: (unsigned) GLUTKey;
|
||||
- (void) specialKeyReleased: (unsigned) GLUTKey;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Mouse. button is GLUT_LEFT_MOUSE, GLUT_RIGHT_MOUSE, etc.
|
||||
|
||||
- (void) mouseButtonPressed: (unsigned) mouseButton;
|
||||
- (void) mouseButtonReleased: (unsigned) mouseButton;
|
||||
- (void) mouseMoved: (NSPoint) delta;
|
||||
- (void) newMousePosition: (NSPoint) newMousePosition;
|
||||
- (void) scrollWheel: (NSPoint) delta;
|
||||
@end
|
||||
65
Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLView.h
Normal file
65
Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLView.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#import "BTOpenGLDisplayDelegate.h"
|
||||
|
||||
@interface BTOpenGLView : NSView
|
||||
{
|
||||
IBOutlet id <BTOpenGLDisplayDelegate> _delegate;
|
||||
|
||||
BOOL _firstFrame,
|
||||
_setupBoundsChangeNotification,
|
||||
_isFullScreen,
|
||||
_multisample,
|
||||
_vblSync,
|
||||
_suppressResize;
|
||||
|
||||
NSOpenGLContext *_windowedContext;
|
||||
|
||||
unsigned int _modifierFlags;
|
||||
|
||||
float _interval,
|
||||
_currentFPS;
|
||||
|
||||
double _lastFrameTime;
|
||||
|
||||
NSWindow *_fullscreenWindow,
|
||||
*_windowedWindow;
|
||||
|
||||
NSTimer *_timer;
|
||||
}
|
||||
|
||||
- (void) setDelegate: (id <BTOpenGLDisplayDelegate>) delegate;
|
||||
- (id <BTOpenGLDisplayDelegate>) delegate;
|
||||
|
||||
- (void) setTargetFPS: (float) fps;
|
||||
- (float) targetFPS;
|
||||
- (float) currentFPS;
|
||||
|
||||
- (void) setFullscreen: (BOOL) yesno;
|
||||
- (BOOL) fullscreen;
|
||||
|
||||
- (void) setMultisampleRendering: (BOOL) multisample;
|
||||
- (BOOL) multisampleRendering;
|
||||
|
||||
- (void) setVBLSync: (BOOL) sync;
|
||||
- (BOOL) vblSync;
|
||||
|
||||
- (NSOpenGLContext*) openGLContext;
|
||||
|
||||
|
||||
@end
|
||||
603
Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLView.m
Normal file
603
Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLView.m
Normal file
@@ -0,0 +1,603 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#import "BTOpenGLView.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
#import "BTFullScreenWindow.h"
|
||||
#import "BTGLUTKeyAdapter.h"
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Private Methods
|
||||
|
||||
@interface BTOpenGLView (Internal)
|
||||
|
||||
- (void) update;
|
||||
- (void) boundsDidChange: (NSNotification *) notification;
|
||||
- (void) setVBL: (BOOL*) vbl forContext: (NSOpenGLContext*) context;
|
||||
- (void) setMultithreaded: (BOOL) mt;
|
||||
- (NSOpenGLPixelFormat*) windowedPixelFormat: (BOOL*) antialias;
|
||||
|
||||
@end
|
||||
|
||||
@implementation BTOpenGLView
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Bootstrap
|
||||
|
||||
- (id)initWithFrame:(NSRect)frameRect
|
||||
{
|
||||
self = [super initWithFrame:frameRect];
|
||||
if (self == nil)
|
||||
{
|
||||
NSLog( @"BTOpenGLView::initWithFrame - Unable to init" );
|
||||
return nil;
|
||||
}
|
||||
|
||||
_modifierFlags = 0;
|
||||
_multisample = YES;
|
||||
_vblSync = YES;
|
||||
_firstFrame = YES;
|
||||
_setupBoundsChangeNotification = NO;
|
||||
|
||||
/*
|
||||
Set up the windowed context -- it will be assigned to the
|
||||
view later, not now.
|
||||
*/
|
||||
_windowedContext = [[NSOpenGLContext alloc] initWithFormat: [self windowedPixelFormat: &_multisample]
|
||||
shareContext: nil];
|
||||
|
||||
[self setVBL: &_vblSync forContext: _windowedContext];
|
||||
|
||||
if (_windowedContext == nil)
|
||||
{
|
||||
NSLog(@"Got nil windowed context");
|
||||
[self dealloc];
|
||||
return nil;
|
||||
}
|
||||
|
||||
/*
|
||||
Setup and start the update timer.
|
||||
*/
|
||||
_interval = 1.0 / 60.0;
|
||||
_timer = [[NSTimer scheduledTimerWithTimeInterval: _interval
|
||||
target: self
|
||||
selector: @selector(update)
|
||||
userInfo: nil
|
||||
repeats: YES ] retain];
|
||||
|
||||
[[NSRunLoop currentRunLoop] addTimer: _timer forMode: NSEventTrackingRunLoopMode];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_timer invalidate];
|
||||
[_timer release];
|
||||
|
||||
[_delegate contextWillBeDestroyed];
|
||||
|
||||
[_windowedContext release];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: self];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) awakeFromNib
|
||||
{
|
||||
NSWindow *window = [self window];
|
||||
[window setAcceptsMouseMovedEvents: YES];
|
||||
[window makeFirstResponder: self];
|
||||
[window setInitialFirstResponder: self];
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)rect
|
||||
{
|
||||
[self update];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Public API
|
||||
|
||||
- (void) setDelegate: (id <BTOpenGLDisplayDelegate>) delegate
|
||||
{
|
||||
// we don't retain delegates
|
||||
_delegate = delegate;
|
||||
}
|
||||
|
||||
- (id <BTOpenGLDisplayDelegate>) delegate
|
||||
{
|
||||
return _delegate;
|
||||
}
|
||||
|
||||
- (void) setTargetFPS: (float) fps
|
||||
{
|
||||
float newInterval = 1.0 / fps;
|
||||
if ( ABS( newInterval - _interval ) > 1.0e-3 )
|
||||
{
|
||||
_interval = newInterval;
|
||||
|
||||
[_timer invalidate];
|
||||
[_timer release];
|
||||
|
||||
_timer = [[NSTimer scheduledTimerWithTimeInterval: _interval
|
||||
target: self
|
||||
selector: @selector(update)
|
||||
userInfo: nil
|
||||
repeats: YES ] retain];
|
||||
|
||||
[[NSRunLoop currentRunLoop] addTimer: _timer forMode: NSEventTrackingRunLoopMode];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (float) targetFPS
|
||||
{
|
||||
return 1.0 / _interval;
|
||||
}
|
||||
|
||||
- (float) currentFPS
|
||||
{
|
||||
return _currentFPS;
|
||||
}
|
||||
|
||||
- (void) setFullscreen: (BOOL) fullscreen
|
||||
{
|
||||
if ( fullscreen == _isFullScreen ) return;
|
||||
|
||||
_isFullScreen = fullscreen;
|
||||
_suppressResize = YES;
|
||||
|
||||
if ( _isFullScreen )
|
||||
{
|
||||
_windowedWindow = [self window];
|
||||
|
||||
/*
|
||||
Detach & retain the content view from the non-fullscreen window.
|
||||
*/
|
||||
|
||||
NSView *contentView = [_windowedWindow contentView];
|
||||
[contentView retain];
|
||||
[contentView removeFromSuperviewWithoutNeedingDisplay];
|
||||
|
||||
/*
|
||||
Create a fullscreen window, attach the content view,
|
||||
and release the content view since the fullscreen window retained it.
|
||||
*/
|
||||
|
||||
_fullscreenWindow = [[BTFullScreenWindow alloc] initForScreen: [_windowedWindow screen]];
|
||||
[_fullscreenWindow setContentView: contentView ];
|
||||
[_fullscreenWindow makeKeyAndOrderFront:nil];
|
||||
[contentView release];
|
||||
|
||||
/*
|
||||
Hide the old window
|
||||
*/
|
||||
[_windowedWindow orderOut: nil];
|
||||
|
||||
/*
|
||||
Now, use the SetSystemUIMode API to auto-hide the dock
|
||||
*/
|
||||
|
||||
OSStatus error = SetSystemUIMode( kUIModeContentSuppressed, 0 );
|
||||
if ( error != noErr)
|
||||
{
|
||||
NSLog(@"Error couldn't set SystemUIMode: %ld", (long)error);
|
||||
}
|
||||
|
||||
}
|
||||
else if ( _fullscreenWindow )
|
||||
{
|
||||
/*
|
||||
Detach and retain the content view from the fullscreen window
|
||||
*/
|
||||
NSView *contentView = [_fullscreenWindow contentView];
|
||||
[contentView retain];
|
||||
[contentView removeFromSuperviewWithoutNeedingDisplay];
|
||||
|
||||
/*
|
||||
Reparent the content view to the non-fullscreen window,
|
||||
and release it since it's now owned by the non-fullscreen window
|
||||
*/
|
||||
[_windowedWindow setContentView: contentView];
|
||||
[contentView release];
|
||||
|
||||
[_windowedWindow makeKeyAndOrderFront: nil];
|
||||
|
||||
/*
|
||||
Release the fullscreen window
|
||||
*/
|
||||
[_fullscreenWindow orderOut: nil];
|
||||
[_fullscreenWindow release];
|
||||
_fullscreenWindow = nil;
|
||||
|
||||
/*
|
||||
Restore dock's normal behaior
|
||||
*/
|
||||
|
||||
OSStatus error = SetSystemUIMode( kUIModeNormal, 0 );
|
||||
if ( error != noErr)
|
||||
{
|
||||
NSLog(@"Error couldn't set SystemUIMode: %ld", (long)error);
|
||||
}
|
||||
}
|
||||
|
||||
_suppressResize = NO;
|
||||
|
||||
[self boundsDidChange: nil];
|
||||
}
|
||||
|
||||
- (BOOL) fullscreen
|
||||
{
|
||||
return _isFullScreen;
|
||||
}
|
||||
|
||||
- (void) setMultisampleRendering: (BOOL) multisample
|
||||
{
|
||||
if ( multisample == _multisample ) return;
|
||||
|
||||
_multisample = multisample;
|
||||
_firstFrame = YES;
|
||||
|
||||
|
||||
NSOpenGLContext *oldWindowedContext = _windowedContext;
|
||||
_windowedContext = [[NSOpenGLContext alloc] initWithFormat: [self windowedPixelFormat: &_multisample]
|
||||
shareContext: oldWindowedContext ];
|
||||
|
||||
[self setVBL: &_vblSync forContext: _windowedContext];
|
||||
|
||||
[oldWindowedContext release];
|
||||
[_windowedContext setView: self];
|
||||
[_windowedContext makeCurrentContext];
|
||||
[_windowedContext update];
|
||||
[self update];
|
||||
}
|
||||
|
||||
- (BOOL) multisampleRendering
|
||||
{
|
||||
return _multisample;
|
||||
}
|
||||
|
||||
- (void) setVBLSync: (BOOL) sync
|
||||
{
|
||||
if ( sync == _vblSync ) return;
|
||||
|
||||
_vblSync = sync;
|
||||
[self setVBL: &_vblSync forContext: _windowedContext];
|
||||
}
|
||||
|
||||
- (BOOL) vblSync
|
||||
{
|
||||
return _vblSync;
|
||||
}
|
||||
|
||||
- (NSOpenGLContext *) openGLContext
|
||||
{
|
||||
return _windowedContext;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark NSView Overrides
|
||||
|
||||
- (BOOL) isOpaque
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL) acceptsFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) keyDown:(NSEvent *)theEvent
|
||||
{
|
||||
int key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
|
||||
|
||||
if ( BTKeyIsAlpha( key ))
|
||||
{
|
||||
[ _delegate keyPressed: key ];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_delegate specialKeyPressed: BTKeyTranslateKeyCodeToSpecial( key )];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) keyUp:(NSEvent *)theEvent
|
||||
{
|
||||
int key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
|
||||
|
||||
if ( BTKeyIsAlpha( key ))
|
||||
{
|
||||
[ _delegate keyReleased: key ];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_delegate specialKeyReleased: BTKeyTranslateKeyCodeToSpecial( key )];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) mouseDown: (NSEvent *) event
|
||||
{
|
||||
int button = GLUT_LEFT_BUTTON;
|
||||
switch( [event buttonNumber] )
|
||||
{
|
||||
case 0: button = GLUT_LEFT_BUTTON; break;
|
||||
case 1: button = GLUT_RIGHT_BUTTON; break;
|
||||
case 2: button = GLUT_MIDDLE_BUTTON; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if ( _modifierFlags & NSControlKeyMask ) button = GLUT_RIGHT_BUTTON;
|
||||
else if ( _modifierFlags & NSAlternateKeyMask ) button = GLUT_MIDDLE_BUTTON;
|
||||
|
||||
[_delegate mouseButtonPressed: button];
|
||||
}
|
||||
|
||||
- (void) mouseUp: (NSEvent *) event
|
||||
{
|
||||
int button = GLUT_LEFT_BUTTON;
|
||||
switch( [event buttonNumber] )
|
||||
{
|
||||
case 0: button = GLUT_LEFT_BUTTON; break;
|
||||
case 1: button = GLUT_RIGHT_BUTTON; break;
|
||||
case 2: button = GLUT_MIDDLE_BUTTON; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if ( _modifierFlags & NSControlKeyMask ) button = GLUT_RIGHT_BUTTON;
|
||||
else if ( _modifierFlags & NSAlternateKeyMask ) button = GLUT_MIDDLE_BUTTON;
|
||||
|
||||
[_delegate mouseButtonReleased: button];
|
||||
}
|
||||
|
||||
-(void) mouseMoved: (NSEvent *) event
|
||||
{
|
||||
float dx = [event deltaX],
|
||||
dy = [event deltaY];
|
||||
|
||||
NSPoint locationInView = [self convertPoint: [event locationInWindow] fromView: nil ];
|
||||
|
||||
[_delegate mouseMoved: NSMakePoint( dx, dy )];
|
||||
[_delegate newMousePosition: locationInView];
|
||||
}
|
||||
|
||||
-(void) mouseDragged: (NSEvent *) event
|
||||
{
|
||||
[self mouseMoved: event];
|
||||
}
|
||||
|
||||
- (void) scrollWheel: (NSEvent *) event
|
||||
{
|
||||
float dx = [event deltaX],
|
||||
dy = [event deltaY];
|
||||
|
||||
[_delegate scrollWheel: NSMakePoint( dx, dy )];
|
||||
}
|
||||
|
||||
- (void)flagsChanged:(NSEvent *) event
|
||||
{
|
||||
_modifierFlags = [event modifierFlags];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Private
|
||||
|
||||
- (void) update
|
||||
{
|
||||
if ( !_setupBoundsChangeNotification )
|
||||
{
|
||||
_setupBoundsChangeNotification = YES;
|
||||
|
||||
/*
|
||||
This is hacky, but basically, we can't handle bounds-changing
|
||||
ops correctly until everything's set up correctly.
|
||||
*/
|
||||
[self setPostsBoundsChangedNotifications:YES];
|
||||
[[NSNotificationCenter defaultCenter] addObserver: self
|
||||
selector: @selector( boundsDidChange: )
|
||||
name: NSViewFrameDidChangeNotification
|
||||
object: nil];
|
||||
}
|
||||
|
||||
if (_firstFrame)
|
||||
{
|
||||
[_windowedContext setView:self];
|
||||
}
|
||||
|
||||
[_windowedContext makeCurrentContext];
|
||||
|
||||
if (_firstFrame)
|
||||
{
|
||||
_firstFrame = NO;
|
||||
|
||||
[_delegate contextCreated];
|
||||
|
||||
if ( _multisample )
|
||||
{
|
||||
glEnable (GL_MULTISAMPLE_ARB);
|
||||
// this fucks up text rendering, on nVIDIA, at least
|
||||
//glHint (GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable( GL_MULTISAMPLE_ARB );
|
||||
}
|
||||
|
||||
[self setMultithreaded: NO];
|
||||
|
||||
NSSize contextSize;
|
||||
if ( _isFullScreen )
|
||||
{
|
||||
contextSize.width = CGDisplayPixelsWide(kCGDirectMainDisplay);
|
||||
contextSize.height = CGDisplayPixelsHigh(kCGDirectMainDisplay);
|
||||
}
|
||||
else
|
||||
{
|
||||
contextSize = [self bounds].size;
|
||||
}
|
||||
|
||||
[_delegate contextWillResize];
|
||||
[_delegate contextResized: contextSize];
|
||||
[_delegate contextDidResize];
|
||||
[_delegate contextStateInvalidated];
|
||||
}
|
||||
|
||||
double now = CFAbsoluteTimeGetCurrent();
|
||||
|
||||
if ( _delegate) [_delegate display: now - _lastFrameTime];
|
||||
else
|
||||
{
|
||||
glClearColor( 0.5, 0.5, 0.5, 1 );
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
}
|
||||
|
||||
_lastFrameTime = now;
|
||||
|
||||
|
||||
[[NSOpenGLContext currentContext] flushBuffer];
|
||||
|
||||
/*
|
||||
Now, update our FPS
|
||||
*/
|
||||
|
||||
{
|
||||
static unsigned int frameCounter = 1;
|
||||
static double lastCheckTime = 0;
|
||||
|
||||
double elapsed = now - lastCheckTime;
|
||||
if ( elapsed > 1.0 )
|
||||
{
|
||||
_currentFPS = (float) ( ((double) frameCounter ) / elapsed );
|
||||
|
||||
lastCheckTime = now;
|
||||
frameCounter = 0;
|
||||
}
|
||||
|
||||
frameCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) boundsDidChange: (NSNotification *) notification
|
||||
{
|
||||
if ( _suppressResize ) return;
|
||||
|
||||
[_windowedContext setView:self];
|
||||
[_windowedContext makeCurrentContext];
|
||||
[_windowedContext update];
|
||||
|
||||
NSSize contextSize = [self bounds].size;
|
||||
|
||||
if ( _delegate )
|
||||
{
|
||||
[_delegate contextWillResize];
|
||||
[_delegate contextResized: contextSize ];
|
||||
[_delegate contextDidResize];
|
||||
}
|
||||
else
|
||||
{
|
||||
glViewport( 0, 0, (int) contextSize.width, (int) contextSize.height );
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setVBL: (BOOL*) vbl forContext: (NSOpenGLContext*) context
|
||||
{
|
||||
GLint value = *vbl ? 1 : 0;
|
||||
[context setValues: &value forParameter: NSOpenGLCPSwapInterval];
|
||||
|
||||
*vbl = value ? YES : NO;
|
||||
}
|
||||
|
||||
- (void) setMultithreaded: (BOOL) mt
|
||||
{
|
||||
CGLError err = kCGLNoError;
|
||||
CGLContextObj ctx = CGLGetCurrentContext();
|
||||
|
||||
// Enable Apple's multi-threaded GL engine -- it's generally useful for
|
||||
// high vertex throughput. Not high fragment situations
|
||||
|
||||
if ( mt )
|
||||
{
|
||||
err = CGLEnable( ctx, kCGLCEMPEngine );
|
||||
}
|
||||
else
|
||||
{
|
||||
err = CGLDisable( ctx, kCGLCEMPEngine );
|
||||
}
|
||||
|
||||
if (err != kCGLNoError )
|
||||
{
|
||||
NSLog( @"BTOpenGLView -setMultithreaded: forContext: -- Unable to %s multithreaded GL",
|
||||
mt ? "enable" : "disable" );
|
||||
}
|
||||
}
|
||||
|
||||
- (NSOpenGLPixelFormat*) windowedPixelFormat: (BOOL*) antialias
|
||||
{
|
||||
NSOpenGLPixelFormatAttribute aaAttrs[] =
|
||||
{
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
NSOpenGLPFAAccelerated,
|
||||
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)32,
|
||||
NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)0,
|
||||
NSOpenGLPFASingleRenderer,
|
||||
NSOpenGLPFASampleBuffers, (NSOpenGLPixelFormatAttribute)( 1 ),
|
||||
NSOpenGLPFASamples, (NSOpenGLPixelFormatAttribute)( 4 ),
|
||||
NSOpenGLPFAScreenMask, (NSOpenGLPixelFormatAttribute) CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
|
||||
NSOpenGLPFANoRecovery,
|
||||
(NSOpenGLPixelFormatAttribute)0
|
||||
};
|
||||
|
||||
NSOpenGLPixelFormatAttribute vanillaAttrs[] =
|
||||
{
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
NSOpenGLPFAAccelerated,
|
||||
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)32,
|
||||
NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)0,
|
||||
NSOpenGLPFASingleRenderer,
|
||||
NSOpenGLPFASampleBuffers, (NSOpenGLPixelFormatAttribute)( 0 ),
|
||||
NSOpenGLPFASamples, (NSOpenGLPixelFormatAttribute)( 0 ),
|
||||
NSOpenGLPFAScreenMask, (NSOpenGLPixelFormatAttribute) CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
|
||||
NSOpenGLPFANoRecovery,
|
||||
(NSOpenGLPixelFormatAttribute)0
|
||||
};
|
||||
|
||||
NSOpenGLPixelFormat* fmt = 0;
|
||||
|
||||
if ( *antialias )
|
||||
{
|
||||
fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: (NSOpenGLPixelFormatAttribute*) aaAttrs];
|
||||
if ( nil == fmt )
|
||||
{
|
||||
*antialias = NO;
|
||||
fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: (NSOpenGLPixelFormatAttribute*) vanillaAttrs];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: (NSOpenGLPixelFormatAttribute*) vanillaAttrs];
|
||||
}
|
||||
|
||||
return fmt;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user