Changed: #947 showCursor, setMousePos, improved window move, useOptimizedDrawing:YES, cleaned up comments
This commit is contained in:
parent
59155f1839
commit
38fd14fbd2
7 changed files with 145 additions and 28 deletions
|
@ -1006,8 +1006,8 @@ bool CDriverGL::release()
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
||||||
# warning "OpenGL Driver: Missing Mac Implementation"
|
|
||||||
nlwarning("OpenGL Driver: Missing Mac Implementation");
|
NL3D::MAC::release();
|
||||||
|
|
||||||
#elif defined (NL_OS_UNIX)
|
#elif defined (NL_OS_UNIX)
|
||||||
if(_FullScreen)
|
if(_FullScreen)
|
||||||
|
|
|
@ -1288,8 +1288,8 @@ void CDriverGL::showCursor(bool b)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
||||||
# warning "OpenGL Driver: Missing Mac Implementation"
|
|
||||||
nlwarning("OpenGL Driver: Missing Mac Implementation");
|
NL3D::MAC::showCursor(b);
|
||||||
|
|
||||||
#elif defined (NL_OS_UNIX)
|
#elif defined (NL_OS_UNIX)
|
||||||
|
|
||||||
|
@ -1335,8 +1335,8 @@ void CDriverGL::setMousePos(float x, float y)
|
||||||
SetCursorPos(pt.x, pt.y);
|
SetCursorPos(pt.x, pt.y);
|
||||||
}
|
}
|
||||||
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
||||||
# warning "OpenGL Driver: Missing Mac Implementation"
|
|
||||||
nlwarning("OpenGL Driver: Missing Mac Implementation");
|
NL3D::MAC::setMousePos(x, y);
|
||||||
|
|
||||||
#elif defined (NL_OS_UNIX)
|
#elif defined (NL_OS_UNIX)
|
||||||
XWindowAttributes xwa;
|
XWindowAttributes xwa;
|
||||||
|
@ -1459,8 +1459,8 @@ void CDriverGL::setCapture (bool b)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
||||||
# warning "OpenGL Driver: Missing Mac Implementation"
|
|
||||||
nlwarning("OpenGL Driver: Missing Mac Implementation");
|
NL3D::MAC::setCapture(b);
|
||||||
|
|
||||||
#elif defined (NL_OS_UNIX)
|
#elif defined (NL_OS_UNIX)
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,18 @@ void setWindowTitle(const ucstring &title);
|
||||||
/// mac specific stuff while calling CDriverGL::swapBuffers()
|
/// mac specific stuff while calling CDriverGL::swapBuffers()
|
||||||
void swapBuffers();
|
void swapBuffers();
|
||||||
|
|
||||||
|
/// mac specific stuff while calling CDriverGL::setCapture()
|
||||||
|
void setCapture(bool b);
|
||||||
|
|
||||||
|
/// mac specific stuff while calling CDriverGL::showCursor()
|
||||||
|
void showCursor(bool b);
|
||||||
|
|
||||||
|
/// mac specific stuff while calling CDriverGL::setMousePos()
|
||||||
|
void setMousePos(float x, float y);
|
||||||
|
|
||||||
|
/// mac specific stuff while calling CDriverGL::release()
|
||||||
|
void release();
|
||||||
|
|
||||||
/// mac specific stuff while calling CCocoaEventEmitter::submitEvents()
|
/// mac specific stuff while calling CCocoaEventEmitter::submitEvents()
|
||||||
void submitEvents(NLMISC::CEventServer& server,
|
void submitEvents(NLMISC::CEventServer& server,
|
||||||
bool allWindows, NLMISC::CCocoaEventEmitter* eventEmitter);
|
bool allWindows, NLMISC::CCocoaEventEmitter* eventEmitter);
|
||||||
|
|
|
@ -74,6 +74,10 @@ bool init(uint windowIcon, emptyProc exitFunc)
|
||||||
|
|
||||||
bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
|
bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
TODO use show and resizable flags
|
||||||
|
*/
|
||||||
|
|
||||||
// create a cocoa window with the size provided by the mode parameter
|
// create a cocoa window with the size provided by the mode parameter
|
||||||
g_window = [[CocoaWindow alloc]
|
g_window = [[CocoaWindow alloc]
|
||||||
initWithContentRect:NSMakeRect(0, 0, mode.Width, mode.Height)
|
initWithContentRect:NSMakeRect(0, 0, mode.Width, mode.Height)
|
||||||
|
@ -126,6 +130,9 @@ bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
|
||||||
// enable mouse move events, NeL wants them
|
// enable mouse move events, NeL wants them
|
||||||
[g_window setAcceptsMouseMovedEvents:YES];
|
[g_window setAcceptsMouseMovedEvents:YES];
|
||||||
|
|
||||||
|
// there are no overlapping subview, so we can use the magical optimization!
|
||||||
|
[g_window useOptimizedDrawing:YES];
|
||||||
|
|
||||||
// create a opengl context for the view
|
// create a opengl context for the view
|
||||||
g_glctx = [g_glview openGLContext];
|
g_glctx = [g_glview openGLContext];
|
||||||
|
|
||||||
|
@ -138,6 +145,9 @@ bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
|
||||||
// put the window to the front and make it the key window
|
// put the window to the front and make it the key window
|
||||||
[g_window makeKeyAndOrderFront:nil];
|
[g_window makeKeyAndOrderFront:nil];
|
||||||
|
|
||||||
|
// this is our main window
|
||||||
|
[g_window makeMainWindow];
|
||||||
|
|
||||||
// tell the application that we are running now
|
// tell the application that we are running now
|
||||||
[g_app finishLaunching];
|
[g_app finishLaunching];
|
||||||
|
|
||||||
|
@ -168,11 +178,11 @@ bool setMode(const GfxMode& mode)
|
||||||
// leave fullscreen mode, enter windowed mode
|
// leave fullscreen mode, enter windowed mode
|
||||||
if(mode.Windowed && [g_glview isInFullScreenMode])
|
if(mode.Windowed && [g_glview isInFullScreenMode])
|
||||||
{
|
{
|
||||||
// pull the view back from fullscreen restoring windows options
|
// pull the view back from fullscreen restoring window options
|
||||||
[g_glview exitFullScreenModeWithOptions:nil];
|
[g_glview exitFullScreenModeWithOptions:nil];
|
||||||
|
|
||||||
// disable manual setting of back buffer size, cocoa handles this
|
// disable manual setting of back buffer size, cocoa handles this
|
||||||
// automatically as soon as the window gets resized
|
// automatically as soon as the view gets resized
|
||||||
CGLError error = CGLDisable((CGLContextObj)[g_glctx CGLContextObj],
|
CGLError error = CGLDisable((CGLContextObj)[g_glctx CGLContextObj],
|
||||||
kCGLCESurfaceBackingSize);
|
kCGLCESurfaceBackingSize);
|
||||||
|
|
||||||
|
@ -197,7 +207,7 @@ bool setMode(const GfxMode& mode)
|
||||||
// NOTE: withOptions:nil disables <CMD>+<Tab> application switching!
|
// NOTE: withOptions:nil disables <CMD>+<Tab> application switching!
|
||||||
/*
|
/*
|
||||||
TODO check if simply using NSView enterFullScreenMode is a good idea.
|
TODO check if simply using NSView enterFullScreenMode is a good idea.
|
||||||
the context can be set to full screen as well? performance differences?
|
the context can be set to full screen as well, performance differences?
|
||||||
*/
|
*/
|
||||||
[g_glview enterFullScreenMode:[NSScreen mainScreen] withOptions:
|
[g_glview enterFullScreenMode:[NSScreen mainScreen] withOptions:
|
||||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
@ -207,8 +217,8 @@ bool setMode(const GfxMode& mode)
|
||||||
NSFullScreenModeApplicationPresentationOptions, nil]];
|
NSFullScreenModeApplicationPresentationOptions, nil]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
|
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
|
||||||
|
// due to the back buffer size reading problem, just store the size
|
||||||
g_bufferSize[0] = mode.Width;
|
g_bufferSize[0] = mode.Width;
|
||||||
g_bufferSize[1] = mode.Height;
|
g_bufferSize[1] = mode.Height;
|
||||||
#endif
|
#endif
|
||||||
|
@ -226,11 +236,9 @@ void getWindowSize(uint32 &width, uint32 &height)
|
||||||
// changed, but the view still stays at full resolution. So the scaling of
|
// changed, but the view still stays at full resolution. So the scaling of
|
||||||
// the image from the rendered resolution to the view's resolution is done
|
// the image from the rendered resolution to the view's resolution is done
|
||||||
// by cocoa automatically while flushing buffers.
|
// by cocoa automatically while flushing buffers.
|
||||||
// That's why, in fullscreen mode, return the resolution from the back buffer,
|
// That's why, in fullscreen mode, return the resolution of the back buffer,
|
||||||
// not the one from the window.
|
// not the one from the window.
|
||||||
|
|
||||||
// check if manual back buffer sizing is enabled (thats only in fullscreen)
|
|
||||||
|
|
||||||
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
|
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
|
||||||
if([g_glview isInFullScreenMode])
|
if([g_glview isInFullScreenMode])
|
||||||
{
|
{
|
||||||
|
@ -244,10 +252,10 @@ void getWindowSize(uint32 &width, uint32 &height)
|
||||||
height = rect.size.height;
|
height = rect.size.height;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO does not work atm, "invalid enumeration"
|
TODO does not work atm, "invalid enumeration"
|
||||||
*/
|
*/
|
||||||
|
// check if manual back buffer sizing is enabled (thats only in fullscreen)
|
||||||
GLint surfaceBackingSizeSet = 0;
|
GLint surfaceBackingSizeSet = 0;
|
||||||
CGLError error = CGLIsEnabled((CGLContextObj)[g_glctx CGLContextObj],
|
CGLError error = CGLIsEnabled((CGLContextObj)[g_glctx CGLContextObj],
|
||||||
kCGLCESurfaceBackingSize, &surfaceBackingSizeSet);
|
kCGLCESurfaceBackingSize, &surfaceBackingSizeSet);
|
||||||
|
@ -291,10 +299,10 @@ void getWindowSize(uint32 &width, uint32 &height)
|
||||||
|
|
||||||
void getWindowPos(uint32 &x, uint32 &y)
|
void getWindowPos(uint32 &x, uint32 &y)
|
||||||
{
|
{
|
||||||
// get the size of the screen
|
// get the rect (position, size) of the screen
|
||||||
NSRect screenRect = [[g_window screen] frame];
|
NSRect screenRect = [[g_window screen] frame];
|
||||||
|
|
||||||
// get the size of the window
|
// get the rect (position, size) of the window
|
||||||
NSRect windowRect = [g_window frame];
|
NSRect windowRect = [g_window frame];
|
||||||
|
|
||||||
// simply return x
|
// simply return x
|
||||||
|
@ -331,6 +339,92 @@ void swapBuffers()
|
||||||
[g_glctx flushBuffer];
|
[g_glctx flushBuffer];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setCapture(bool b)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
TODO implement capture cursor, no need to fake using pull back to 0.5 / 0.5
|
||||||
|
set a flag and then act accordingly in event loop?
|
||||||
|
|
||||||
|
// no screen bounds...
|
||||||
|
void CGGetLastMouseDelta(CGMouseDelta* deltaX, CGMouseDelta* deltaY);
|
||||||
|
*/
|
||||||
|
nlwarning("not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
void showCursor(bool b)
|
||||||
|
{
|
||||||
|
// Mac OS manages a show/hide counter for the cursor, so hiding the cursor
|
||||||
|
// twice requires two calls to show to make the cursor visible again.
|
||||||
|
// Since other platforms seem to not do this, the functionality is masked here
|
||||||
|
// by only calling hide if the cursor is visible and only calling show if
|
||||||
|
// the cursor was hidden.
|
||||||
|
|
||||||
|
CGDisplayErr error = kCGErrorSuccess;
|
||||||
|
static bool visible = true;
|
||||||
|
|
||||||
|
if(b && !visible)
|
||||||
|
{
|
||||||
|
error = CGDisplayShowCursor(kCGDirectMainDisplay);
|
||||||
|
visible = true;
|
||||||
|
}
|
||||||
|
else if(!b && visible)
|
||||||
|
{
|
||||||
|
error = CGDisplayHideCursor(kCGDirectMainDisplay);
|
||||||
|
visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(error != kCGErrorSuccess)
|
||||||
|
nlerror("cannot get capture / un-capture cursor");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMousePos(float x, float y)
|
||||||
|
{
|
||||||
|
// CG wants absolute coordinates related to screen top left
|
||||||
|
CGFloat fromScreenLeft = 0.0;
|
||||||
|
CGFloat fromScreenTop = 0.0;
|
||||||
|
|
||||||
|
// get the gl view's rect for height and width
|
||||||
|
NSRect viewRect = [g_glview frame];
|
||||||
|
|
||||||
|
// if the view is not fullscreen, window top left is needed as offset
|
||||||
|
if(![g_glview isInFullScreenMode])
|
||||||
|
{
|
||||||
|
// get the rect (position, size) of the screen
|
||||||
|
NSRect screenRect = [[g_window screen] frame];
|
||||||
|
|
||||||
|
// get the rect (position, size) of the window
|
||||||
|
NSRect windowRect = [g_window frame];
|
||||||
|
|
||||||
|
// window's x is ok
|
||||||
|
fromScreenLeft = windowRect.origin.x;
|
||||||
|
|
||||||
|
// TODO this code assumes, that the view fills the window
|
||||||
|
|
||||||
|
// map window bottom to view top
|
||||||
|
fromScreenTop = screenRect.size.height -
|
||||||
|
viewRect.size.height - windowRect.origin.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// position inside the view
|
||||||
|
fromScreenLeft += (viewRect.size.width * x);
|
||||||
|
fromScreenTop += (viewRect.size.height * (1 - y));
|
||||||
|
|
||||||
|
// actually set the mouse position
|
||||||
|
CGDisplayErr error = CGDisplayMoveCursorToPoint(
|
||||||
|
kCGDirectMainDisplay, CGPointMake(fromScreenLeft, fromScreenTop));
|
||||||
|
|
||||||
|
if(error != kCGErrorSuccess)
|
||||||
|
nlerror("cannot set mouse position");
|
||||||
|
}
|
||||||
|
|
||||||
|
void release()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
TODO release some stuff
|
||||||
|
*/
|
||||||
|
nlwarning("not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: this function has to be moved to a more central place to handle key
|
TODO: this function has to be moved to a more central place to handle key
|
||||||
mapping on mac x11 as well
|
mapping on mac x11 as well
|
||||||
|
@ -552,10 +646,19 @@ void submitEvents(NLMISC::CEventServer& server,
|
||||||
// get the views size
|
// get the views size
|
||||||
NSRect rect = [g_glview frame];
|
NSRect rect = [g_glview frame];
|
||||||
|
|
||||||
|
// TODO this code assumes, that the view fills the window
|
||||||
// convert the mouse position to NeL style (relative)
|
// convert the mouse position to NeL style (relative)
|
||||||
float mouseX = event.locationInWindow.x / (float)rect.size.width;
|
float mouseX = event.locationInWindow.x / (float)rect.size.width;
|
||||||
float mouseY = event.locationInWindow.y / (float)rect.size.height;
|
float mouseY = event.locationInWindow.y / (float)rect.size.height;
|
||||||
|
|
||||||
|
// if the mouse event was placed on the window's titlebar, ignore it
|
||||||
|
if(mouseY > 1.0 && event.type != NSKeyDown && event.type != NSKeyUp)
|
||||||
|
{
|
||||||
|
[g_app sendEvent:event];
|
||||||
|
[g_app updateWindows];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch(event.type)
|
switch(event.type)
|
||||||
{
|
{
|
||||||
case NSLeftMouseDown:
|
case NSLeftMouseDown:
|
||||||
|
@ -597,6 +700,8 @@ void submitEvents(NLMISC::CEventServer& server,
|
||||||
/*
|
/*
|
||||||
TODO modifiers with mouse events
|
TODO modifiers with mouse events
|
||||||
*/
|
*/
|
||||||
|
// nldebug("mouse left drag %f %f", mouseX, mouseY);
|
||||||
|
|
||||||
server.postEvent(new NLMISC::CEventMouseMove(
|
server.postEvent(new NLMISC::CEventMouseMove(
|
||||||
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
|
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
[characterStorage release];
|
[characterStorage release];
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(BOOL)acceptsFirstResponder
|
-(BOOL)acceptsFirstResponder
|
||||||
{
|
{
|
||||||
return YES;
|
return YES;
|
||||||
|
|
|
@ -66,7 +66,7 @@ bool SetMousePosFirstTime = true;
|
||||||
uint DownMouseButtons = 0;
|
uint DownMouseButtons = 0;
|
||||||
|
|
||||||
#ifdef NL_OS_UNIX
|
#ifdef NL_OS_UNIX
|
||||||
// on X11, store whether the mouse was captured or not
|
// on X11 and cocoa, store whether the mouse was captured or not
|
||||||
bool MouseCapture = false;
|
bool MouseCapture = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -251,8 +251,8 @@ void SetMouseFreeLook ()
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NL_OS_UNIX
|
#ifdef NL_OS_UNIX
|
||||||
// on X11 the mouse needs to get pulled into the middle each update, else
|
// on X11 and cocoa the mouse needs to get pulled into the middle each update,
|
||||||
// the cursor would reach the border of the window / desktop
|
// else the cursor would reach the border of the window / desktop
|
||||||
// and freelook would hang
|
// and freelook would hang
|
||||||
Driver->setMousePos(0.5f, 0.5f);
|
Driver->setMousePos(0.5f, 0.5f);
|
||||||
#endif
|
#endif
|
||||||
|
@ -373,7 +373,7 @@ void CaptureSystemCursor()
|
||||||
if (!drvWnd) return;
|
if (!drvWnd) return;
|
||||||
SetCapture(drvWnd);
|
SetCapture(drvWnd);
|
||||||
#else
|
#else
|
||||||
// on X11, set driver mouse capture on and store it locally as well
|
// on X11 and cocoa, set driver mouse capture on and store it locally as well
|
||||||
Driver->setCapture(MouseCapture = true);
|
Driver->setCapture(MouseCapture = true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -392,7 +392,7 @@ void ReleaseSystemCursor()
|
||||||
}
|
}
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
#else
|
#else
|
||||||
// on X11, set driver mouse capture off and store it locally as well
|
// on X11 and cocoa, set driver mouse capture off and store it locally as well
|
||||||
Driver->setCapture(MouseCapture = false);
|
Driver->setCapture(MouseCapture = false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -458,25 +458,24 @@ void CUserControls::getMouseAngleMove(float &dx, float &dy)
|
||||||
{
|
{
|
||||||
float dmpx, dmpy;
|
float dmpx, dmpy;
|
||||||
|
|
||||||
#ifndef NL_MAC_NATIVE
|
// On X11 and Cocoa in free look mode, the mouse is pulled back to (0.5, 0.5)
|
||||||
// On X11 in free look mode, the mouse is pulled back to (0.5, 0.5)
|
|
||||||
// every update to prevent reaching a border and get stuck.
|
// every update to prevent reaching a border and get stuck.
|
||||||
if(IsMouseFreeLook())
|
if(IsMouseFreeLook())
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
TODO use setCapture to not fake it
|
TODO on X11, use setCapture to not fake it, capture on mac?
|
||||||
*/
|
*/
|
||||||
dmpx = EventsListener.getMousePosX() - 0.5;
|
dmpx = EventsListener.getMousePosX() - 0.5;
|
||||||
dmpy = EventsListener.getMousePosY() - 0.5;
|
dmpy = EventsListener.getMousePosY() - 0.5;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
dmpx = EventsListener.getMousePosX() - _LastFrameMousePosX;
|
dmpx = EventsListener.getMousePosX() - _LastFrameMousePosX;
|
||||||
dmpy = EventsListener.getMousePosY() - _LastFrameMousePosY;
|
dmpy = EventsListener.getMousePosY() - _LastFrameMousePosY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: read desktop mouse speed value on X11 / implement X11MouseDevice
|
// TODO: read desktop mouse speed value on X11 and Cocoa
|
||||||
|
// implement X11MouseDevice/CocoaMouseDevice?
|
||||||
dmpx *= 450.0f;
|
dmpx *= 450.0f;
|
||||||
dmpy *= 450.0f;
|
dmpy *= 450.0f;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue