Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/RenderSystems/GL/src/OSX/OgreOSXGLSupport.mm @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
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 "OgreException.h"
31#include "OgreLogManager.h"
32#include "OgreStringConverter.h"
33#include "OgreRoot.h"
34
35#include "OgreOSXGLSupport.h"
36#include "OgreOSXCarbonWindow.h"
37#include "OgreOSXCocoaWindow.h"
38
39#include "OgreGLTexture.h"
40#include "OgreOSXRenderTexture.h"
41
42#include <OpenGL/OpenGL.h>
43#include <mach-o/dyld.h>
44
45namespace Ogre {
46
47OSXGLSupport::OSXGLSupport() : mAPI(""), mContextType("")
48{
49}
50
51OSXGLSupport::~OSXGLSupport()
52{
53}
54
55void OSXGLSupport::addConfig( void )
56{
57        ConfigOption optFullScreen;
58        ConfigOption optVideoMode;
59        ConfigOption optBitDepth;
60    ConfigOption optFSAA;
61        ConfigOption optRTTMode;
62
63        // FS setting possiblities
64        optFullScreen.name = "Full Screen";
65        optFullScreen.possibleValues.push_back( "Yes" );
66        optFullScreen.possibleValues.push_back( "No" );
67        optFullScreen.currentValue = "No";
68        optFullScreen.immutable = false;
69
70        optBitDepth.name = "Colour Depth";
71        optBitDepth.possibleValues.push_back( "32" );
72        optBitDepth.possibleValues.push_back( "16" );
73        optBitDepth.currentValue = "32";
74        optBitDepth.immutable = false;
75
76    mOptions[ optFullScreen.name ] = optFullScreen;
77        mOptions[ optBitDepth.name ] = optBitDepth;
78
79        CGLRendererInfoObj rend;
80        long nrend;
81        CGLQueryRendererInfo(CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &rend, &nrend);
82
83        long maxSamples;
84        CGLDescribeRenderer(rend, 0, kCGLRPMaxSamples, &maxSamples);
85
86    //FSAA possibilities
87    optFSAA.name = "FSAA";
88    optFSAA.possibleValues.push_back( "0" );
89
90        switch( maxSamples )
91        {
92                case 6:
93                        optFSAA.possibleValues.push_back( "2" );
94                        optFSAA.possibleValues.push_back( "4" );
95                        optFSAA.possibleValues.push_back( "6" );
96                        break;
97                case 4:
98                        optFSAA.possibleValues.push_back( "2" );
99                        optFSAA.possibleValues.push_back( "4" );
100                        break;
101                case 2:
102                        optFSAA.possibleValues.push_back( "2" );
103                        break;
104                default: break;
105        }
106
107    optFSAA.currentValue = "0";
108    optFSAA.immutable = false;
109
110    mOptions[ optFSAA.name ] = optFSAA;
111
112        // Video mode possiblities
113        optVideoMode.name = "Video Mode";
114        optVideoMode.immutable = false;
115
116        CFArrayRef displayModes = CGDisplayAvailableModes(CGMainDisplayID());
117        CFIndex numModes = CFArrayGetCount(displayModes);
118        CFMutableArrayRef goodModes = NULL;
119        goodModes = CFArrayCreateMutable(kCFAllocatorDefault, numModes, NULL);
120       
121        // Grab all the available display modes, then weed out duplicates...
122        for(int i = 0; i < numModes; ++i)
123        {
124                CFDictionaryRef modeInfo = (CFDictionaryRef)CFArrayGetValueAtIndex(displayModes, i);
125               
126                Boolean safeForHardware = _getDictionaryBoolean(modeInfo, kCGDisplayModeIsSafeForHardware);
127                Boolean stretched = _getDictionaryBoolean(modeInfo, kCGDisplayModeIsStretched);
128                Boolean skipped = false;
129               
130                if((safeForHardware) || (!stretched))
131                {
132                        long width  = _getDictionaryLong(modeInfo, kCGDisplayWidth);
133                        long height = _getDictionaryLong(modeInfo, kCGDisplayHeight);
134                       
135                        for(int j = 0; j < CFArrayGetCount(goodModes); ++j)
136                        {
137                                CFDictionaryRef otherMode = (CFDictionaryRef)CFArrayGetValueAtIndex(goodModes, j);
138
139                                long otherWidth  = _getDictionaryLong(otherMode, kCGDisplayWidth);
140                                long otherHeight = _getDictionaryLong(otherMode, kCGDisplayHeight);
141                               
142                                // If we find a duplicate then skip this mode
143                                if((otherWidth == width) && (otherHeight == height))
144                                        skipped = true;
145                        }
146                       
147                        // This is a new mode, so add it to our goodModes array
148                        if(!skipped)
149                                CFArrayAppendValue(goodModes, modeInfo);
150                }
151        }
152       
153        // Sort the modes...
154        CFArraySortValues(goodModes, CFRangeMake(0, CFArrayGetCount(goodModes)),
155                                          (CFComparatorFunction)_compareModes, NULL);
156                                         
157        // Now pull the modes out and put them into optVideoModes
158        for(int i = 0; i < CFArrayGetCount(goodModes); ++i)
159        {
160                CFDictionaryRef resolution = (CFDictionaryRef)CFArrayGetValueAtIndex(goodModes, i);
161               
162                long fWidth  = _getDictionaryLong(resolution, kCGDisplayWidth);
163                long fHeight = _getDictionaryLong(resolution, kCGDisplayHeight);
164               
165                String resoString = StringConverter::toString(fWidth) + " x " + StringConverter::toString(fHeight);
166                optVideoMode.possibleValues.push_back(resoString);
167               
168                //LogManager::getSingleton().logMessage( "Added resolution: " + resoString);
169        }
170       
171        optRTTMode.name = "RTT Preferred Mode";
172        optRTTMode.possibleValues.push_back( "FBO" );
173        optRTTMode.possibleValues.push_back( "PBuffer" );
174        optRTTMode.possibleValues.push_back( "Copy" );
175        optRTTMode.currentValue = "PBuffer";
176        optRTTMode.immutable = false;
177
178
179        mOptions[optFullScreen.name] = optFullScreen;
180        mOptions[optVideoMode.name] = optVideoMode;
181    mOptions[optFSAA.name] = optFSAA;
182        mOptions[optRTTMode.name] = optRTTMode;
183
184}
185
186String OSXGLSupport::validateConfig( void )
187{
188        return String( "" );
189}
190
191RenderWindow* OSXGLSupport::createWindow( bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle )
192{
193        if( autoCreateWindow )
194        {
195                ConfigOptionMap::iterator opt = mOptions.find( "Full Screen" );
196                if( opt == mOptions.end() )
197                        OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, "Can't find full screen options!", "OSXGLSupport::createWindow" );
198                bool fullscreen = ( opt->second.currentValue == "Yes" );
199
200                opt = mOptions.find( "Video Mode" );
201                if( opt == mOptions.end() )
202                        OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, "Can't find video mode options!", "OSXGLSupport::createWindow" );
203                String val = opt->second.currentValue;
204                String::size_type pos = val.find( 'x' );
205                if( pos == String::npos )
206                        OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, "Invalid Video Mode provided", "OSXGLSupport::createWindow" );
207
208                unsigned int w = StringConverter::parseUnsignedInt( val.substr( 0, pos ) );
209                unsigned int h = StringConverter::parseUnsignedInt( val.substr( pos + 1 ) );
210
211        // Parse FSAA config
212                NameValuePairList winOptions;
213                winOptions[ "title" ] = windowTitle;
214        int fsaa_x_samples = 0;
215        opt = mOptions.find( "FSAA" );
216        if( opt != mOptions.end() )
217        {
218                        winOptions[ "FSAA" ] = opt->second.currentValue;
219        }
220
221                return renderSystem->createRenderWindow( windowTitle, w, h, fullscreen, &winOptions );
222        }
223        else
224        {
225                // XXX What is the else?
226                return NULL;
227        }
228}
229
230RenderWindow* OSXGLSupport::newWindow( const String &name, unsigned int width, unsigned int height,
231        bool fullScreen, const NameValuePairList *miscParams )
232{
233        //  Does the user want Cocoa or Carbon, default to carbon...
234        mAPI = "carbon";
235        mContextType = "AGL";
236       
237        if(miscParams)
238        {
239                NameValuePairList::const_iterator opt = NULL;
240               
241                // First we must determine if this is a carbon or a cocoa window
242                // that we wish to create
243                opt = miscParams->find("macAPI");
244                if(opt != miscParams->end() && opt->second == "cocoa")
245                {
246                        // Our user wants a cocoa compatable system
247                        mAPI = "cocoa";
248                        mContextType = "NSOpenGL";
249                }
250        }
251       
252        // Create the window, if cocoa return a cocoa window
253        if(mAPI == "cocoa")
254        {
255                LogManager::getSingleton().logMessage("Creating a Cocoa Compatible Render System");
256                OSXCocoaWindow* window = new OSXCocoaWindow();
257                window->create(name, width, height, fullScreen, miscParams);
258                return window;
259        }
260       
261        // Otherwise default to carbon
262        LogManager::getSingleton().logMessage("Creating a Carbon Compatible Render System");
263        OSXCarbonWindow* window = new OSXCarbonWindow();
264        window->create(name, width, height, fullScreen, miscParams);
265        return window;
266}
267
268void OSXGLSupport::start()
269{
270        LogManager::getSingleton().logMessage(
271                        "*******************************************\n"
272                        "***    Starting OSX OpenGL Subsystem    ***\n"
273                        "*******************************************");
274}
275
276void OSXGLSupport::stop()
277{
278        LogManager::getSingleton().logMessage(
279                        "*******************************************\n"
280                        "***    Stopping OSX OpenGL Subsystem    ***\n"
281                        "*******************************************");
282}
283
284void* OSXGLSupport::getProcAddress( const char* name )
285{
286        NSSymbol symbol;
287    char *symbolName;
288    // Prepend a '_' for the Unix C symbol mangling convention
289    symbolName = (char*)malloc (strlen (name) + 2);
290    strcpy(symbolName + 1, name);
291    symbolName[0] = '_';
292    symbol = NULL;
293        // TODO:  dlopen calls, dyld
294    if (NSIsSymbolNameDefined (symbolName))
295        symbol = NSLookupAndBindSymbol (symbolName);
296    free (symbolName);
297    return symbol ? NSAddressOfSymbol (symbol) : NULL;
298}
299
300void* OSXGLSupport::getProcAddress( const String& procname )
301{
302        return getProcAddress( procname.c_str() );
303}
304
305bool OSXGLSupport::supportsPBuffers()
306{
307        return true;
308}
309
310GLPBuffer* OSXGLSupport::createPBuffer(PixelComponentType format, size_t width, size_t height)
311{
312//      if(mContextType == "NSOpenGL")
313//              return new OSXCocoaPBuffer(format, width, height);
314//      if(mContextType == "CGL")
315//              return new OSXCGLPBuffer(format, width, height);
316//      else
317                return new OSXPBuffer(format, width, height);
318}
319
320CFComparisonResult OSXGLSupport::_compareModes (const void *val1, const void *val2, void *context)
321{
322        // These are the values we will be interested in...
323        /*
324        _getDictionaryLong((mode), kCGDisplayWidth)
325        _getDictionaryLong((mode), kCGDisplayHeight)
326        _getDictionaryLong((mode), kCGDisplayRefreshRate)
327        _getDictionaryLong((mode), kCGDisplayBitsPerPixel)
328        _getDictionaryBoolean((mode), kCGDisplayModeIsSafeForHardware)
329        _getDictionaryBoolean((mode), kCGDisplayModeIsStretched)
330        */
331       
332        // CFArray comparison callback for sorting display modes.
333        #pragma unused(context)
334        CFDictionaryRef thisMode = (CFDictionaryRef)val1;
335        CFDictionaryRef otherMode = (CFDictionaryRef)val2;
336       
337        long width = _getDictionaryLong(thisMode, kCGDisplayWidth);
338        long otherWidth = _getDictionaryLong(otherMode, kCGDisplayWidth);
339       
340        long height = _getDictionaryLong(thisMode, kCGDisplayHeight);
341        long otherHeight = _getDictionaryLong(otherMode, kCGDisplayHeight);
342
343        // sort modes in screen size order
344        if (width * height < otherWidth * otherHeight)
345        {
346                return kCFCompareLessThan;
347        }
348        else if (width * height > otherWidth * otherHeight)
349        {
350                return kCFCompareGreaterThan;
351        }
352
353        // sort modes by bits per pixel
354        long bitsPerPixel = _getDictionaryLong(thisMode, kCGDisplayBitsPerPixel);
355        long otherBitsPerPixel = _getDictionaryLong(otherMode, kCGDisplayBitsPerPixel);
356
357        if (bitsPerPixel < otherBitsPerPixel)
358        {
359                return kCFCompareLessThan;
360        }
361        else if (bitsPerPixel > otherBitsPerPixel)
362        {
363                return kCFCompareGreaterThan;
364        }
365
366        // sort modes by refresh rate.
367        long refreshRate = _getDictionaryLong(thisMode, kCGDisplayRefreshRate);
368        long otherRefreshRate = _getDictionaryLong(otherMode, kCGDisplayRefreshRate);
369
370        if (refreshRate < otherRefreshRate)
371        {
372                return kCFCompareLessThan;
373        }
374        else if (refreshRate > otherRefreshRate)
375        {
376                return kCFCompareGreaterThan;
377        }
378
379        return kCFCompareEqualTo;
380}
381
382Boolean OSXGLSupport::_getDictionaryBoolean(CFDictionaryRef dict, const void* key)
383{
384        Boolean value = false;
385        CFBooleanRef boolRef;
386        boolRef = (CFBooleanRef)CFDictionaryGetValue(dict, key);
387       
388        if (boolRef != NULL)
389                value = CFBooleanGetValue(boolRef);     
390               
391        return value;
392}
393
394long OSXGLSupport::_getDictionaryLong(CFDictionaryRef dict, const void* key)
395{
396        long value = 0;
397        CFNumberRef numRef;
398        numRef = (CFNumberRef)CFDictionaryGetValue(dict, key);
399       
400        if (numRef != NULL)
401                CFNumberGetValue(numRef, kCFNumberLongType, &value);   
402               
403        return value;
404}
405
406
407}
Note: See TracBrowser for help on using the repository browser.