openFrameworks icon indicating copy to clipboard operation
openFrameworks copied to clipboard

ofGetOrientation() Can't get hardware orientation on startup

Open cuinjune opened this issue 8 years ago • 2 comments

Hi, I'm trying to detect the device orientation when the app is launched.

But it seems like the app always changes its orientation to OF_ORIENTATION_DEFAULT on startup regardless of its current hardware orientation.

For example, if I start an app in a landscape mode, it always changes to a default portrait mode.

Here's my example code,

in main.mm

int main() {
    
    //  here are the most commonly used iOS window settings.
    //------------------------------------------------------
    ofiOSWindowSettings settings;
    settings.enableRetina = true; // enables retina resolution if the device supports it.
    settings.enableDepth = true; // enables depth buffer for 3d drawing.
    settings.enableAntiAliasing = true; // enables anti-aliasing which smooths out graphics on the screen.
    settings.numOfAntiAliasingSamples = 4; // number of samples used for anti-aliasing.
    settings.enableHardwareOrientation = true; // enables native view orientation.
    settings.enableHardwareOrientationAnimation = false; // enables native orientation changes to be animated.
    settings.glesVersion = OFXIOS_RENDERER_ES1; // type of renderer to use, ES1, ES2, etc.
    
    ofCreateWindow(settings);
    
	return ofRunApp(new ofApp);
}

in ofApp.mm

//--------------------------------------------------------------
void ofApp::setup(){	

    switch (ofGetOrientation()) {
            
        case OF_ORIENTATION_DEFAULT:
            cout << "OF_ORIENTATION_DEFAULT" << endl;
            break;
        case OF_ORIENTATION_180:
            cout << "OF_ORIENTATION_180" << endl;
            break;
        case OF_ORIENTATION_90_LEFT:
            cout << "OF_ORIENTATION_90_LEFT" << endl;
            break;
        case OF_ORIENTATION_90_RIGHT:
            cout << "OF_ORIENTATION_90_RIGHT" << endl;
            break;
        case OF_ORIENTATION_UNKNOWN:
            cout << "OF_ORIENTATION_UNKNOWN" << endl;
            break;
        default:
            break;
    }
}

And it always prints OF_ORIENTATION_DEFAULT regardless of the device orientation. I think this is a bug since this worked properly on of_v0.9.0_ios version. ( I had to change some codes though as there were some bugs https://forum.openframeworks.cc/t/fixed-orientation-issues-on-ios8/20275)

If anyone has a solution to this, please let me know. I tested this on both of_v0.9.8_ios and the latest nightly build.

Thanks!

forum post : https://forum.openframeworks.cc/t/ios-cant-get-hardware-orientation-on-startup/26817

cuinjune avatar May 18 '17 07:05 cuinjune

I figured out what was causing it and how to fix it.

- The Problem It seems like ofiOSWindowSettings::setupOrientation was added in ofAppiOSWindow.h at some point since OF 0.9.x. (It didn't exist in 0.9.0) ofiOSWindowSettings::setupOrientation allows one to set the desired orientation on startup.

For example in main.mm, if you add settings.setupOrientation = OF_ORIENTATION_90_LEFT; It will make the app always start in a landscape orientation.

And since the default setting of ofiOSWindowSettings::setupOrientation is currently set to OF_ORIENTATION_DEFAULT, the app always starts in portrait mode regardless of the device orientation before launching the app.

This can be problematic if you want to create apps that support multiple orientations and it can cause a bad user experience since users should rotate the device on startup unnecessarily.

- The Solution My solution is to make use of OF_ORIENTATION_UNKNOWN which currently does nothing but just changes to OF_ORIENTATION_DEFAULT on startup. So if ofiOSWindowSettings::setupOrientation is set to OF_ORIENTATION_UNKNOWN, the app will no longer always start in OF_ORIENTATION_DEFAULT orientation but it will follow the device's current orientation on startup.

To achieve this, there are 3 parts to be fixed.

Firstly, in ofAppiOSWindow.h, in line 49, replace this setupOrientation = OF_ORIENTATION_DEFAULT; with this below setupOrientation = OF_ORIENTATION_UNKNOWN;

Secondly, in ofAppiOSWindow.mm, inside void ofAppiOSWindow::setup() {}, find and uncomment below.

//  if(settings.setupOrientation == OF_ORIENTATION_UNKNOWN) {
//       settings.setupOrientation = OF_ORIENTATION_DEFAULT;
//  }

And lastly, in ofxiOSAppDelegate.mm,

inside - (void)applicationDidFinishLaunching:(UIApplication *)application {}, find ofOrientation defaultOrient = ofGetOrientation(); And add this right below it

if (defaultOrient == OF_ORIENTATION_UNKNOWN) {
		
	if(bDoesHWOrientation) {
		// update the window orientation based on the orientation of the device //
		switch (iOrient) {
			case UIInterfaceOrientationPortrait:
				defaultOrient = OF_ORIENTATION_DEFAULT;
				break;
			case UIInterfaceOrientationPortraitUpsideDown:
				defaultOrient = OF_ORIENTATION_180;
				break;
			case UIInterfaceOrientationLandscapeLeft:
				defaultOrient = OF_ORIENTATION_90_RIGHT;
				break;
			case UIInterfaceOrientationLandscapeRight:
				defaultOrient = OF_ORIENTATION_90_LEFT;
				break;
		}
	} else {
		defaultOrient = OF_ORIENTATION_DEFAULT;
	}
	ofSetOrientation(defaultOrient);
}

And now if you want to test it, in main.mm, make sure you enable hardware orientation as below. settings.enableHardwareOrientation = true;

And in ofApp.mm, add this in setup() {} so you can print the orientation on startup

    switch (ofGetOrientation()) {
            
        case OF_ORIENTATION_DEFAULT:
            cout << "OF_ORIENTATION_DEFAULT" << endl;
            break;
        case OF_ORIENTATION_180:
            cout << "OF_ORIENTATION_180" << endl;
            break;
        case OF_ORIENTATION_90_LEFT:
            cout << "OF_ORIENTATION_90_LEFT" << endl;
            break;
        case OF_ORIENTATION_90_RIGHT:
            cout << "OF_ORIENTATION_90_RIGHT" << endl;
            break;
        case OF_ORIENTATION_UNKNOWN:
            cout << "OF_ORIENTATION_UNKNOWN" << endl;
            break;
        default:
            break;
    }

Now, if you run the app, it will always follow the current device's orientation on startup unless you manually set ofiOSWindowSettings::setupOrientation in main.mm

I tested this on both OF v0.9.8 and the latest nightly builds. I also tested this on both simulator and real device(iPad Air 2)

I would appreciate if someone can confirm this fix so it can be updated in OF.

cuinjune avatar May 20 '17 09:05 cuinjune

Maybe ofGetOrientation is unrelated to the physical device orientation, and only related to the result of ofSetOrientation function, which is the way you actually rotate the content on the screen if you want.

It is a little bit confusing since we have the physical device orientation and the content, and to confuse things further when you rotate the physical screen to left, content should be rotated to the right so things are still upright.

void ofApp::deviceOrientationChanged(int newOrientation){
	map <int, string> orientationString = {
		{ OF_ORIENTATION_90_LEFT, "OF_ORIENTATION_90_LEFT" },
		{ OF_ORIENTATION_90_RIGHT, "OF_ORIENTATION_90_RIGHT" },
		{ OF_ORIENTATION_180, "OF_ORIENTATION_180" },
		{ OF_ORIENTATION_DEFAULT, "OF_ORIENTATION_DEFAULT" },
		{ OF_ORIENTATION_UNKNOWN, "OF_ORIENTATION_UNKNOWN" },
	};
	cout << "deviceOrientationChanged : " << orientationString[newOrientation] << endl;
	
	if(newOrientation==OF_ORIENTATION_90_LEFT){
		ofSetOrientation(OF_ORIENTATION_90_RIGHT);
	}
	else if(newOrientation==OF_ORIENTATION_90_RIGHT){
		ofSetOrientation(OF_ORIENTATION_90_LEFT);
	}
	else if(newOrientation==OF_ORIENTATION_DEFAULT) {
		ofSetOrientation(OF_ORIENTATION_DEFAULT);
	}
	else if(newOrientation==OF_ORIENTATION_180) {
		ofSetOrientation(OF_ORIENTATION_180);
	}
}

dimitre avatar May 07 '22 02:05 dimitre

iPad app gives wrong touch coordinates when started upside-down (180); I implemented @cuinjune's mods above (OF-git, Xcode 14.2 targeting iOS16) and see a print of OF_ORIENTATION_180 (so detection works good from UNKNOWN state) but: I still get inverted touch coordinates. #7311

artificiel avatar Feb 09 '23 03:02 artificiel