用现代OpenGL进行二维渲染的正交投影

时间:2014-09-23 11:04:59

标签: c++ opengl opengl-es sdl orthogonal

我试图将我前段时间写过的旧SDL游戏移植到3.3+ OpenGL上,并且我在获得正确的正交矩阵及其相应视图时遇到了一些问题。

    glm::mat4 proj = glm::ortho( 0.0f, static_cast<float>(win_W), static_cast<float>(win_H), 0.0f,-5.0f, 5.0f);

如果我只是使用这个投影并尝试在win_W和win_H的边界内渲染一个四边形,它就可以了。但是,如果我尝试使用以下方法模拟相机:

   glm::mat4 view = glm::lookAt(
    glm::vec3(0.0f, 0.0f, 1.0f),//cam pos
    glm::vec3(0.0f, 0.0f, 0.0f),//looking at
    glm::vec3(0.0f, 0.0f, 1.0f)//floored
);

我一无所获。即使将四边形定位在中心,相反,如果相反,我将视图居中:

  glm::mat4 view = glm::lookAt(
    glm::vec3(static_cast<float>(win_W), static_cast<float>(winH), 1.0f),//cam pos
    glm::vec3(static_cast<float>(win_W), static_cast<float>(winH), 0.0f),//looking at
    glm::vec3(0.0f, 0.0f, 1.0f)//floored
);

考虑到SDL通常会从游戏中的顶点中减去相机值以模拟视图,在这样的着色器中替换我的MVP操作会更好:

#version 150

in vec2 position;
in vec3 color;

out vec3 Color;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform mat4 camera;

void main()
{
Color = color;
 //faulty view
//gl_Position = projection *view * model * vec4(position, 0.0, 1.0);
//new SDL style camera
  mat4 newPosition = projection * model * vec4(position, 0.0, 1.0);
 gl_Position = newPosition - camera;
} 

不幸的是,我从(ArcSynthesis Book)学习的资源并不涵盖涉及默认NDC以外的坐标系的视图。由于某些原因,即使在今天,关于opengl的大多数讨论都是关于弃用版本的。  简而言之,对于现代opengl中的简单2D渲染,将视图设置为正交投影矩阵的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

您的查找调用实际上根本没有意义,因为您的up向量(0,0,1)与观察方向(0,0,-1)共线。这不会产生可用的矩阵。

您可能希望(0,1,0)为up向量。但是,即使你改变了,你可能会对结果感到惊讶。结合您设置的投影矩阵,您指定为外观目标的点不会出现在中心,而是出现在屏幕的角落。您的投影不会将(0,0)映射到中心,这通常在使用某些LookAt函数时会假设。

我同意三十二上校的评论:除非你有充分的理由,否则不要在这种情况下使用LookAt