How to keep consistent 2D coordinates in a 3D world having different resolutions

This document aims to document how to support 2D objects positions in a 3D engine supporting different resolutions and aspect ratios.   This is the solution I have currently adopted in our PATRIA 3D engine and it is not for sure the best solution available there.

 

In such conditions it is quite difficult to position objects that perfectly fit your scene such as the game’s HUD (for instance life icons, energy bars etc). I am sure there are multiple ways to achieve the wanted result but this is the way I have implemented in my PATRIA engine. Let’s take as an example the following HUD positioning in for the fantasy racing game based on the Team Novasoft’s PATRIA 3D engine.

 

Focusing our attention on the right side of the picture where the HUD is displayed:

 

We can easily understand tha the HUD is composed of 6 pictures, 5 pictures that diplay small stars (life in the game) and a pause button placed in the center.

 

In order to calculate the X game 3D coordinates of where the engine has to diplay the texture’s quad (2 triangles), some calculation is required as shown in the following code excerpt:

   

First, I calculate a base X coordinate called HUD_Life_Coordinate_X based on the window_width (in my initial case 800 pixels) and then I divide it by 2 (the negation is used for following code not in this picture).

 

Starting from that I start playing with trigonometric functions to have the starts moving in circle around the circle of the pause button. But this is just a fancy effect, not the core of the discussion.

 

Now, the problem starts here, I initially thought that calculating the coordinates based on screen’s widths would have been enough, I was wrong…..

 

I have started testing the application on different android devices and this is what I found out.

 

On Galaxy TAB device, having a resolution of 1024X600, different from the initial development environment which is 800X480, this is the result of the above solution:

 

On other resolutions such as the Asus Transformer (1280* 800) the problem is even worse, the HUD is not displayed at all.

 

  At this point I started guessing which was the best way to handle this situation.

 

  I initially thought that it was depending only on the X resolution of the screen but I was wrong, every attempt in that send failed.

 

  I have then focused my attention to the screen ratio which is used as well in the OpenGL view frustum configuration of my engine (I guess any engine does it btw).

 

  So, the question was, how can I calculate an X value so that the HUD is displayed correctly on any “valid” resolution?

 

 

My approach was the following:

 

  • Take a resolution as a base for the final calculation, in my case I took the 800X400 as base.

  • Calculate the aspect ratio of the standard resolution:

       

  • Calculate the Aspect ratio of the current device resolution.

  • Convert the base offset coordinate in the following way:

 

 

     

Where: ReferenceCoordinate is the coordinate you calculated during the design of your game based on default resolution.

 

CurrentRatio is the screen ratio of the current resolution. DefaultRatio is the ratio of your default resolution (in my case 800X480) Therefore, having said so, I have changed my code in the following way:

  • Defined a new standard value for the default resolution’s aspect ratio (this step is not mandatory but helps a lot in code usability)

     

  • Modify the previously shown procedure to calculate the coordinates of the object in the following way:

So, having applied this solution, achieves the wanted result:


Illustration 1: 800X480 (used my many devices such as Samsung Galaxy S, Motorola Defy etc)

 

 

Illustration 2: 1024X600 used by Samsung Galaxy TAB 7"

 

 


llustration 3: 1280X800 (used for instance my our Asus Transformer)

Leave a comment