我编写了一个将“屏幕”坐标转换为“视图”坐标的函数。它看起来像这样(C#中的例子):
Vector2 ScreenToViewCoords(Point p)
{
return new Vector2(
_projMatrix.M11 * p.X + _projMatrix.M12 * p.Y + _projMatrix.M14,
_projMatrix.M21 * p.X + _projMatrix.M22 * p.Y + _projMatrix.M24
);
}
p
是相对于OpenGL控件/视口左上角的点,以像素为单位。
_projMatrix
是我的投影矩阵。
我的渲染功能如下所示:
private void Render()
{
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref _projMatrix);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
if (_texture != null)
{
_texture.Bind();
GL.Color3(Color.White);
GL.Begin(BeginMode.Quads);
{
GL.TexCoord2(0, 0); GL.Vertex2(0, 0);
GL.TexCoord2(0, 1); GL.Vertex2(0, _texture.Height);
GL.TexCoord2(1, 1); GL.Vertex2(_texture.Width, _texture.Height);
GL.TexCoord2(1, 0); GL.Vertex2(_texture.Width, 0);
}
GL.End();
_texture.Unbind();
}
glControl.SwapBuffers();
}
使用投影矩阵,并在屏幕上绘制图像,始终位于相同的位置:(0,0)到(宽度,高度)。
由于图像是以1个视图单位= 1像素绘制的,所以我希望我的所有投影矩阵都需要做一些翻译才能将图像放在正确的位置。因此,我认为它看起来像
1 0 0 0
0 1 0 0
0 0 1 0
tx ty 0 1
但实际上看起来像这样:
(注意:它显示为旋转,因为它们是列,而不是行)
那部分已经让我感到困惑,但无论如何,我的数学应该是正确的,除非我忘了什么?
请注意,渲染功能完全按照预期工作,我只是尝试将鼠标单击转换为视图坐标。另请注意,这是一个2D应用程序,因此没有真正使用Z向量(再次,不确定为什么Column2
会出现奇怪的现象。)
所以我在这里错误地认为坐标没有正确出现?
例如,如果我正如前所述在(0,0)到(w,h)处绘制图像,并且我点击700x500图像的右下角,我希望它输出699x499但它改为(0.9959349, -0.9971989)
。
编辑:找出Z
坐标奇怪的原因。我设置了-1和11之间的正交矩阵,而不是-1和1.然而,这并没有真正改变任何东西,因为Z值无关紧要。
Edit2:现在我发现投影矩阵将模型视图转换为屏幕坐标,我基本上想要反过来 - 我是否需要反转矩阵?这样做会给我更多像素化的数字,但乘以它会使我的坐标变得太大而不是:
答案 0 :(得分:1)
GL中的投影矩阵转换为标准化坐标空间,其中X和Y介于-1和1之间(在透视分割之后,在正交投影中可以忽略,因为它只是除以1)
要获取像素坐标,您需要按视口缩放/偏移,以便-1到1范围映射到视口中指定的左右宽度和高度。
例如:
screenX = (viewWidth * (normX + 1) / 2) + viewLeft;
要从屏幕坐标转换回视图坐标,请反过来 - 将屏幕坐标转换为标准化坐标,然后将它们推送到逆变换。
gluProject()
和gluUnproject()
会为您执行此操作,或者您可以咨询来源。