//-------------------------------------------------------------------------------------------------// void OSXCarbonWindow::setVSyncEnabled(bool vsync) { mVSync = vsync; mContext->setCurrent(); CGLContextObj share = NULL; aglGetCGLContext(mAGLContext, (void**)&share); GLint vsyncInterval = mVSync ? 1 : 0; aglSetInteger(mAGLContext, AGL_SWAP_INTERVAL, &vsyncInterval); mContext->endCurrent(); if(!mIsFullScreen) { if(mAGLContext != aglGetCurrentContext()) aglSetCurrentContext(mAGLContext); } else { if(share != CGLGetCurrentContext()) CGLSetCurrentContext(share); } }
//-------------------------------------------------------------------------------------------------// void OSXCarbonWindow::create( const String& name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams ) { bool hasDepthBuffer; String title = name; size_t fsaa_samples = 0; int left = 0; int top = 0; int depth = 32; if( miscParams ) { NameValuePairList::const_iterator opt = NULL; // Full screen anti aliasing opt = miscParams->find( "FSAA" ); if( opt != miscParams->end() ) fsaa_samples = StringConverter::parseUnsignedInt( opt->second ); opt = miscParams->find( "left" ); if( opt != miscParams->end() ) left = StringConverter::parseUnsignedInt( opt->second ); opt = miscParams->find( "top" ); if( opt != miscParams->end() ) top = StringConverter::parseUnsignedInt( opt->second ); opt = miscParams->find( "title" ); if( opt != miscParams->end() ) title = opt->second; opt = miscParams->find( "depthBuffer" ); if( opt != miscParams->end() ) hasDepthBuffer = StringConverter::parseBool( opt->second ); opt = miscParams->find( "colourDepth" ); if( opt != miscParams->end() ) depth = StringConverter::parseUnsignedInt( opt->second ); } if(fullScreen) { GLRenderSystem *rs = static_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem()); OSXContext *mainContext = (OSXContext*)rs->_getMainContext(); CGLContextObj share = NULL; if(mainContext == 0) { share = NULL; } else if(mainContext->getContextType() == "AGL") { OSXCarbonContext* aglShare = static_cast<OSXCarbonContext*>(mainContext); aglGetCGLContext(aglShare->getContext(), &((void*)share)); } else if(mainContext->getContextType() == "CGL") { OSXCGLContext* cglShare = static_cast<OSXCGLContext*>(mainContext); share = cglShare->getContext(); } // create the context createCGLFullscreen(width, height, depth, fsaa_samples, share); } else { int i = 0; AGLPixelFormat pixelFormat; GLint attribs[ 20 ]; attribs[ i++ ] = AGL_NO_RECOVERY; attribs[ i++ ] = GL_TRUE; attribs[ i++ ] = AGL_ACCELERATED; attribs[ i++ ] = GL_TRUE; attribs[ i++ ] = AGL_RGBA; attribs[ i++ ] = AGL_DOUBLEBUFFER; attribs[ i++ ] = AGL_ALPHA_SIZE; attribs[ i++ ] = 8; attribs[ i++ ] = AGL_STENCIL_SIZE; attribs[ i++ ] = 8; attribs[ i++ ] = AGL_DEPTH_SIZE; attribs[ i++ ] = depth; if(fsaa_samples > 1) { attribs[ i++ ] = AGL_MULTISAMPLE; attribs[ i++ ] = 1; attribs[ i++ ] = AGL_SAMPLE_BUFFERS_ARB; attribs[ i++ ] = fsaa_samples; } attribs[ i++ ] = AGL_NONE; pixelFormat = aglChoosePixelFormat( NULL, 0, attribs ); // Create the AGLContext from our pixel format // Share it with main GLRenderSystem *rs = static_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem()); OSXContext* mainContext = static_cast<OSXContext*>( rs->_getMainContext() ); if(mainContext == 0) { mAGLContext = aglCreateContext(pixelFormat, NULL); } else if(mainContext->getContextType() == "AGL") { OSXCarbonContext* context = static_cast<OSXCarbonContext*>( rs->_getMainContext() ); AGLContext shared = context->getContext(); mAGLContext = aglCreateContext(pixelFormat, context->getContext()); } else { // If we do not have an AGL, we can not clone it using this window LogManager::getSingleton().logMessage( "Warning: You asked to create a second window, " "when the previous window was not of this type. OgreOSXCarbonWindow can only share " "with an AGL context."); } NameValuePairList::const_iterator opt = 0; if(miscParams) opt = miscParams->find("externalWindowHandle"); if(!miscParams || opt == miscParams->end()) { // create the window rect in global coords ::Rect windowRect; windowRect.left = 0; windowRect.top = 0; windowRect.right = width; windowRect.bottom = height; // set the default attributes for the window WindowAttributes windowAttrs = kWindowStandardDocumentAttributes; // default: "resize" if (miscParams) { opt = miscParams->find("border"); if( opt != miscParams->end() ) { String borderType = opt->second; if( borderType == "none" ) windowAttrs = kWindowNoTitleBarAttribute; else if( borderType == "fixed" ) windowAttrs = kWindowStandardFloatingAttributes; } } windowAttrs |= kWindowStandardHandlerAttribute | kWindowInWindowMenuAttribute | kWindowHideOnFullScreenAttribute; // Create the window CreateNewWindow(kDocumentWindowClass, windowAttrs, &windowRect, &mWindow); // Color the window background black SetThemeWindowBackground (mWindow, kThemeBrushBlack, true); // Set the title of our window CFStringRef titleRef = CFStringCreateWithCString( kCFAllocatorDefault, title.c_str(), kCFStringEncodingASCII ); SetWindowTitleWithCFString( mWindow, titleRef ); // Center our window on the screen RepositionWindow( mWindow, NULL, kWindowCenterOnMainScreen ); // Get our view HIViewFindByID( HIViewGetRoot( mWindow ), kHIViewWindowContentID, &mView ); // Set up our UPP for Window Events EventTypeSpec eventSpecs[] = { {kEventClassWindow, kEventWindowActivated}, {kEventClassWindow, kEventWindowDeactivated}, {kEventClassWindow, kEventWindowShown}, {kEventClassWindow, kEventWindowHidden}, {kEventClassWindow, kEventWindowDragCompleted}, {kEventClassWindow, kEventWindowBoundsChanged}, {kEventClassWindow, kEventWindowExpanded}, {kEventClassWindow, kEventWindowCollapsed}, {kEventClassWindow, kEventWindowClosed}, {kEventClassWindow, kEventWindowClose} }; EventHandlerUPP handlerUPP = NewEventHandlerUPP(WindowEventUtilities::_CarbonWindowHandler); // Install the standard event handler for the window EventTargetRef target = GetWindowEventTarget(mWindow); InstallStandardEventHandler(target); // We also need to install the WindowEvent Handler, we pass along the window with our requests InstallEventHandler(target, handlerUPP, 10, eventSpecs, (void*)this, &mEventHandlerRef); // Display and select our window ShowWindow(mWindow); SelectWindow(mWindow); // Add our window to the window event listener class WindowEventUtilities::_addRenderWindow(this); } else { // TODO: The Contol is going to report the incorrect location with a // Metalic / Textured window. The default windows work just fine. // First get the HIViewRef / ControlRef mView = (HIViewRef)StringConverter::parseUnsignedLong(opt->second); mWindow = GetControlOwner(mView); // Lets try hiding the HIView //HIViewSetVisible(mView, false); // Get the rect bounds ::Rect ctrlBounds; GetControlBounds(mView, &ctrlBounds); GLint bufferRect[4]; bufferRect[0] = ctrlBounds.left; // left edge bufferRect[1] = ctrlBounds.bottom; // bottom edge bufferRect[2] = ctrlBounds.right - ctrlBounds.left; // width of buffer rect bufferRect[3] = ctrlBounds.bottom - ctrlBounds.top; // height of buffer rect aglSetInteger(mAGLContext, AGL_BUFFER_RECT, bufferRect); aglEnable (mAGLContext, AGL_BUFFER_RECT); mIsExternal = true; } // Set the drawable, and current context // If you do this last, there is a moment before the rendering window pops-up // This could go once inside each case above, before the window is displayed, // if desired. aglSetDrawable(mAGLContext, GetWindowPort(mWindow)); aglSetCurrentContext(mAGLContext); // Give a copy of our context to the render system mContext = new OSXCarbonContext(mAGLContext, pixelFormat); } mName = name; mWidth = width; mHeight = height; mActive = true; mClosed = false; mCreated = true; mIsFullScreen = fullScreen; }
void OSXCarbonWindow::setFullscreen(bool fullScreen, unsigned int width, unsigned int height) { if (mIsFullScreen != fullScreen || width != mWidth || height != mHeight) { // Set the full screen flag mIsFullScreen = fullScreen; createAGLContext(mFSAA, mColourDepth); if (mIsFullScreen) { GLRenderSystem *rs = static_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem()); CGLContextObj share = NULL; aglGetCGLContext(mAGLContext, (void**)&share); // Create the CGL context object if it doesn't already exist, sharing the AGL context. if(!mCGLContext) { void *cglPixFormat; aglGetCGLPixelFormat(mAGLPixelFormat, (void **)&cglPixFormat); mCGLContext = OGRE_NEW OSXCGLContext(mCGLContextObj, (CGLPixelFormatObj) cglPixFormat); } // Create the context, keeping the current colour depth and FSAA settings createCGLFullscreen(width, height, getColourDepth(), getFSAA(), share); rs->_switchContext(mContext); // Hide the Carbon window HideWindow(mWindow); // And tell the rendersystem to stop rendering to it too WindowEventUtilities::_removeRenderWindow(this); } else { // Create a new AGL context and pixel format if necessary createAGLContext(mFSAA, mColourDepth); // Create a window if we haven't already, existence check is done within the functions if(!mWindow) { if(mIsExternal) createWindowFromExternal(mView); else createNewWindow(width, height, mWindowTitle); } // Destroy the current CGL context, we will create a new one when/if we go back to full screen destroyCGLFullscreen(); // Set the drawable, and current context // If you do this last, there is a moment before the rendering window pops-up #if defined(MAC_OS_X_VERSION_10_4) && MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 aglSetDrawable(mAGLContext, GetWindowPort(mWindow)); #else aglSetWindowRef(mAGLContext, mWindow); #endif aglSetCurrentContext(mAGLContext); if(!mCarbonContext) { mCarbonContext = OGRE_NEW OSXCarbonContext(mAGLContext, mAGLPixelFormat); } GLRenderSystem *rs = static_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem()); mContext = mCarbonContext; rs->_switchContext(mContext); WindowEventUtilities::_addRenderWindow(this); ShowWindow(mWindow); SelectWindow(mWindow); RepositionWindow(mWindow, NULL, kWindowCenterOnMainScreen); } mWidth = width; mHeight = height; } }