1
\$\begingroup\$

I'm having a bit of an issue when it comes to 3D- and 2D camera(s), in relation to a game's window resolution. I want to let the player choose from different window resolutions, either from a menu or by just resizing the window by dragging the window border, and can't get the scaling of the graphics to work properly. In games I've played, I can go into the options menu, choose a screen resolution and then the window resize itself and the graphic's, menu buttons etc just scales up to the correct sizes.

At the moment, I've tried two different window resolutions; 800x600 and 1280x720 (don't mind the different aspect ratios).

800x600 800x600

1280x720 1280x720

As you can see, more of the game world can be seen (more stone tiles can be seen, if that makes sense) in the window with a resolution of 1280x720 and I want my 3D/2D game(s) to be resolution independent and that the same amount of the game world to be seen, independent of what window resolution the player chooses to use.

My camera class consist of:

  • Camera matrix - used to translate and rotate my camera
  • View matrix - the inverse of the camera matrix
  • Perspective matrix - see code below
  • View projection matrix - view matrix * perspective matrix
  • Fov - 45.0f
  • Aspect ratio - camera width / camera height

Note: row-major matrices

Perspective matrix:

const float Tangent     = 1.0f / tanf(DEGREES_TO_RADIANS(Fov * 0.5f));
const float NearToFar   = FarClip - NearClip;

PerspectiveMatrix(Identity);

PerspectiveMatrix[0]    = -Tangent / AspectRatio;
PerspectiveMatrix[5]    =  Tangent;
PerspectiveMatrix[10]   =  FarClip / NearToFar;
PerspectiveMatrix[11]   =  1.0f;
PerspectiveMatrix[14]   = (-NearClip * FarClip) / NearToFar;
PerspectiveMatrix[15]   =  0.0f;

At each update, I'm also setting the viewport by calling glViewport(0, 0, CameraWidth, CameraHeight). This might change in the future if I decide to make two cameras in a game, for a splitscreen game for example.

How can I solve the window resolution independence issue?

I have though about creating a framebuffer the size I want, attach it to a quad and then render the quad the size of the window, which will scale up/down the framebuffer if the window is bigger/smaller than the framebuffer's original size, but if it's an easier way of doing it, I would gladly use that instead.

\$\endgroup\$
1
\$\begingroup\$

don't mind the different aspect ratios

But that's the problem. If you use 2 windows with different sizes but the same aspect ratio you won't see this problem.

It looks like you're using the Field of View to represent the vertical field of view. As you can see, the vertical fields are the same. You see the same amount of ceiling and floor in both windows. But because the windows are different aspect ratios, that necessarily means that there will be a different field of view horizontally.

You have some options:

  1. Use the field of view to represent the horizontal FOV instead of vertical. This will mean you get the same number of bricks horizontally, but will change the vertical view so in one case you see more ceiling and floor than the other.
  2. Stretch things to fit the different aspect ratios - this will distort things but will give you the same horizontal and vertical fields of view in both cases. It is ugly and drives some users (like me) nuts. I don't recommend it.
  3. Limit your various resolutions to the same aspect ratio. Some users will dislike this because "you're not using the full screen."
  4. Leave it like it is now. This is what most games do, as far as I can tell. (Well this or #1 which has the same issue in reverse.) I've not heard many users complain about this because they don't often change screen aspect ratios over the course of playing a game (even between sessions).
\$\endgroup\$
  • \$\begingroup\$ Thank you for your detailed answer. I think I will end up only using window resolutions with the same aspect ratio (i.e 16/9 format). Let say I have a menu with 5 different window resolutions and the player choose one, what in my code do I need to manipulate whenever the window size changes, besides the window size itself? \$\endgroup\$ – Daniel_1985 Dec 30 '17 at 18:41
  • \$\begingroup\$ Generally, things like the glViewport() and your cameraWidth and cameraHeight. Much of OpenGL's drawing will scale to the resolution of the frame buffer, so long as you set up things like the viewport correctly. (And if you're drawing to a texture-backed FBO, then making sure the texture is the right size.) \$\endgroup\$ – user1118321 Dec 30 '17 at 21:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.