# Converting between screen coordinates and pixels

**URL:** <https://discourse.glfw.org/t/converting-between-screen-coordinates-and-pixels/1841>\
**Category:** support\
**Created:** [April 24, 2021, 8:19am UTC](https://discourse.glfw.org/t/converting-between-screen-coordinates-and-pixels/1841 "2021-04-24T08:19:03Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dylan](https://avatars.discourse-cdn.com/v4/letter/d/e95f7d/32.png) [@Dylan](https://discourse.glfw.org/u/Dylan)\
**Post date:** [April 24, 2021, 8:19am UTC](https://discourse.glfw.org/t/converting-between-screen-coordinates-and-pixels/1841/1 "2021-04-24T08:19:03Z")

</div>

The documentation says that screen coordinates are not necessarily measured in pixels. It also says that functions that return mouse cursor position operate in screen coordinates. So if I understand correctly, if I want to translate cursor positions into world coordinates of whatever I’m rendering in OpenGL, I should first convert the cursor position from screen coordinates to pixels. However, every example that I came across seems to feed cursor positions directly to OpenGL transforms as if they were already in pixels.

Am I right that a conversion is needed? If so, what is the correct way to do it? Do I just compute it manually based on the ratio between window size and framebuffer size?

---

<div class="post-metadata">

**Author:** ![dougbinks](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/dougbinks/32/39_2.png) [@dougbinks](https://discourse.glfw.org/u/dougbinks)\
**Post date:** [April 24, 2021, 11:04am UTC](https://discourse.glfw.org/t/converting-between-screen-coordinates-and-pixels/1841/2 "2021-04-24T11:04:41Z")

</div>

If you look at the projection matrix calculations you will see that they do not depend on the _resolution_ of the framebuffer, but on the _aspect ratio_ defined by the `width / height`. This is because the output of the vertex shader is in _clip space_ which is an axis aligned cube with coordinates ranging from `(-1.0,-1.0,-1.0)` to `(+1.0,+1.0,+1.0)`. The _clip space coordinates_ are transformed to _screen space coordinates_ using the _viewport transform_ you set with `glViewport`.

So you don’t need to worry about transforming your window coordinates to viewport coordinates if you use the inverse projection transform, as your input to these is in _clip space_. You will likely need a transform like:

```auto
// Following code untested
double x, y;
glfwGetCursorPos( g_pSys->window, &x, &y );

// cursor pos is in window coordinates, not gl fragment coords so use window size not framebuffer size
int w, h;
glfwGetWindowSize( g_pSys->window, &w, &h );

vec4 clip_space;
clip_space.x = 2.0f * (float)x/(float)w- 1.0f;
clip_space.y = 1.0f - 2.0f * (float)y/(float)h;
clip_space.z = -1.0f; // depends on whether you want the near or far plane
clip_space.w = 1.0f;
vec4 view_space = mInverseProjFromView * clip_space;

```

---

<div class="post-metadata">

**Author:** ![Dylan](https://avatars.discourse-cdn.com/v4/letter/d/e95f7d/32.png) [@Dylan](https://discourse.glfw.org/u/Dylan)\
**Post date:** [April 24, 2021, 12:58pm UTC](https://discourse.glfw.org/t/converting-between-screen-coordinates-and-pixels/1841/3 "2021-04-24T12:58:36Z")

</div>

Some projections depend only on the aspect ratio (like the perspective projection), but some don’t (like the orthographic projection), so unless I misunderstood, your answer doesn’t completely address my question.

As a side question: is the aspect ratio of the framebuffer guaranteed to be the same as the aspect ratio of the window? Or could it happen that there are different scale factors in x and y coordinates?

---

<div class="post-metadata">

**Author:** ![dougbinks](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/dougbinks/32/39_2.png) [@dougbinks](https://discourse.glfw.org/u/dougbinks)\
**Post date:** [April 24, 2021, 1:36pm UTC](https://discourse.glfw.org/t/converting-between-screen-coordinates-and-pixels/1841/4 "2021-04-24T13:36:39Z")

</div>

> but some don’t (like the orthographic projection)

The orthographic projection also does not depend on the resolution. The input coordinates define a box in _view space_ (view space is the coordinates after the camera view transform, similar to world space coordinates with an non-rotated, camera at the origin) which is converted to _clip space_ by the projection and then after the vertex shader to _viewport space_ by the current _glViewport_ setting.

This is often confused in tutorials which use the window coordinates as inputs to the orthographic matrix calculation. It’s fairly easy to figure out why this should be view space - as they define a box around what you want to display.

To make the result of an orthographic projection have the same scale in your rendered view, it’s usually best to ensure that the aspect ration is the same as the aspect ration of your window.

> is the aspect ratio of the framebuffer guaranteed to be the same as the aspect ratio of the window?

No (though I can’t recall seeing any real world situation with it being different, and many window APIs have only one scale value for both x and y). However this doesn’t change the way you convert cursor coordinates to clip space and then to view space and finally world space.

---

<div class="post-metadata">

**Author:** ![Dylan](https://avatars.discourse-cdn.com/v4/letter/d/e95f7d/32.png) [@Dylan](https://discourse.glfw.org/u/Dylan)\
**Post date:** [April 24, 2021, 2:04pm UTC](https://discourse.glfw.org/t/converting-between-screen-coordinates-and-pixels/1841/5 "2021-04-24T14:04:54Z")

</div>

> [@dougbinks](#):
>
> The orthographic projection also does not depend on the resolution.

I don’t understand what you mean. Here’s the matrix of [orthogonal projection](https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glOrtho.xml), it clearly depends on width and height, not just on the aspect ratio. If I set my projection to orthogonal projection with twice the framebuffer size what I see on my screen is half of the original size as it should be.

---

<div class="post-metadata">

**Author:** ![dougbinks](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/dougbinks/32/39_2.png) [@dougbinks](https://discourse.glfw.org/u/dougbinks)\
**Post date:** [April 24, 2021, 2:29pm UTC](https://discourse.glfw.org/t/converting-between-screen-coordinates-and-pixels/1841/6 "2021-04-24T14:29:35Z")

</div>

The coordinates of `glOrtho` are all _view space_ coordinates.

So if you have three points, `p0, p1, p2` which define the vertices of a triangle, and you want to view this triangle with `glOrtho` then you do something like the following:

```auto
// untested code

float left = min(p0.x, min(p1.x, p2.x) );
float right = max(p0.x, max(p1.x, p2.x) );
float bottom = min(p0.y, min(p1.y, p2.y) );
float top = max(p0.y, max(p1.y, p2.y) );
float nearVal = min(p0.z, min(p1.z, p2.z) );
float farVal = max(p0.z, max(p1.z, p2.z) );

glOrtho( left, right, bottom, top, nearVal, farVal );

```

If you want to ensure the aspect ratio is the same as your window, then you modify the `left,right` or `bottom,top` coordinates to maintain your desired aspect ration.

---

<div class="post-metadata">

**Author:** ![Dylan](https://avatars.discourse-cdn.com/v4/letter/d/e95f7d/32.png) [@Dylan](https://discourse.glfw.org/u/Dylan)\
**Post date:** [April 25, 2021, 8:33am UTC](https://discourse.glfw.org/t/converting-between-screen-coordinates-and-pixels/1841/7 "2021-04-25T08:33:56Z")

</div>

> [@dougbinks](#):
>
> The coordinates of `glOrtho` are all _view space_ coordinates.

Sure, but the arguments I need to pass to `glOrtho` to see what I want to see depend on the framebuffer size which is exactly what you say next:

> [@](#):
>
> If you want to ensure the aspect ratio is the same as your window, then you modify the `left,right` or `bottom,top` coordinates to maintain your desired aspect ration.

I agree, but I need to take the actual framebuffer size into account (not just the aspect ratio) since it’s going to affect how much of my screen the triangle will occupy.

---

<div class="post-metadata">

**Author:** ![dougbinks](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/dougbinks/32/39_2.png) [@dougbinks](https://discourse.glfw.org/u/dougbinks)\
**Post date:** [April 25, 2021, 2:22pm UTC](https://discourse.glfw.org/t/converting-between-screen-coordinates-and-pixels/1841/8 "2021-04-25T14:22:53Z")

</div>

> [@Dylan](#):
>
> Sure, but the arguments I need to pass to `glOrtho` to see what I want to see depend on the framebuffer size which is exactly what you say next:

I stated that they depend on the aspect ratio, not the actual size.

> [@Dylan](#):
>
> I agree, but I need to take the actual framebuffer size into account (not just the aspect ratio) since it’s going to affect how much of my screen the triangle will occupy.

The quantity _how much of my screen_ is a ratio, and since it’s a proportion of your window size you can use window coordinates.

All of this is however mute, the question you’ve asked is if you need to transform mouse coordinates to pixels before translating to world coordinates, and the answer is you do not - the code from my first reply is what you need for all cases.
