Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the correct coordinate system in GLSL vertex shader

I seem to have a curious problem. I set up OpenGL like this:

glViewport(0, 0, width, height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, -width, width);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

Obviously, width and height are the size of my window, which is 600 by 400. Inside OpenGL everything is fine, I can move around the correct coordinate system. ie translating by 200 moves whatever is being drawn by 200 pixels.

Now, inside my vertex shader I can't seem to use the same coordinate system, I do the usual:

vec4 pos  = gl_ModelViewProjectionMatrix * gl_Vertex;   
gl_Position = pos;

inside main() and everything seems to be fine. However when I attempt something like this:

vec4 pos  = gl_ModelViewProjectionMatrix * gl_Vertex;   
pos.x+= 1.0;
pos.y-= 1.0;
gl_Position = pos;

The vertex positions are translated not by 1 pixel in each direction but by 300 in the x and 200 in the y.

I understand that I could scale these values inside the shader, but that seems a bit dirty. Surely I must be doing something wrong in the setup. Any help is much appreciated.

like image 877
whg Avatar asked Nov 19 '11 13:11

whg


2 Answers

The position output by gl_Position is not screen space. It's clip space. Clip space goes from -1 to 1 in each direction after an implied /w divide. glOrtho applies a transformation to the projection, that will offset/scale coordinates in the [0, 800]x[0,600] range to [-1,1].

The transformation to screen space pixels happens through the viewport transform. It is the viewport that relates NDC coordinates (those are one little, but important step after clip coordinates) to your window dimensions. The projection and not required to depend on the viewport dimensions (of course if one wants to place things by pixel, then using a projection that maps eye space coordinates to screen pixel space is desireable).

like image 134
datenwolf Avatar answered Oct 24 '22 04:10

datenwolf


You are applying the [+1, -1] translation after the transform. -1 <= x <= 1, -1 <= y <= 1 correspond to the viewport edges after this transformation, which is why you're getting increments of width/2 and height/2.

like image 4
Brett Hale Avatar answered Oct 24 '22 04:10

Brett Hale