# OpenGL Having trouble working out how to adjust 2D coordinates to OpenGL's coordinate system

This topic is 1361 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have a set of textured quads for text and user interface elements, very carefully positioned in relation to a top-left origin. OpenGL's y axis is inverted though, and I'm having a lot of trouble getting the calculations right so that the user interface elements retain their top-left relative positions when rendered.

Here's my default view and projection matrices:

auto projmat = glm::ortho<float>(0.0f, window.width, 0.0f, window.height, 0.0f, 1000.0f);
auto viewMatrix = glm::translate(glm::mat4(1.0), glm::vec3(0)

I'm aware that the ortho values are wrong, as they put my glyphs at the bottom of the screen, with the offsets pushing my glyphs upwards, instead of pushing them downwards from the top, which is what is supposed to happen:

If I change the projection to:

auto projmat = glm::ortho<float>(0.0f, window.width, -window.height, 0.0f, 0.0f, 1000.0f);

then my glyphs end up offset from each other correctly, but the baseline is now at the very top of the client area:

#version 450

layout(location=0) in vec4 in_Position;
layout(location=1) in vec4 in_Color;
layout(location=2) in vec4 in_Normal;
layout(location=3) in vec2 in_TexCoord;

out VSOutput
{
vec4 color;
vec2 texCoord;

} vs_output;

struct InstanceData
{
vec2 pos;
vec2 scale;
vec2 uvScale;
vec2 uvOffset;
};

layout (std430) buffer instance_data
{
InstanceData instances[];
};

uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;

void main(void)
{
InstanceData instance = instances[gl_InstanceID];

float magnification = 50.0f; // TO DO: replace with uniform input

// these are text glyphs so I need to scale the unit quad to the correct aspect ratio
vec4 aspectScaling = vec4(instance.scale.x, instance.scale.y, 0, 0);
vec4 scaledOriginalPosition = aspectScaling * magnification * in_Position;

// we now translate the quad to the position specified by the current draw instance
vec4 instancePosition = vec4(instance.pos.x, instance.pos.y, 0, 0);
vec4 actualPosition = scaledOriginalPosition + instancePosition;
actualPosition.w = 1; // set w to 1 because scaling would have screwed it up

// perform the final world-view-projection transformation
vec4 pos = projectionMatrix * ((viewMatrix * actualPosition));
gl_Position = pos;

vs_output.texCoord = (in_TexCoord * instance.uvScale) + instance.uvOffset;
vs_output.color = in_Color;
}

Note that the texture coordinate calculation works just fine - it's just the y axis stuff that's giving me issues.

Any assistance would be appreciated. I want something that ideally is applied on the GL side of things - this concern shouldn't bleed back into the UI layout code, which I'd prefer to keep relative to normal screen coordinates.

##### Share on other sites

Simply revert the top and the bottom values:

auto projmat = glm::ortho<float>(0.0f, window.width, window.height, 0.0f, 0.0f, 1000.0f);

##### Share on other sites

I am working on a sprite batcher.

My sprites live in a top-left corner screen coordinates (we will abreviate by TLCSC). Meaning 0,0 is the top-left corner of the screen, the x-axis goes right and the y-axis goes down. The unit of each axis is the pixel.

OpenGL has a center normalized screen coordinates (we will abreviate by CNSC). Meaning 0,0 is at the center of the screen, x-axis going right and y-axis going up. No fixed units here, just know that  in-screen coordinates are pairs (x, y) such that x in [-1 ; 1] and y in [-1 ; 1].

From that, I wrote a matrix screenMat  doing conversion from TLCSC to CNSC:

glm::mat4 screenScaleMat = glm::scale(glm::mat4(1.0f), glm::vec3(2.0f/screenWidth, 2.0f/screenHeight, 1.0f));
glm::mat4 screenTransMat = glm::translate(glm::mat4(1.0f), glm::vec3(-1.0f, -1.0f, 0.0f));
glm::mat4 screenAxisMat = glm::scale(glm::mat4(1.0f), glm::vec3(1.0f, -1.0f, 1.0f));
glm::mat4 screenMat = screenAxisMat*screenTransMat*screenScaleMat;

I can apply screenMat  to any vec4(x, y, 0.0f, 1.0f).

Edited by Totologic

##### Share on other sites
Thanks for your suggestions. @Totologic - not sure if you're aware, but your calculations produce the same output as Mr.A's:

I tried inverting the texture coordinates but something to do with the inversion causes a bunch of the letters to miss the baseline by one pixel, causing the result to look... dodgy. I have another idea I am going to try; I'll report back with the results.

##### Share on other sites
Actually inverting the texture coordinates does work. I have a different problem related to my scaling values. Thanks for the help.

1. 1
Rutin
40
2. 2
3. 3
4. 4
5. 5

• 16
• 18
• 12
• 14
• 9
• ### Forum Statistics

• Total Topics
633360
• Total Posts
3011522
• ### Who's Online (See full list)

There are no registered users currently online

×