b523cb15c1
attached you'll find the second part of the IOS-submission. It contains * GraphicsWindowIOS, which supports external and "retina" displays, multisample-buffers (for IOS > 4.0) and multi-touch-events * an ios-specific implementation of the imageio-plugin * an iphone-viewer example * cMake support for creating a xcode-project * an updated ReadMe-file describing the necessary steps to get a working xcode-project-file from CMake Please credit Thomas Hogarth and Stephan Huber for these changes. This brings the ios-support in line with the git-fork on github. It needs some more testing and some more love, the cmake-process is still a little complicated. You'll need a special version of the freetype lib compiled for IOS, there's one bundled in the OpenFrameworks-distribution, which can be used." Notes, from Robert Osfield, modified CMakeLists.txt files so that the IOS specific paths are within IF(APPLE) blocks.
289 lines
9.2 KiB
Plaintext
Executable File
289 lines
9.2 KiB
Plaintext
Executable File
/*
|
|
* 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;
|
|
}
|
|
|
|
}
|