旋转时形状倾斜,使用openGL,glm数学,正交投影

时间:2018-05-02 23:28:16

标签: opengl matrix opengl-3 glm-math orthographic

练习我在openGL中设置一个2d /正交渲染管道用于简单的游戏,但是我遇到了与坐标系相关的问题。

简而言之,旋转扭曲了2d形状,我似乎无法理解为什么。我也不完全确定我的坐标系是合理的。

首先我查找了以前的答案,但是以下(最相关的2D opengl rotation causes sprite distortion)表明问题是转换的顺序不正确,但是现在我只使用视图矩阵和投影矩阵,乘以顶点着色器中的正确顺序:

gl_Position = projection * view * model vec4(1.0); //(The model is just the identity matrix.)

总结我到目前为止的设置: - 我成功上传了应该在整个屏幕上延伸的四边形:

GLfloat vertices[] = {
   -wf,  hf,  0.0f, 0.0, 0.0, 1.0, 1.0,  // top left
   -wf, -hf,  0.0f, 0.0, 0.0, 1.0, 1.0,  // bottom left
    wf, -hf,  0.0f, 0.0, 0.0, 1.0, 1.0,  // bottom right
    wf,  hf,  0.0f, 0.0, 0.0, 1.0, 1.0,  // top right
};
GLuint indices[] = {
    0, 1, 2,  // first Triangle
    2, 3, 0,   // second Triangle
};

wf和hf是1,我试图使用-1到1的坐标系,所以我不需要按着色器的分辨率进行缩放(尽管我不确定这是否正确)。 )

我的视口和拼写矩阵:

glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
...
glm::mat4 mat_ident(1.0f);
glm::mat4 mat_projection = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);

......虽然这显然不会影响屏幕的宽度和高度。我见过其他人使用宽度和高度而不是1秒,但这似乎打破了系统或显示任何内容。

我使用静态方法旋转,该方法修改包含glm::quaternion(时间/ 1000)的结构以获得秒:

    main_cam.rotate((GLfloat)curr_time / TIME_UNIT_TO_SECONDS, 0.0f, 0.0f, 1.0f);
// which does: glm::angleAxis(angle, glm::vec3(x, y, z) * orientation)

最后,我将矩阵作为制服传递:

glUniformMatrix4fv(MAT_LOC, 1, GL_FALSE, glm::value_ptr(mat_projection * FreeCamera_calc_view_matrix(&main_cam) * mat_ident));

...并在顶点着色器中相乘

   gl_Position = u_matrix * vec4(a_position, 1.0);
   v_position = a_position.xyz;

全屏四边形在其中心旋转(0,0,如我所愿),但它的长度和宽度扭曲,这意味着我没有正确设置。

我最好的猜测是我还没有创建正确的正交矩阵,但不可否认的是,我在堆栈溢出或其他可能有助于调试的其他地方找不到任何其他东西。大多数答案都表明矩阵乘法顺序是错误的,但这不是这种情况。

第二个问题是 - 我不应该在2D游戏的背景下将我的坐标设置为1 / -1吗?我这样做是为了使写入着色器更容易。一旦我添加了模型矩阵,我也会关注角色/物体的移动。

可能导致此问题的原因是什么?如果我需要通过宽度和高度将参数乘以gl :: ortho,那么我如何变换坐标以便v_position(我的"在" /"变化"位置属性的插值版本在着色器中应该按-1到1工作吗?在轻松放置实体时,选择特定坐标系有什么含义?游戏将使用精灵和纹理,所以我正在考虑一个像素坐标系,但很快就变得很难在着色器方面进行推理。我宁愿让这个工作。

感谢您的帮助。

编辑:是否可以将我的变化/插值v_position设置为计算出的gl_Position值而不是属性位置?

1 个答案:

答案 0 :(得分:2)

尝试在glm :: ortho的前两个参数中考虑您正在显示的窗口的宽高比,以反映显示器的宽高比。

GLfloat aspectRatio = SCREEN_WIDTH / SCREEN_HEIGHT;
glm::mat4 mat_projection = glm::ortho(-aspectRatio, aspectRatio, -1.0f, 1.0f, -1.0f, 1.0f);