[iOS] What is the correct way to handle orientation changes

Discussion of issues specific to mobile platforms such as iOS, Android, Symbian and Meego.
Post Reply
simedj
Goblin
Posts: 262
Joined: Fri Nov 18, 2011 6:50 pm
x 3

[iOS] What is the correct way to handle orientation changes

Post by simedj »

I'm running Ogre 1.9 and whichever initial orientation is selected, it works fine. But as soon as you change the orientation, everything gets squished/squashed and input events appear messed up too.

I'm using a very simple iOS-Ogre setup where I create a RenderWindow manually.

I have seen threads in the past about this, but can't remember if Ogre is supposed to handle this automatically, or if I need some additional event handler to do it. The most detailed thread I found was 2-3 years old and I know iOS support has improved a LOT since Ogre 1.7 :)

Thankyou for any help.
Looking to find experienced Ogre & shader developers/artists. PM me with a contact email address if interested.
User avatar
masterfalcon
OGRE Team Member
OGRE Team Member
Posts: 4270
Joined: Sun Feb 25, 2007 4:56 am
Location: Bloomington, MN
x 126
Contact:

Re: [iOS] What is the correct way to handle orientation chan

Post by masterfalcon »

Interesting. I haven't seen that happen in a long time. Are you using GL ES 1 or 2? Even with a manually created window the render buffers should get recreated with the proper dimensions and input should also be correct. How old are the dependencies that you are using?
simedj
Goblin
Posts: 262
Joined: Fri Nov 18, 2011 6:50 pm
x 3

Re: [iOS] What is the correct way to handle orientation chan

Post by simedj »

Built within the last few weeks - I finally switched from the supplied pre-built dependencies to building my own from source too.

Actually, I haven't tested this since doing that...

...aha. Now I do see the Ogre viewport toggle. It's a bit ugly as it rotates and stretches, then pops back afterwards, but it is working.

However my GUI stuff is still being messed up. Now this isn't Ogre's responsibility - you're off the hook ;) - but I still need to fix it. So I think I still need to catch some event and handle it, either an iOS event or an Ogre one. How is Ogre internally handling this - catching an orientation change notification and translating it to a window-resize action maybe? If you can tell me how Ogre is automatically handling orientation changes maybe I can dig through the code to see myself, but I'd still appreciate any higher-level advice.

Just for background, I'm using MyGUI for my GUI stuff as this is cross-compiling Win32 and iOS. I checked and on Win32 I can resize my window without this problem so either Ogre isn't treating them the same, or I have inadvertently coded different behaviour on my side.
Looking to find experienced Ogre & shader developers/artists. PM me with a contact email address if interested.
User avatar
masterfalcon
OGRE Team Member
OGRE Team Member
Posts: 4270
Joined: Sun Feb 25, 2007 4:56 am
Location: Bloomington, MN
x 126
Contact:

Re: [iOS] What is the correct way to handle orientation chan

Post by masterfalcon »

We listen for shouldAutorotateToInterfaceOrientation in our ViewController which in turn calls setNeedsDisplay. This tells views to redo their layout, at this point layoutSubviews is called, which does the actual GL context resizing.
simedj
Goblin
Posts: 262
Joined: Fri Nov 18, 2011 6:50 pm
x 3

Re: [iOS] What is the correct way to handle orientation chan

Post by simedj »

So if I need to do something additional - can/should I also be handling shouldAutorotateToInterfaceOrientation? I'll dig into the code when on the right computer but I think my biggest question is: does all of this end up with my RenderWindow acting as if it has been resized - i.e. I can catch this happening through rendersystem-independent Ogre listeners?
Looking to find experienced Ogre & shader developers/artists. PM me with a contact email address if interested.
User avatar
masterfalcon
OGRE Team Member
OGRE Team Member
Posts: 4270
Joined: Sun Feb 25, 2007 4:56 am
Location: Bloomington, MN
x 126
Contact:

Re: [iOS] What is the correct way to handle orientation chan

Post by masterfalcon »

Yeah, you probably can. You could create a RenderTargetListener and check the size at the beginning or ending of each frame.
simedj
Goblin
Posts: 262
Joined: Fri Nov 18, 2011 6:50 pm
x 3

Re: [iOS] What is the correct way to handle orientation chan

Post by simedj »

But it won't fire a window-resized event - it doesn't treat an orientation change like simply resizing? That would be kind of ideal :)
Looking to find experienced Ogre & shader developers/artists. PM me with a contact email address if interested.
User avatar
masterfalcon
OGRE Team Member
OGRE Team Member
Posts: 4270
Joined: Sun Feb 25, 2007 4:56 am
Location: Bloomington, MN
x 126
Contact:

Re: [iOS] What is the correct way to handle orientation chan

Post by masterfalcon »

What window resized event are you referring to?
simedj
Goblin
Posts: 262
Joined: Fri Nov 18, 2011 6:50 pm
x 3

Re: [iOS] What is the correct way to handle orientation chan

Post by simedj »

I'm meaning Ogre::WindowEventListener, I think.
Looking to find experienced Ogre & shader developers/artists. PM me with a contact email address if interested.
simedj
Goblin
Posts: 262
Joined: Fri Nov 18, 2011 6:50 pm
x 3

Re: [iOS] What is the correct way to handle orientation chan

Post by simedj »

OK, so from looking at MyGUI code and from their own sub-forum (http://www.ogre3d.org/addonforums/viewt ... 17&t=30089) it would seem that MyGUI relies on Ogre::WindowEventListener events, specifically windowResized(Ogre::RenderWindow* _window), to know when it needs to update its layout, MyGUI's implementation looks like this in case that's useful:

Code: Select all

	void OgreRenderManager::windowResized(Ogre::RenderWindow* _window)
	{
		if (_window->getNumViewports() > mActiveViewport)
		{
			Ogre::Viewport* port = _window->getViewport(mActiveViewport);
#if OGRE_VERSION >= MYGUI_DEFINE_VERSION(1, 7, 0) && OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0
			Ogre::OrientationMode orient = port->getOrientationMode();
			if (orient == Ogre::OR_DEGREE_90 || orient == Ogre::OR_DEGREE_270)
				mViewSize.set(port->getActualHeight(), port->getActualWidth());
			else
				mViewSize.set(port->getActualWidth(), port->getActualHeight());
#else
			mViewSize.set(port->getActualWidth(), port->getActualHeight());
#endif

			// обновить всех
			mUpdate = true;

			updateRenderInfo();

			onResizeView(mViewSize);
		}
	}
However, from testing it appears Ogre::WindowEventListener::windowResized simply isn't called in an iOS orientation change event.

Is that how it has always been, or has something changed here - because it looks like the MyGUI code was written with at least some consideration of orientation events in mind?
Looking to find experienced Ogre & shader developers/artists. PM me with a contact email address if interested.
simedj
Goblin
Posts: 262
Joined: Fri Nov 18, 2011 6:50 pm
x 3

Re: [iOS] What is the correct way to handle orientation chan

Post by simedj »

Looking at the GLES2 subsystem, I think the key function is in OgreEAGL2View.mm:

Code: Select all

- (void)layoutSubviews ()
{
<snip>

        // Get the window size and initialize temp variables
        unsigned int w = 0, h = 0;
        unsigned int width = (uint)self.bounds.size.width;
        unsigned int height = (uint)self.bounds.size.height;

        if (UIDeviceOrientationIsLandscape(deviceOrientation))
        {
            w = std::max(width, height);
            h = std::min(width, height);
        }
        else
        {
            h = std::max(width, height);
            w = std::min(width, height);
        }

        width = w;
        height = h;

        // Resize the window
        window->resize(width, height);
        
        // After rotation the aspect ratio of the viewport has changed, update that as well.
        if(window->getNumViewports() > 0)
        {
            Ogre::Viewport *viewPort = window->getViewport(0);
            viewPort->getCamera()->setAspectRatio((Real) width / (Real) height);
        }
This logic looks very similar to what I do in my windowResized() event handler on Windows, where I update the camera aspect ratio. However It means I don't get a chance to do other stuff at the same time.

It does look like Viewport::Listener::viewportDimensionsChanged() should be called though from inside window->resize() - I'll have to check this out. Maybe this is an option.
Looking to find experienced Ogre & shader developers/artists. PM me with a contact email address if interested.
Post Reply