在GLSL顶点着色器中使用正确的坐标系

5

我似乎有一个奇怪的问题。我像这样设置了OpenGL:

glViewport(0, 0, width, height);

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

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

很显然,宽度和高度是我的窗口大小,即600乘以400。在OpenGL内部一切正常,我可以在正确的坐标系中移动。例如,将绘制的内容向右平移200像素。

现在,在我的顶点着色器中,我似乎无法使用相同的坐标系,我按照惯例进行操作:

vec4 pos  = gl_ModelViewProjectionMatrix * gl_Vertex;   
gl_Position = pos;

在main()函数内,一切似乎都很正常。然而,当我尝试这样做时:
vec4 pos  = gl_ModelViewProjectionMatrix * gl_Vertex;   
pos.x+= 1.0;
pos.y-= 1.0;
gl_Position = pos;

顶点的位置不是在每个方向上移动1个像素,而是在x方向上移动300个像素,在y方向上移动200个像素。

我知道我可以在着色器中缩放这些值,但这似乎有点不太干净。我肯定在设置中做错了什么。非常感谢任何帮助。

2个回答

12

gl_Position输出的位置不是屏幕空间,而是剪裁空间。剪裁空间在每个方向上从-1到1,经过隐含的/w除法。glOrtho对投影进行转换,会将[0, 800]x[0,600]范围内的坐标进行偏移/缩放,以映射到[-1,1]。

转换为屏幕像素空间的变换是通过视口变换实现的。视口将NDC坐标(这些是剪裁坐标之后的一小但重要的步骤)与窗口尺寸相关联。投影不需要依赖视口尺寸(当然,如果想要按像素放置物体,则使用将眼空间坐标映射到屏幕像素空间的投影是可取的)。


4
你正在应用变换之后的[+1, -1]翻译。-1<=x<=1,-1<=y<=1对应于此转换后视口的边缘,这就是为什么您会得到宽度/2和高度/2的增量的原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接