Android, unwanted margin on LG G3

edited April 2015 in Help request
Hi everyone,

I've been trying to fix a little issue I'm having with an Orx game running on an LG G3(Android 5.0, 2560x1440). Note that I've run the same game on two other devices (Galaxy Note 10.1:[4.1.2], HTC Desire S:[2.3.5]) and they don't have this issue.

The problem is that the orx surface view seems to leave a 84pixel margin on the left and right sides on landscape orientation, and I can't remove that margin in a reasonable manner. I've been fighting with that issue for a few days now, so I've gained some insight into it:

First of all, I've noticed that when the orx activity is first created, it's for some reason created with those margins, and they're immediately removed, but at that point, orx has already initialized itself. I've tried to log the width of the SurfaceView at various times and here's what happens:

When the surface is first created: 2392 px
In my native Init function: 2392 px
Very shortly afterwards: 2560 px

I've tried to remove the margins in the dimens.xml file (both of them) and it doesn't help. I've discovered something that DOES help; inside src/res/values/themes.xml, when you change the parent of MyStyle from @android:style/Theme.NoTitleBar.Fullscreen to @android:style/Theme.NoTitleBar, the visual margins disappear, but there's still something fishy about it: Even though the margins disappear, the SurfaceView still starts out being 2392px wide and inside my native Init function, orxViewport_GetSize still reports a width of 2392!

Another oddity I've noticed while working on this issue is that the margin magically disappeared on a random run (without the MyTheme trick). I couldn't replicate that run, but I'm definitely sure that it happened. My guess is that on that particular run, the starting of the orx thread was delayed just enough to catch the correct SurfaceView size.

Another important thing to note is when I set the orientation of the activity to be portrait, I get those same margins at the top and bottom (so they're physically at the same place)

My feeling about all this and the magic 2392 number is that just when the activity is first created, Android adjusts the view sizes taking into account a title bar, or maybe a status bar, but then it immediately removes it, which is already too late for the orx thread by that time.

I'd be glad if you could give me a hint about what might be going on, and how I might debug/fix it.

Thanks

Comments

  • edited April 2015
    Lydesik will probably give you a better answer than me, but for a work around, I think you should be able to call orxDisplay_SetVideoMode() after a short delay. It will query the device again and you should hopefully end up without that border.

    Something like this should work:
    orxDISPLAY_VIDEO_MODE stMode;
    
    orxDisplay_SetVideoMode(orxDisplay_GetVideoMode(0, &stMode));
    
  • edited April 2015
    Great! Thanks a lot iarwain, I don't have the LG G3 lying around right now, but I'm quite confident you've solved my problem.

    In fact, my problem might not have been the Video mode to begin with (or video was a part of my problem, I'll write again when I try the solution on the problematic G3), but trying your suggestion made me realize that my main problem was the camera frustum. Currently, in my .ini file, the camera is configured as:
    FrustumWidth  = @Display.ScreenWidth
    FrustumHeight = @Display.ScreenHeight
    

    Where, [Display] is configured to have a certain width and height for the desktop build, but the android build does not specify them, and I guess they're automagically provided by the platform. This situation worked fine until the LG G3 case, where the Display parameters change after initialization. Now, I haven't tested whether the video mode is automatically updated whenever the SurfaceView gets resized on the Android side (if it doesn't I'll use your snippet), but the camera frustum doesn't get adjusted automatically for sure.

    Up until this issue, I never had to worry about the camera frustum, as the above snippet from the .ini file worked fine.

    I'll post my final solution and the details here when I get my hands on the G3 again.

    Thanks a lot :)
  • edited April 2015
    If you base your android build on the demo, in the Activity there is some code to enable IMMERSIVE_MODE.

    This is to allow a fullscreen experience. The issue is that, indeed, the SurfaceView is resized after orx has inited the display.

    Anyway you need to have some code to optimize the frustum aspect ratio versus the SurfaceView aspect ratio to remove the letterboxing, because on android devices have different aspect ratio.

    to fix the frustum when the SurfaceView is resized at runtime, just install a EventHandler like this
    static orxSTATUS orxFASTCALL EventHandler(const orxEVENT *_pstEvent)
    {
      // Depending on event type
      switch(_pstEvent->eType)
      {
      case orxEVENT_TYPE_VIEWPORT:
      {
        if(_pstEvent->eID == orxVIEWPORT_EVENT_RESIZE)
        {
          Game::GetInstance().UpdateFrustum();
        }
        break;
      }
      default:
        break;
      }
      return orxSTATUS_SUCCESS;
    }
    

    Also, I highly advice to fix your Camera Frustum in your config file.

    Hope this will help
  • edited April 2015
    Thanks a lot lydesik,

    lydesik wrote:
    to fix the frustum when the SurfaceView is resized at runtime, just install a EventHandler like this

    I've tried this and the event handler is indeed called when the SurfaceView is resized to the full width. But I've also noticed that orxDisplay_SetVideoMode still needs to be called, otherwise the unwanted margins remain (even if I update the camera frustum). When I query the video mode width and the viewport width, they return the full width of the device screen. But even if I set the camera frustum to that width, I get the margins unless I call orxDisplay_SetVideoMode as well.

    Also, I highly advice to fix your Camera Frustum in your config file.
    Can you elaborate a bit more on that? How can I fix the frustum when I don't know the device's resolution? The way I do it currently is that I set the frustum to be the full viewport size and then I adjust the size of the scene using the Camera's zoom. Is there a better way to handle this? I actually don't see the point of the camera frustum.
    Hope this will help
    Sure it did thanks again :)
  • edited April 2015
    weird that you need to call orxDisplay_SetVideoMode to get rid of the margins.

    Here is how I do it.

    While developing the game on PC, i choose a target resolution let's say (1280x720). That is my MainCamera frustum.
    FrustumWidth  = 1280
    FrustumHeight = 720
    

    Usually on PC i also set the Display size to 1280x720, (or at least i keep the same aspect ratio).

    I install my EventHandler, and in my UpdateFrustum function, I adapt the Frustum to make it match the actual Display ratio, not the size of the Display.

    Let's say the Screen size is 1500x800.

    The frustum will be (1280x844)

    844 = 720/1280*1500
  • edited April 2015
    Thanks for the explanation, as I said, I view the camera frustum as a redundancy (or you could say that the camera zoom is a redundancy), so I set the frustum to be the same as the viewport, and adjust the scene size with the zoom. Though, now I realise that this approach might break down when one wants to use the 3D parallax effect, as zoom and frustum will probably interact differently with depth.
  • edited April 2015
    yes, they have the same effect (changes the area of the world rendered on screen)

    but their usage is different.

    frustum (except for the Android case), is mostly static, you dont change it at runtime.

    zoom is a different story. If I want to add a zoom FX, playing with frustum is overkill. and if you tweak the Zoom to "fix" the frustum size, you ends up with a unknown zoom value when you want to apply zoom FX...
Sign In or Register to comment.