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
Change how is Retina handled on iOS #3709
Conversation
I agree we should unify this now that we have the HDPI support in core. However, using a float to calculate the backbuffer width/height is less than ideal, especially since functions like glViewport/glScissor rely on integer pixel sizes. We'll need to find a way to get the backbuffer size properly in pixels, otherwise we'll run into off-by-one errors. |
Please also add an explicite note to CHANGES as this is a big API breaking change! |
The reason for floats is that iOS reports everything in doubles. If I am not mistaken, there is currently no legal way for it to report fraction values, so the code should always result in correct dimensions. However if it does indeed return fractions sometimes in the future, it may not break (that much) if we use doubles/floats as well. But I can amend it so it rounds first and then works in integers. I don't usually put CHANGES in PR because CHANGES change often and then it results in merge conflicts, but I can add it. |
Fixed merge conflicts. |
I have made a few changes:
I will add CHANGES when this gets approved, so it doesn't cause merge conflict. |
7cb4f4a
to
217aa9c
Compare
Had to revert that because it didn't play well with offsetting for status bar. |
Thanks for the PR @Darkyenus, I've pushed changes that break your PR's ability to be merged. If you could fix those by just pushing your changes to retina and squash to a commits I can merge. |
This is a breaking change, but makes the API consistent with core. Fixes libgdx#3789 (resize() being triggered with same dimensions) Fixes touch mapping on older iOS versions when screen is rotated
Squashed |
@cypherdare I know, but this probably won't get merged anyway, judging by recent events and the fact that this has been opened for quite some time, without any activity. |
Hey @Darkyenus, how would you recommend us build libgdx with your fix? Checkout your commit and build libgdx using ant or try to monkey patch it in somehow? |
@Istenes You have probably figured it already, but if not, here is how I would do it:
|
Thanks for the fix @Darkyenus, have received reports from several users using iOS 7 saying the app was unusable and this fixes it. Given that RoboVM is still the best choice for iOS backend I think this PR is important and should be merged. |
# Conflicts: # backends/gdx-backend-robovm/src/com/badlogic/gdx/backends/iosrobovm/IOSApplication.java # backends/gdx-backend-robovm/src/com/badlogic/gdx/backends/iosrobovm/IOSGraphics.java # backends/gdx-backend-robovm/src/com/badlogic/gdx/backends/iosrobovm/IOSInput.java
I've pushed changes to merge master to resolve conflicts. I think @Darkyenus did a good job with this PR and even if it's old it's still relevant. It improves consitency between backends, makes hdpi on the iOS backend closer to Apple's idea, it makes it more future proof and flexible and the code (as well as the ios configurations is cleaner. The drawback is that it does break backwards compatibility. Points and pixels are now different things so all apps that currently use I've tested it on my projects and everything seems to work but considering the nature of the changes, more testing would be great. |
I've tested the latest code with my project and it works so far. When we are going to change getWidth()/getHeight() anyway, maybe we should also merge the fix from #5814 |
I've been working on Split screen and have a PR ready but I'd rather wait until this is merged to avoid conflicts. If we merge this one now before 1.10.0 we can get both in while having them on SNAPSHOT for long enough for more people to test them. |
The problem with merging before 1.10 is that afaik 1.10 is not supposed to contain any breaking changes (see #6154 which is on hold for the same reason). |
Sorry if I've created confusion, I was assuming next release would be 1.10.0 (and that we would skip 1.9.12) considering the roadmap for end of October release. That's why I though it made sense to merge it now but If 1.9.12 is going to happen then I agree we should wait to 1.10.0. |
I think this is a bad change and I am not exactly sure it is working as intended.
For example I calculated the (freetype) font size by screen width, worked across all devices (android, ios, desktop) now I must calculate it with a special function for iOS. Other calculations that worked perfectly on all dives and resolutions have now some pixel shifts on iOS too. In the end iOS devices must now handled different from all other devices, before handling across all devices in libgdx was consistent. I don't care that this change aligns better with "Apples ideas" in regards to handling different screen resolutions. Apple ideas for resolution handling are just bad. Libgdx should not implement such vendor specialized design ideas but stay consistent across all devices. |
That is not correct. For example, you should just calculate your freetype font size based on backbuffer size on all platforms.
Exactly this was the attempt here. Libgdx core supports the difference between logical and physical screen size for a long time now. Unfortunately, only Lwjgl3 backend made use of this. Now, another step was done to support it on iOS. GWT will follow for sure. |
That is of course true but. And I already implemented this. But if I calculate screen positions for some objects with backbuffer size (or the screen width) I could used this position regardless of the device. Now I must scale it down for iOS, before 1.9.12. I could just use the same calculated value for all devices.
I can see why some developer might think this is a change for better if they never calculated their screen designs to fit the real device screen perfectly but were satisfied with approximate values (that look way worse in my opinion). The libgdx logical and physical screen size and the iOS scaling are some different things. For example I never used libgdx scaling anyway (that looks often weird and cheap). My games just use the real screen sizes on all devices and it worked perfectly. Now with 1.9.12. virtual screen sizes are enforced with libgdx on iOS and it will makes headaches for all developer who use native screen sizes in their apps. Because the upscaling and calculation methods must now have special calculations for iOS otherwise it will result in pixel shifts. There should at least be an option to use the physical resolution on iOS as it was before. Why take away such important options from developers? |
You mention 2 different issues here. The first one seems not to be a problem, as @MrStahlfelge has said, using backbuffer size to determine the real size of the screen to load/generate the correct assets is the way to go. Regarding the second issue. If I've understood correctly, your game has a mapping of 1 world unit -> 1 pixel which means you use (or do the same as) a |
Its much easier and give games a more high-quality look, anyway:
Before 1.9.12 I could just use native resolution for all devices and could position objects accordingly. Now I have to include extra calculations for iOS to the virtual resolutions. This change is fine for people who don't care about native resolutions. An option to just use native resolution on iOS as before would be appreciated. |
It is definitely not easier to have a 1 pixel - 1 world unit mapping than to use predictable bounded world sizes once you understand how Viewports work. And the quality look is (or should) be independent from the viewport you use.
Caring about native resolutions to make sure your game looks perfect on all devices (which is a good thing) is different from having to care about them every time you position an object on your game world. You have not explained the exact issue you are facing regarding "pixel shifts" or if the workaround I provided (that requires changing 1 single line) works for you. My advice is we move this conversation to the #ios channel on Discord where, with more information, we can investigate further whether there's a use case in which this change could be limiting or maybe you discover a better way to deal with different device resolutions. |
I somewhat agree with @Trurl101. My app (not a game) also uses a 1:1 mapping. The UI elements are sized using the current display density so they are physically the same size on all devices, platforms and OS scaling. |
After this change the behavior on iOS and on lwjgl3 is the same. If you are experiencing different behavior, you are introducing it yourself or you aren't using proper APIs for the task (getWidth/getBackBufferWidth). If you insist on using the old behavior, just replace all calls to getWidth with calls to getBackBufferWidth (and Height, of course), then you can handle the scaling yourself. However if you do and don't match what getWidth gives you, your app won't feel native as it will have different scaling from every other application on the OS. As obigu mentioned, Discord is the place for these discussions, unless you think that there is a real bug. |
That doesn't help. If I have have a backbufferwidth of 800px and libgdx width of 444 I must calculate the new position. On all other platforms I can just use the "real" native position.
Is the future of libgdx to not support development for native resolutions anymore? If the libgdy maintainer think only virtual resolutions are the way to go it will be a big change. I think libgdx should be produce the same results on all platforms if you use the same code, but with this change in 1.9.12. iOS development is practically broken and force developers to change the code often in a big way. There should be implemented some kind of config setting developers could use to turn on "old" but better/more consistent behaviour for iOS development. |
The maintainers are part of the community, and the community is what drives the project. The PR was open for 4 years with no one from said community chiming in and telling it is a bad idea or that it should be configurable. Everyone throwing in the effort to test this had zero problems. If you want to participate in decisions what is merged, take part of the process beforehand. Most PRs are left open before merging after approval for a time for a reason - this reason is to give others the chance to give input. |
@davidgiga1993 reported an issue on @Trurl101 I'm not sure what your issue is but, unless you report what you consider is a bug and be a bit specific we won't be able to help you here. Again, we will happily help you on Discord #ios channel. |
I guess the issue @Trurl101 is having is that the units now are less precise when positioning objects on the screen and you would have to manually adjust it with additional computations (to compensate for the loss of precision). If less pixels is better (e.g. 414 vs. 1242), then why do all screen manufacturers always try to increase the number of pixels in the screen? They always strive to increase pixel count and density. I wonder if it's better to have 414 pixels vs 1242, why are not screens produced with just 414 pixels and why would we ever need screens with 1242 pixels? |
I don't think you get the point of this PR. There is a difference between logical (414x 896) and hardware/physical resolutions (1242x2688). The iOS backend now properly reports those sizes in the same way the four other backends already do. If you require the "real" resolution (1242x2688 in this case), it is as simple as changing |
You may want to always work with exact integers for positioning your objects and have a 1 world unit - 1 screen pixel, that's ok, but that doesn't mean you lose precision capability (as in the sense of not being able to place stuff with precision) when using a smaller points/logical pixels world size, positions don't have to be integers. If that's the case, if your project works in a world with a 1 world unit - 1 screen pixel mapping, you can keep the same behaviour as you had before by using the |
Thanks for the hint. I implemented this, and it seems to work. |
In the LWJGL3 adapter we can set As it is, it is debatably incorrect to claim that this aligns iOS with the behaviour of the other backends. Android is always raw pixels regardless of screen density, as far as I understand, and LWJGL3 allows one to set the HDPI mode. I'm happy to attempt to add this HDPI mode to iOS, but would be good to know beforehand if the maintainers are dead against it. :) |
@JoelOtter Sure, I think it'd be a good addition! |
This is a breaking change, but makes the API consistent with the core API.
It gets rid of the
configuration.displayScaleIf
fields in favor of correctgetWidth/Height
andgetBackBufferWidth/Height
implementations. This makes development of cross platform hi-dpi applications much easier.Input and
getW/H
previously returned pixels, now it returns points.