289 lines
9.2 KiB
Plaintext
289 lines
9.2 KiB
Plaintext
|
/*
|
||
|
* DarwinUtils.cpp
|
||
|
* OpenSceneGraph
|
||
|
*
|
||
|
* Created by Stephan Huber on 27.06.08.
|
||
|
* Copyright 2008 Stephan Maximilian Huber, digital mind. All rights reserved.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include <osg/Referenced>
|
||
|
#include <osg/DeleteHandler>
|
||
|
#include <Foundation/Foundation.h>
|
||
|
#import <UIKit/UIKit.h>
|
||
|
#include "IOSUtils.h"
|
||
|
|
||
|
|
||
|
namespace osgIOS {
|
||
|
|
||
|
|
||
|
class AutoReleasePoolHelper {
|
||
|
public:
|
||
|
AutoReleasePoolHelper() {
|
||
|
pool = [[NSAutoreleasePool alloc] init];
|
||
|
}
|
||
|
|
||
|
~AutoReleasePoolHelper() { [pool release]; }
|
||
|
private:
|
||
|
NSAutoreleasePool* pool;
|
||
|
};
|
||
|
|
||
|
|
||
|
/** ctor, get a list of all attached displays */
|
||
|
IOSWindowingSystemInterface::IOSWindowingSystemInterface()
|
||
|
: osg::GraphicsContext::WindowingSystemInterface()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/** dtor */
|
||
|
IOSWindowingSystemInterface::~IOSWindowingSystemInterface()
|
||
|
{
|
||
|
if (osg::Referenced::getDeleteHandler())
|
||
|
{
|
||
|
osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0);
|
||
|
osg::Referenced::getDeleteHandler()->flushAll();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/** @return count of attached screens */
|
||
|
unsigned int IOSWindowingSystemInterface::getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si)
|
||
|
{
|
||
|
AutoReleasePoolHelper auto_release_pool_helper;
|
||
|
return [[UIScreen screens] count];
|
||
|
}
|
||
|
|
||
|
void IOSWindowingSystemInterface::getScreenSettings(const osg::GraphicsContext::ScreenIdentifier& si, osg::GraphicsContext::ScreenSettings & resolution)
|
||
|
{
|
||
|
AutoReleasePoolHelper auto_release_pool_helper;
|
||
|
|
||
|
if(si.screenNum >= [[UIScreen screens] count]){return;}
|
||
|
|
||
|
|
||
|
|
||
|
//get the screens array from the UIScreen class
|
||
|
NSArray* screens = [UIScreen screens];
|
||
|
//iterate to the desired screen num
|
||
|
UIScreen* screen = [screens objectAtIndex:si.screenNum];
|
||
|
|
||
|
if (si.screenNum == 0)
|
||
|
{
|
||
|
//internal display supports only one mode, UiScreenMode reports wrong sizes for internal display at least for iOS 3.2
|
||
|
float scale = 1.0f;
|
||
|
|
||
|
#ifdef __IPHONE_4_0 && (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_4_0)
|
||
|
scale = [screen scale];
|
||
|
#endif
|
||
|
|
||
|
|
||
|
resolution.width = [screen bounds].size.width * scale;
|
||
|
resolution.height = [screen bounds].size.height * scale;
|
||
|
resolution.colorDepth = 24;
|
||
|
resolution.refreshRate = 60; //i've read 60 is max, not sure if thats true
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//get the screen mode
|
||
|
NSArray* modesArray = [screen availableModes];
|
||
|
|
||
|
if(modesArray)
|
||
|
{
|
||
|
//for this method we copy the first mode (default) then return
|
||
|
UIScreenMode* mode = [modesArray objectAtIndex:0];
|
||
|
|
||
|
CGSize size = [mode size];
|
||
|
resolution.width = size.width;
|
||
|
resolution.height = size.height;
|
||
|
resolution.colorDepth = 24;
|
||
|
resolution.refreshRate = 60; //i've read 60 is max, not sure if thats true
|
||
|
|
||
|
OSG_INFO << "new resolution for screen " << si.screenNum << ": " << size.width << "x" << size.height << std::endl;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
//Due to the weird
|
||
|
void IOSWindowingSystemInterface::enumerateScreenSettings(const osg::GraphicsContext::ScreenIdentifier& si,
|
||
|
osg::GraphicsContext::ScreenSettingsList & resolutionList)
|
||
|
{
|
||
|
AutoReleasePoolHelper auto_release_pool_helper;
|
||
|
|
||
|
if(si.screenNum >= [[UIScreen screens] count]){return;}
|
||
|
|
||
|
//get the screens array from the UIScreen class
|
||
|
NSArray* screens = [UIScreen screens];
|
||
|
//get the desired screen num
|
||
|
UIScreen* screen = [screens objectAtIndex:si.screenNum];
|
||
|
|
||
|
if (si.screenNum == 0)
|
||
|
{
|
||
|
//internal display supports only one mode, UiScreenMode reports wrong sizes for internal screen at least for iOS 3.2
|
||
|
osg::GraphicsContext::ScreenSettings resolution;
|
||
|
|
||
|
float scale = 1.0f;
|
||
|
#ifdef __IPHONE_4_0 && (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_4_0)
|
||
|
scale = [screen scale];
|
||
|
#endif
|
||
|
|
||
|
resolution.width = [screen bounds].size.width * scale;
|
||
|
resolution.height = [screen bounds].size.height * scale;
|
||
|
resolution.colorDepth = 24;
|
||
|
resolution.refreshRate = 60; //i've read 60 is max, not sure if thats true
|
||
|
resolutionList.push_back(resolution);
|
||
|
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// external display may support more resolutions:
|
||
|
|
||
|
//get the screen mode
|
||
|
NSArray* modesArray = [screen availableModes];
|
||
|
NSEnumerator* modesEnum = [modesArray objectEnumerator];
|
||
|
UIScreenMode* mode;
|
||
|
//iterate over modes and get their size property
|
||
|
while ( mode = [modesEnum nextObject] ) {
|
||
|
|
||
|
osg::GraphicsContext::ScreenSettings resolution;
|
||
|
CGSize size = [mode size];
|
||
|
resolution.width = size.width;
|
||
|
resolution.height = size.height;
|
||
|
resolution.colorDepth = 24;
|
||
|
resolution.refreshRate = 60; //i've read 60 is max, not sure if thats true
|
||
|
resolutionList.push_back(resolution);
|
||
|
|
||
|
OSG_INFO << "new resolution: " << size.width << "x" << size.height << std::endl;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
bool IOSWindowingSystemInterface::setScreenSettings(const osg::GraphicsContext::ScreenIdentifier &si, const osg::GraphicsContext::ScreenSettings & settings)
|
||
|
{
|
||
|
bool result = setScreenResolutionImpl(si, settings.width, settings.height);
|
||
|
if (result)
|
||
|
setScreenRefreshRateImpl(si, settings.refreshRate);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/** implementation of setScreenResolution */
|
||
|
//IPad can have extenal screens which we can request a res for
|
||
|
//the main screen screenNum 0 can not currently have its res changed
|
||
|
//as it only has one mode (might change though and this should still handle it)
|
||
|
//
|
||
|
bool IOSWindowingSystemInterface::setScreenResolutionImpl(const osg::GraphicsContext::ScreenIdentifier& si, unsigned int width, unsigned int height)
|
||
|
{
|
||
|
AutoReleasePoolHelper auto_release_pool_helper;
|
||
|
|
||
|
if(si.screenNum >= [[UIScreen screens] count]){return false;}
|
||
|
|
||
|
|
||
|
//get the screens array from the UIScreen class
|
||
|
NSArray* screens = [UIScreen screens];
|
||
|
|
||
|
//iterate to the desired screen num
|
||
|
UIScreen* screen = [screens objectAtIndex:si.screenNum];
|
||
|
|
||
|
//get the screen mode
|
||
|
NSArray* modesArray = [screen availableModes];
|
||
|
NSEnumerator* modesEnum = [modesArray objectEnumerator];
|
||
|
UIScreenMode* mode;
|
||
|
//iterate over modes and get their size property
|
||
|
while ( mode = [modesEnum nextObject] ) {
|
||
|
|
||
|
osg::GraphicsContext::ScreenSettings resolution;
|
||
|
CGSize size = [mode size];
|
||
|
|
||
|
//if the modes size/resolution matches the passed width/height then assign this
|
||
|
//mode as the screens current mode
|
||
|
if(size.width == width && size.height == height)
|
||
|
{
|
||
|
screen.currentMode = mode;
|
||
|
OSG_INFO << "IOSWindowingSystemInterface::setScreenResolutionImpl: Set resolution of screen '" << si.screenNum << "', to '" << width << ", " << height << "'." << std::endl;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
OSG_WARN << "IOSWindowingSystemInterface::setScreenResolutionImpl: Failed to set resolution of screen '" << si.screenNum << "', to '" << width << ", " << height << "'." << std::endl;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/** implementation of setScreenRefreshRate, don't think you can do this on IOS */
|
||
|
bool IOSWindowingSystemInterface::setScreenRefreshRateImpl(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, double refreshRate) {
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
unsigned int IOSWindowingSystemInterface::getScreenContaining(int x, int y, int w, int h)
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
//return the UIScreen object asscoiated with the passed ScreenIdentifier
|
||
|
//returns nil if si isn't found
|
||
|
//
|
||
|
UIScreen* IOSWindowingSystemInterface::getUIScreen(const osg::GraphicsContext::ScreenIdentifier& si)
|
||
|
{
|
||
|
AutoReleasePoolHelper auto_release_pool_helper;
|
||
|
|
||
|
if(si.screenNum >= [[UIScreen screens] count]){return nil;}
|
||
|
|
||
|
UIScreen* screen = [[UIScreen screens] objectAtIndex:si.screenNum];
|
||
|
return screen;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
//Returns the contents scale factor of the screen, this is the scale factor required
|
||
|
//to convert points to pixels on this screen
|
||
|
//
|
||
|
bool IOSWindowingSystemInterface::getScreenContentScaleFactor(const osg::GraphicsContext::ScreenIdentifier& si, float& scaleFactor)
|
||
|
{
|
||
|
AutoReleasePoolHelper auto_release_pool_helper;
|
||
|
|
||
|
if(si.screenNum >= [[UIScreen screens] count]){return false;}
|
||
|
|
||
|
UIScreen* screen = this->getUIScreen(si);
|
||
|
if(screen != nil)
|
||
|
{
|
||
|
scaleFactor = 1.0f;
|
||
|
#ifdef __IPHONE_4_0 && (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_4_0)
|
||
|
CGFloat scale = [screen scale];
|
||
|
scaleFactor = scale;
|
||
|
#endif
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
//Returns the screens size in points, docs state a point is roughly 1/160th of an inch
|
||
|
//
|
||
|
bool IOSWindowingSystemInterface::getScreenSizeInPoints(const osg::GraphicsContext::ScreenIdentifier& si, osg::Vec2& pointSize)
|
||
|
{
|
||
|
AutoReleasePoolHelper auto_release_pool_helper;
|
||
|
|
||
|
if(si.screenNum >= [[UIScreen screens] count]){return false;}
|
||
|
|
||
|
UIScreen* screen = this->getUIScreen(si);
|
||
|
if(screen != nil)
|
||
|
{
|
||
|
CGRect bounds = [screen bounds];
|
||
|
pointSize.x() = bounds.size.width;
|
||
|
pointSize.y() = bounds.size.height;
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
}
|