Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Landscape Support for WP8 #1227

Closed
tomspilman opened this issue Jan 24, 2013 · 64 comments
Closed

Landscape Support for WP8 #1227

tomspilman opened this issue Jan 24, 2013 · 64 comments
Labels
Windows 10 UWP UWP platform

Comments

@tomspilman
Copy link
Member

We need to implement landscape left/right (also upside down portrait) support for Windows Phone 8.

In XNA this was done for the user automatically. An oriented render target was provided for rendering and all input was rotated.

In Windows 8 Store apps it is also done automatically for you by default as well. You get an oriented render target and input is rotated. The docs do however provide some additional insight when using automatic rotation:

"It performs a redundant full screen copy operation."
http://msdn.microsoft.com/en-us/library/windows/apps/jj262112.aspx

So this is telling us automatic works, but it is costing us some fillrate doing a copy.

This means that even on WinRT there is some savings to not using automatic rotation. They recommend what has been mentioned before... append the rotation to your projection matrix. Here is a good example of implementing this for WP8:

http://www.catalinzima.com/2012/12/handling-orientation-in-a-windows-phone-8-game/

Where does this leave MonoGame? I think we have to do two things:

1 - Provide the automatic method using an offscreen render target with an efficient copy.

This would not only be a feature for WP8, but we can possibly use it to also support scaling of the backbuffer on Android as well.

2 - Add support for matrix level rotation.

We can add some flag in GraphicsDevice or GraphicsDeviceManager that hints to the system that we want to opt-out of automatic rotation. We would expose something like GraphicsDevice.ScreenRotationMatrix. Under the hood stock Effects and SpriteBatch would use this automatically... so most games won't care. If you are using a custom effect you would have to add this explicitly into your projection.

These two features should cover us no matter the platform moving forward with minimal pain to end users.

@KonajuGames
Copy link
Contributor

Android doesn't have the same issue, I believe. We get a landscape
framebuffer when requested.

@tomspilman
Copy link
Member Author

Ah... i was confused. It is the size of the framebuffer... which on Android you cannot control. This feature could still play a part in that if we wanted. I fixed the description.

@Nezz
Copy link
Member

Nezz commented Jan 28, 2013

I'm fine with it. This plus the tiny bit of work to rotate the touch and WP8 may become usable.

@tomspilman
Copy link
Member Author

Should we try to put this under GraphicsDevice directly? Or should we develop a new SwapChain abstraction and put this code in there?

@Nezz
Copy link
Member

Nezz commented Jan 28, 2013

GraphicsDevice seems to be more future proof to me.

@motek80
Copy link

motek80 commented Feb 16, 2013

Hi guys,
Could you share please the current status of this issue? My cool WP8 MonoGame game must have a landscape mode, and I prefer to use your solution instead of reinventing a wheel...

Thanks

@Nezz
Copy link
Member

Nezz commented Feb 16, 2013

There is no progress made in MonoGame so far. #1336 allows you to detect if you should manually correct orientation and apply a rotation matrix.

@tomspilman
Copy link
Member Author

FYI. We're starting to implement this in the office. I figure in a few days we'll have a pull request in for the matrix method.

@RayBatts
Copy link

Work for this has started in #1445

@SimonDarksideJ
Copy link
Contributor

Any update on this?, the associated PR was pulled.

@deluksic
Copy link

deluksic commented Jul 5, 2013

Any updates on this?

@totallyeviljake
Copy link
Contributor

I found this which was very informative about the landscape rendering problems on WP8:

http://www.catalinzima.com/2012/12/handling-orientation-in-a-windows-phone-8-game/#more-1005

Maybe we can implement something similar to this technique in MonoGame. I think Ray Batts started that once about 5 months ago.

@totallyeviljake
Copy link
Contributor

Then there is this discussion where Alexander claims it works for him:

https://monogame.codeplex.com/discussions/439446#post1065608

@tomspilman
Copy link
Member Author

What stopped @RayBatts and I with the orientation work was the realization that you cannot hide geometric orientation (using a matrix to rotate rendering) within the existing API. There are a bunch of small issues including knowing not to rotate when rendering to offscreen render targets, but the biggest is that custom Effects follow no rules. So you can have a custom effect with no input matrices at all... there is no way for us to inject any orientation changes in this case.

The only way for this to work consistently is to expose the orientation matrix as a part of the public API. It would then be the users responsibility to multiply the orientation matrix into their projection in each of their Effects... custom or not. Note that input rotation can still be internalized.

This API can be used on all the platforms... even Win8 where orientation can be automatic. This is because automatic orientation depends on the OS doing a copy of your back buffer to rotate it. This copy does cost fillrate.... so depending on your game... it might be a win to render rotated from the start.

@totallyeviljake
Copy link
Contributor

Thanks @tomspilman - I read through all of Ray's posts as well. I think Alexander's change at least gets us to the rabbit hole.

Weird is that on WP8, the Guide works properly in landscape mode, even through the game renders in portrait!!! There's something in that deep windows core library that we're not able to access ...

@tomspilman
Copy link
Member Author

deep windows core library that we're not able to access

With the little bit of talk I've had with WP8 engineers it seemed to me that it was something they simply omitted because they thought that doing your own rotation via matrix transforms would be easy and faster.

Performance won over convenience in the WP8 team.... while the Win8 team chose to support both.

@totallyeviljake
Copy link
Contributor

Weird part is that all of our landscape mode WP7 games render perfectly on WP8 with no changes. So there is something in there, either in the baggage from Microsoft XNA 4, or something hidden in WP8 that the phone people don't want to discuss.

@tomspilman
Copy link
Member Author

So there is something in there

I'm sure it is there... they probably consider it legacy support for XNA titles.

It is just some engineer or group of engineers in the WP8 group that is adamant that render target rotation is the "worst performance sin evah" and refuses to expose the feature because "you can just rotate your projection".

My guess is the feature will re-appear as WP8 is more unified with Win8 development.

@totallyeviljake
Copy link
Contributor

I agree with your guess. I wonder if it will appear in 8.1?

@tomspilman
Copy link
Member Author

I'm sure it will appear the second we fix MonoGame to work around it. ;)

@totallyeviljake
Copy link
Contributor

at least we share the same sense of humor about Microsoft's WP team. most definitely.

@Nezz
Copy link
Member

Nezz commented Jul 9, 2013

As the moment there are two ways to achieve proper orientation:
The easy way: Use DrawingSurface instead of DrawingSurfaceBackgroundGrid. Rotation works with that. (The method @totallyeviljake linked).
The hard way: Use a transformation matrix to draw. That matrix can also be used to transform the touch input according to the rotation.

@tomspilman
Copy link
Member Author

The easy way: Use DrawingSurface instead of DrawingSurfaceBackgroundGrid.

I've seen mention of that technique.

DrawingSurface is meant to be used when you want to layer XAML and DirectX stuff together. That is a nice feature, but it comes at the cost of some extra work to composite the DirectX in with the XAML. I suppose this cost should be no more than a single copy of the DrawingSurface into the back buffer.

Has anyone done any measurement of the overhead of that technique?

@KonajuGames
Copy link
Contributor

I used DrawingSurface to get TY running on WP8 with no code changes. It
still runs faster on the Nokia 920 than on Surface RT.​

@totallyeviljake
Copy link
Contributor

i put up a PR on cocos2d-xna to use DrawingSurface in our tests and in our templates. Once @kjpou1 merges that for us, then we'll run some tests on my WP8 device and WINRT device to see how it goes. I trust that @Nezz and @KonajuGames have done their homework on this already.

@totallyeviljake
Copy link
Contributor

wait, @KonajuGames - When is Ty coming out? I just searched my WP8 device and no Ty on the xbox live market. is it on some other market?

@KonajuGames
Copy link
Contributor

It's coming out for Windows 8, but we did a test to see how well it ported
to WP8. No planned release on that platform yet.​

@totallyeviljake
Copy link
Contributor

🎱

Ok, so to use the changes from Alexander, you have to make the Xaml change shown in Alexander's post and you have to change the XamlGame code:

        DrawingSurfaceBackgroundGrid drawingSurface = (DrawingSurfaceBackgroundGrid)page.Content;

changes to

         DrawingSurface drawingSurface = (DrawingSurface)page.Content;

Then you need to change the handler setup to be:

        // Hookup the handlers for updates and touch.
        drawingSurface.SetContentProvider(new SurfaceUpdateHandler(game));
        drawingSurface.SetManipulationHandler(new SurfaceTouchHandler());

@totallyeviljake
Copy link
Contributor

My comment is incorrect. Changes to XamlGame are more extensive for this to work. SurfaceUpdateHandler has to change as well.

@azchohfi
Copy link
Contributor

azchohfi commented Jul 9, 2013

I think my solution works just fine, but I haven't tested it with Touches, so I'm not sure if it will rotate input, but I suspect it won't...

@totallyeviljake
Copy link
Contributor

the current version of MonoGame and @azchohfi changes work just fine (develop branch). I have cocos2d-xna working with it on my Nokia Lumia 820 ...

@SimonDarksideJ
Copy link
Contributor

@totallyeviljake just to clarify what is the mechanism currently employed in the develop branch (so I can test with the new samples)

@totallyeviljake
Copy link
Contributor

@DDReaper I am using this in the GamePage.xaml:

<Grid x:Name="LayoutRoot" Background="Transparent">
    <DrawingSurface x:Name="XnaSurface"/>
    <MediaElement></MediaElement>
</Grid>

Then using just the develop branch of MonoGame, with no changes.

In Cocos2D-XNA, here is the solution to build and run if you want to see it work for yourself:

https://github.com/totallyevil/cocos2d-xna/blob/master/tests/cocos2d-xna.Tests.WindowsPhone.sln

I have not tried any of the WP8 samples yet.

@totallyeviljake
Copy link
Contributor

@azchohfi I tested touches and they worked. Our tests work as expected on the device.

Thanks @azchohfi , @tomspilman , @KonajuGames , and @Nezz for your hard work on WP8 and the DX version of MonoGame.

@SimonDarksideJ
Copy link
Contributor

@totallyeviljake ok, I'll give that a whirl. Had to add those elements for the current build but at last test it didn't display landscape. Will test again since I updated my local repo today.
P.S.
Were in the process of creating some new samples 💃

@SimonDarksideJ
Copy link
Contributor

Quick question, is DrawingSurface different to DrawingSurfaceBackgroundGrid ?

@Nezz
Copy link
Member

Nezz commented Jul 9, 2013

DrawingSurface: You draw into a rendertarget that is drawn on the screen (over some XAML controls, under some other if you wish). It rotates itself but increases the fillrate by one due to the rendertarget.
DrawingSurfaceBackgroundGrid: You draw into the backbuffer, thus it is not possible to draw it over XAML controls. No extra cost, does not rotate itself.

@SimonDarksideJ
Copy link
Contributor

Great, changing the default template DrawingSurfaceBackgroundGrid to the example you detail @totallyeviljake worked and landscape is working in the new sample.

Can the DrawingSurfaceBackgroundGrid be updated to work? , if not then the Windows Phone template will need to be updated with that fix, which if need be I don't mind doing

@totallyeviljake
Copy link
Contributor

@DDReaper I don't think the background grid version works well, but that came out of a comment from @Nezz which may have been outdated (see codeplex discussion). I could not get the background grid to work for me.

We are using this new xaml in all of our templates in cocos2d-xna.

@tomspilman
Copy link
Member Author

So should we simply update the WP template in MonoGame to use DrawingSurface then? If the cost is cheap and solves the issue of rotation then maybe we should.

The burden to figure things out is for people that have portrait only game that find they need more performance. They can then switch back to DrawingSurfaceBackgroundGrid if they like.

@totallyeviljake
Copy link
Contributor

I agree with @tomspilman, maybe there is a way to have a Portrait XamlGame and a Landscape XamlGame ??

Then those games that do both, well ... TILT

@tomspilman
Copy link
Member Author

maybe there is a way to have a Portrait XamlGame and a Landscape XamlGame ??

I'm saying something simpler.

Change the WP template to use DrawingSurface which works both in portrait and landscape.

Forget DrawingSurfaceBackgroundGrid and its portrait only behavior.

@totallyeviljake
Copy link
Contributor

ha! even better.

@azchohfi
Copy link
Contributor

azchohfi commented Jul 9, 2013

I totally agree, its easier for the user and if he wants peformance, I think the template should have a commnet about that.

@SimonDarksideJ
Copy link
Contributor

Ok I'll update the template and submit a pr for it.

To be honest the majority of games I've seen are mostly landscape anyway, so its better to use the 80/20 rule here.

Will ensure there is a comment to do it the other way as well

-----Original Message-----
From: "Alexandre Zollinger Chohfi" notifications@github.com
Sent: ‎09/‎07/‎2013 19:20
To: "mono/MonoGame" MonoGame@noreply.github.com
Cc: "Simon (Darkside) Jackson" darkside@zenithmoon.com
Subject: Re: [MonoGame] Landscape Support for WP8 (#1227)

I totally agree, its easier for the user and if he wants peformance, I think the template should have a commnet about that.

Reply to this email directly or view it on GitHub.

@SimonDarksideJ
Copy link
Contributor

Submitted #1857 which has an updated project template to use the new pattern. includes a commented out section for the original way.

Note, in testing you can use either Landscape or Portrait on a page but NOT both, setting the supported orientations to LandscapeOrPortrait causes the viewport in landscape mode to become stretched to double the width of the screen ???

New template tested and working fine in the new Platformer2D sample

@tomspilman
Copy link
Member Author

setting the supported orientations to LandscapeOrPortrait causes the
viewport in landscape mode to become stretched to double the width
of the screen ???

Probably just a bug in orientation change detection. It should totally be possible to fix that.

@Gmotagi
Copy link

Gmotagi commented Jul 9, 2013

So what does

game = XamlGame.Create("", XnaSurface);

In the code behind change to as sCreate no longer takes a DrawingSurfaceBackgroundGrid ?

@totallyeviljake
Copy link
Contributor

no change required. DrawingSurfaceBackgroundGrid and DrawingSurface will both inherit from the same ancestor. It's their runtime that makes the landscape work here.

@Gmotagi
Copy link

Gmotagi commented Jul 9, 2013

Error 3 Argument 2: cannot convert from 'System.Windows.Controls.DrawingSurface' to 'System.Windows.Controls.DrawingSurfaceBackgroundGrid'

That's with just changing the xaml ?

Should this work with just the latest master branch as thats what i'm using.

@totallyeviljake
Copy link
Contributor

Master? no, develop.

@Nezz
Copy link
Member

Nezz commented Jul 9, 2013

@DDReaper I don't think the background grid version works well, but that came out of a comment from @Nezz which may have been outdated (see codeplex discussion). I could not get the background grid to work for me.

The background grid works fine. We have a game live with it (we do the rotation and handle the touch ourselves).

@SimonDarksideJ
Copy link
Contributor

Confirmed the DrawingSurfaceBackgroundGrid does work fine so long as you only want portrait. If you want landscape as well then you'll have to swap the DrawingSurfaceBackgroundGrid for a standard grid and use @totallyeviljake sample above (now also in the new default template)

@deluksic
Copy link

I just downloaded the develop-branch to be able to have landscape and the template doesn't work on HTC8x as is. I get a black background, fps counter says 0, and got some localizedstrings exception.

edit: when I switch the drawingsurface to drawingsurfacebackgroundgrid, it works

@SimonDarksideJ
Copy link
Contributor

Hmm, well I'll run the Platformer sample on the wifes HTC8s when I get a chance. Does sound odd it works on some devices but not others..

@Nezz
Copy link
Member

Nezz commented Mar 9, 2014

This can be closed as my changes were merged a couple of months ago.

@KonajuGames
Copy link
Contributor

Closing.

alxwest pushed a commit to alxwest/MonoGame that referenced this issue May 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Windows 10 UWP UWP platform
Projects
None yet
Development

No branches or pull requests

10 participants