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

使用openGL、glm数学和正交投影,旋转时形状会倾斜,opengl,matrix,opengl-3,glm-math,orthographic,Opengl,Matrix,Opengl 3,Glm Math,Orthographic,为了练习,我在openGL中设置了一个2d/正交渲染管道,用于一个简单的游戏,但我遇到了与坐标系相关的问题 简言之,旋转会扭曲2d形状,我似乎不明白为什么。我也不完全确定我的坐标系是否可靠 首先,我查找了以前的答案,但以下(最相关的)表明问题在于变换的顺序不正确,但现在我只使用视图矩阵和投影矩阵,在顶点着色器中以正确的顺序相乘: gl_Position = projection * view * model vec4(1.0); //(The model is just the identity

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

简言之,旋转会扭曲2d形状,我似乎不明白为什么。我也不完全确定我的坐标系是否可靠

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

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
(time/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_位置(我的“in”/“variable”插值版本的位置属性)在着色器中以-1对1的方式工作?在放置实体时,选择特定坐标系的含义是什么?游戏将使用精灵和纹理,所以我考虑使用像素坐标系,但这很快就变得非常具有挑战性的原因在着色器方面。我更愿意让它工作

谢谢你的帮助


编辑:是否可能将我的可变/插值v_位置设置为计算的gl_位置值而不是属性位置?

尝试在glm::ortho的前两个参数中考虑正在显示的窗口的纵横比,以反映显示的纵横比

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

当我回到我的系统时,我可以试试这个,但是我不也需要调整顶点坐标吗?或者更确切地说,你的建议是否会使在世界上放置对象变得更困难?我想我的问题是:人们通常如何创建一个独立于分辨率的二维坐标系,该坐标系在着色器中表现良好,同时也允许在世界中直观地放置对象?问题是我的方法可能有很多错误——在CPU和/或着色器上。我不是矩阵方面的专家。但我相信你只需要考虑投影矩阵中的长宽比。我认为你不需要修改你的纹理坐标。我遇到了本教程,它可能会有所帮助,并且在提供的源代码中涉及纵横比的考虑因素:嗯,我正在使用该教程,它可以快速跳过正交投影。无论如何,今天晚些时候我会尝试你的解决方案。