Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/RenderSystems/GL/src/OSX/OgreOSXCarbonWindow.cpp @ 3

Last change on this file since 3 was 3, checked in by anonymous, 17 years ago

=update

File size: 12.5 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29
30#include "OgreOSXCarbonWindow.h"
31#include "OgreRoot.h"
32#include "OgreGLRenderSystem.h"
33#include "OgreImageCodec.h"
34#include "OgreException.h"
35#include "OgreLogManager.h"
36#include "OgreStringConverter.h"
37#include "OgreWindowEventUtilities.h"
38
39#include <OpenGL/gl.h>
40#define GL_EXT_texture_env_combine 1
41#include <OpenGL/glext.h>
42#include <OpenGL/glu.h>
43#include <AGL/agl.h>
44
45namespace Ogre
46{
47
48//-------------------------------------------------------------------------------------------------//
49OSXCarbonWindow::OSXCarbonWindow()
50{
51        mActive = mClosed = mHasResized = mIsFullScreen = false;
52        mAGLContext = NULL;
53        mContext = NULL;
54        mWindow = NULL;
55        mView = NULL;
56}
57
58//-------------------------------------------------------------------------------------------------//
59OSXCarbonWindow::~OSXCarbonWindow()
60{
61}
62
63//-------------------------------------------------------------------------------------------------//
64void OSXCarbonWindow::create( const String& name, unsigned int width, unsigned int height,
65                    bool fullScreen, const NameValuePairList *miscParams )
66{
67        bool hasDepthBuffer;
68        String title = name;
69        size_t fsaa_samples = 0;
70        int left = 0;
71        int top = 0;
72        int depth = 32;
73       
74        if( miscParams )
75        {
76               
77                NameValuePairList::const_iterator opt = NULL;
78               
79                // Full screen anti aliasing
80                opt = miscParams->find( "FSAA" );
81                if( opt != miscParams->end() )
82                        fsaa_samples = StringConverter::parseUnsignedInt( opt->second );
83
84                opt = miscParams->find( "left" );
85                if( opt != miscParams->end() )
86                        left = StringConverter::parseUnsignedInt( opt->second );
87
88                opt = miscParams->find( "top" );
89                if( opt != miscParams->end() )
90                        top = StringConverter::parseUnsignedInt( opt->second );
91
92                opt = miscParams->find( "title" );
93                if( opt != miscParams->end() )
94                        title = opt->second;
95
96                opt = miscParams->find( "depthBuffer" );
97                if( opt != miscParams->end() )
98                        hasDepthBuffer = StringConverter::parseBool( opt->second );
99               
100                opt = miscParams->find( "colourDepth" );
101                if( opt != miscParams->end() )
102                        depth = StringConverter::parseUnsignedInt( opt->second );
103        }
104       
105        if(fullScreen)
106        {
107                GLRenderSystem *rs = static_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem());
108                OSXContext *mainContext = (OSXContext*)rs->_getMainContext();
109               
110                CGLContextObj share = NULL;
111                if(mainContext == 0)
112                {
113                        share = NULL;
114                }
115                else if(mainContext->getContextType() == "AGL")
116                {
117                        OSXCarbonContext* aglShare = static_cast<OSXCarbonContext*>(mainContext);
118                        aglGetCGLContext(aglShare->getContext(), &((void*)share));
119                }
120                else if(mainContext->getContextType() == "CGL")
121                {
122                        OSXCGLContext* cglShare = static_cast<OSXCGLContext*>(mainContext);
123                        share = cglShare->getContext();
124                }
125               
126                // create the context
127                createCGLFullscreen(width, height, depth, fsaa_samples, share);         
128        }
129        else
130        {
131                int i = 0;
132                AGLPixelFormat pixelFormat;
133                GLint attribs[ 20 ];
134               
135                attribs[ i++ ] = AGL_NO_RECOVERY;
136                attribs[ i++ ] = GL_TRUE;
137                attribs[ i++ ] = AGL_ACCELERATED;
138                attribs[ i++ ] = GL_TRUE;
139                attribs[ i++ ] = AGL_RGBA;
140                attribs[ i++ ] = AGL_DOUBLEBUFFER;
141                attribs[ i++ ] = AGL_ALPHA_SIZE;
142                attribs[ i++ ] = 8;
143                attribs[ i++ ] = AGL_STENCIL_SIZE;
144                attribs[ i++ ] = 8;
145                attribs[ i++ ] = AGL_DEPTH_SIZE;
146                attribs[ i++ ] = depth;
147       
148                if(fsaa_samples > 1)
149                {
150                        attribs[ i++ ] = AGL_MULTISAMPLE;
151                        attribs[ i++ ] = 1;
152                        attribs[ i++ ] = AGL_SAMPLE_BUFFERS_ARB;
153                        attribs[ i++ ] = fsaa_samples;
154                }
155       
156                attribs[ i++ ] = AGL_NONE;
157       
158                pixelFormat = aglChoosePixelFormat( NULL, 0, attribs );
159       
160                // Create the AGLContext from our pixel format
161                // Share it with main
162                GLRenderSystem *rs = static_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem());
163                OSXContext* mainContext = static_cast<OSXContext*>( rs->_getMainContext() );
164                if(mainContext == 0)
165                {
166                        mAGLContext = aglCreateContext(pixelFormat, NULL);
167                }
168                else if(mainContext->getContextType() == "AGL")
169                {
170                        OSXCarbonContext* context = static_cast<OSXCarbonContext*>( rs->_getMainContext() );
171                        AGLContext shared = context->getContext();
172                        mAGLContext = aglCreateContext(pixelFormat, context->getContext());
173                }
174                else
175                {
176                        // If we do not have an AGL, we can not clone it using this window
177                        LogManager::getSingleton().logMessage( "Warning: You asked to create a second window, "
178                                "when the previous window was not of this type.  OgreOSXCarbonWindow can only share "
179                                "with an AGL context.");
180                }
181               
182                NameValuePairList::const_iterator opt = 0;
183                if(miscParams)
184                        opt = miscParams->find("externalWindowHandle");
185                if(!miscParams || opt == miscParams->end())
186                {
187                        // create the window rect in global coords
188                        ::Rect windowRect;
189                        windowRect.left = 0;
190                        windowRect.top = 0;
191                        windowRect.right = width;
192                        windowRect.bottom = height;
193                       
194                        // set the default attributes for the window
195                        WindowAttributes windowAttrs = kWindowStandardDocumentAttributes
196                                | kWindowStandardHandlerAttribute
197                                | kWindowInWindowMenuAttribute
198                                | kWindowHideOnFullScreenAttribute;
199                       
200                        // Create the window
201                        CreateNewWindow(kDocumentWindowClass, windowAttrs, &windowRect, &mWindow);
202                       
203                        // Color the window background black
204                        SetThemeWindowBackground (mWindow, kThemeBrushBlack, true);
205                       
206                        // Set the title of our window
207                        CFStringRef titleRef = CFStringCreateWithCString( kCFAllocatorDefault, title.c_str(), kCFStringEncodingASCII );
208                        SetWindowTitleWithCFString( mWindow, titleRef );
209                       
210                        // Center our window on the screen
211                        RepositionWindow( mWindow, NULL, kWindowCenterOnMainScreen );
212                       
213                        // Install the event handler for the window
214                        InstallStandardEventHandler(GetWindowEventTarget(mWindow));
215                       
216                        // Display and select our window
217                        ShowWindow(mWindow);
218                        SelectWindow(mWindow);
219                }
220                else
221                {
222                        // TODO: The Contol is going to report the incorrect location with a
223                        // Metalic / Textured window.  The default windows work just fine.
224                       
225                        // First get the HIViewRef / ControlRef
226                        mView = (HIViewRef)StringConverter::parseUnsignedLong(opt->second);
227                        mWindow = GetControlOwner(mView);
228                       
229                        // Lets try hiding the HIView
230                        //HIViewSetVisible(mView, false);
231                                       
232                        // Get the rect bounds
233                        ::Rect ctrlBounds;
234                        GetControlBounds(mView, &ctrlBounds);
235                        GLint bufferRect[4];
236
237                        bufferRect[0] = ctrlBounds.left;                                        // left edge
238                        bufferRect[1] = ctrlBounds.bottom;                                      // bottom edge
239                        bufferRect[2] = ctrlBounds.right - ctrlBounds.left; // width of buffer rect
240                        bufferRect[3] = ctrlBounds.bottom - ctrlBounds.top; // height of buffer rect
241                        aglSetInteger(mAGLContext, AGL_BUFFER_RECT, bufferRect);
242                        aglEnable (mAGLContext, AGL_BUFFER_RECT);
243                }
244               
245                // Set the drawable, and current context
246                // If you do this last, there is a moment before the rendering window pops-up
247                // This could go once inside each case above, before the window is displayed,
248                // if desired.
249                aglSetDrawable(mAGLContext, GetWindowPort(mWindow));
250                aglSetCurrentContext(mAGLContext);
251
252                // Give a copy of our context to the render system
253                mContext = new OSXCarbonContext(mAGLContext);
254        }
255       
256        WindowEventUtilities::_addRenderWindow(this);
257        mName = name;
258        mWidth = width;
259        mHeight = height;
260        mActive = true;
261        mIsFullScreen = fullScreen;
262}
263
264//-------------------------------------------------------------------------------------------------//
265void OSXCarbonWindow::destroy(void)
266{
267        LogManager::getSingleton().logMessage( "OSXCarbonWindow::destroy()" );
268       
269        if(mIsFullScreen)
270                destroyCGLFullscreen();
271               
272        WindowEventUtilities::_removeRenderWindow( this );
273
274        if(mWindow)
275                DisposeWindow(mWindow);
276
277        mActive = false;
278
279        Root::getSingleton().getRenderSystem()->detachRenderTarget(this->getName());
280}
281
282//-------------------------------------------------------------------------------------------------//
283bool OSXCarbonWindow::isActive() const
284{
285        return mActive;
286}
287
288//-------------------------------------------------------------------------------------------------//
289bool OSXCarbonWindow::isClosed() const
290{
291        return false;
292}
293
294//-------------------------------------------------------------------------------------------------//
295void OSXCarbonWindow::reposition(int left, int top)
296{
297        //LogManager::getSingleton().logMessage( "OSXCarbonWindow::reposition()" );
298        if(mWindow)
299                MoveWindow(mWindow, left, top, true);
300}
301
302//-------------------------------------------------------------------------------------------------//
303void OSXCarbonWindow::resize(unsigned int width, unsigned int height)
304{
305        //LogManager::getSingleton().logMessage( "OSXCarbonWindow::resize()" );
306        if(!mWindow)
307                return;
308
309        // Check if the window size really changed
310        if(mWidth == width && mHeight == height)
311                return;
312
313        mWidth = width;
314        mHeight = height;
315
316        SizeWindow(mWindow, width, height, true);
317}
318
319//-------------------------------------------------------------------------------------------------//
320void OSXCarbonWindow::windowHasResized()
321{
322        mHasResized = true;
323       
324        // Ensure the context is current
325        if(!mIsFullScreen)
326                aglSwapBuffers(mAGLContext);
327        else
328                swapCGLBuffers();
329}
330
331//-------------------------------------------------------------------------------------------------//
332void OSXCarbonWindow::windowResized()
333{
334        LogManager::getSingleton().logMessage( "OSXCarbonWindow::windowResized()" );
335       
336        // Ensure the context is current
337        if(!mIsFullScreen)
338        {
339                aglUpdateContext(mAGLContext);
340                ::Rect rect;
341                GetWindowBounds( mWindow, kWindowContentRgn, &rect );
342                mWidth = rect.left + rect.right;
343                mHeight = rect.top + rect.bottom;
344                mLeft = rect.left;
345                mTop = rect.top;
346        }
347        else
348                swapCGLBuffers();
349       
350        for( ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it )
351        {
352                ( *it ).second->_updateDimensions();
353        }
354}
355
356//-------------------------------------------------------------------------------------------------//
357void OSXCarbonWindow::windowMovedOrResized()
358{
359        // External windows will call this method.
360        if(mView != NULL)
361        {
362                //update our drawing region
363                ::Rect ctrlBounds;
364                GetControlBounds(mView, &ctrlBounds);
365                GLint bufferRect[4];
366
367                bufferRect[0] = ctrlBounds.left; // 0 = left edge
368                bufferRect[1] = ctrlBounds.bottom; // 0 = bottom edge
369                bufferRect[2] = ctrlBounds.right - ctrlBounds.left; // width of buffer rect
370                bufferRect[3] = ctrlBounds.bottom - ctrlBounds.top; // height of buffer rect
371                aglSetInteger(mAGLContext, AGL_BUFFER_RECT, bufferRect);
372                aglEnable (mAGLContext, AGL_BUFFER_RECT);
373                swapBuffers(true);
374               
375                mWidth = ctrlBounds.right - ctrlBounds.left;
376                mHeight = ctrlBounds.bottom - ctrlBounds.top;
377                mLeft = ctrlBounds.left;
378                mTop = ctrlBounds.top;
379               
380        }
381       
382        for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it)
383        {
384        (*it).second->_updateDimensions();
385        }
386}
387
388//-------------------------------------------------------------------------------------------------//
389void OSXCarbonWindow::swapBuffers( bool waitForVSync )
390{
391        if(!mIsFullScreen)
392        {
393                if(mAGLContext != aglGetCurrentContext())
394                        aglSetCurrentContext(mAGLContext);
395                       
396                aglSwapBuffers(mAGLContext);
397        }
398        else
399                swapCGLBuffers();
400               
401        if(mHasResized)
402        {
403                windowResized();
404                mHasResized = false;
405        }
406}
407
408//-------------------------------------------------------------------------------------------------//
409void OSXCarbonWindow::getCustomAttribute( const String& name, void* pData )
410{
411        if( name == "GLCONTEXT" ) 
412        {
413                *static_cast<OSXContext**>(pData) = mContext;
414                return;
415        }
416        else if( name == "WINDOW" )
417        {
418                if(mIsFullScreen)
419                {
420                        // A fullscreen application uses CGL and thus has no window.
421                        pData = 0;
422                        return;
423                }
424                else
425                {
426                                *static_cast<WindowRef*>(pData) = mWindow;
427                }
428                return;
429        }
430}
431}
Note: See TracBrowser for help on using the repository browser.