OpenSceneGraph/src/osgViewer/IOSUtils.mm

289 lines
9.2 KiB
Plaintext
Raw Normal View History

/*
* 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;
}
}