【发布时间】:2018-05-02 23:28:16
【问题描述】:
为了练习,我在 openGL 中设置了一个 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(我的位置属性的“in”/“variing”插值版本)在 -1 到 1 中工作,因为它应该在着色器中?在放置实体方面,选择特定坐标系的含义是什么?游戏将使用精灵和纹理,所以我正在考虑像素坐标系,但这很快就变得非常难以在着色器方面进行推理。我宁愿让这个工作。
感谢您的帮助。
编辑:是否可以将我的可变/插值 v_position 设置为计算的 gl_Position 值而不是属性位置?
【问题讨论】:
标签: opengl matrix opengl-3 glm-math orthographic