C++ OpenGL-平移会拉伸和扭曲sprite

C++ OpenGL-平移会拉伸和扭曲sprite,c++,opengl,transform,translation,distortion,C++,Opengl,Transform,Translation,Distortion,我大致上是在学习非常方便的教程。我已经能够创建一个网格,画一个精灵到它,旋转和缩放网格完美 但是,我在尝试转换网格时遇到了一些问题。(下图) 下面是精灵的更新功能: Transform* transform = static_cast<Transform*>(owner->GetComponent(CID_TRANSFORM)); glUseProgram(shaderID_); glm::mat4 projection = glm::perspec

我大致上是在学习非常方便的教程。我已经能够创建一个网格,画一个精灵到它,旋转和缩放网格完美

但是,我在尝试转换网格时遇到了一些问题。(下图)

下面是精灵的更新功能:

    Transform* transform = static_cast<Transform*>(owner->GetComponent(CID_TRANSFORM));

    glUseProgram(shaderID_);

    glm::mat4 projection = glm::perspective(45.0f , 4.0f / 3.0f, 0.1f, 100.0f);

    glm::mat4 view = glm::lookAt(
        glm::vec3(3, 3, 3),
        glm::vec3(0, 0, 0),
        glm::vec3(0, 1, 0)
        );

    glm::mat4 model = transform->GetModelMatrix();

    glm::mat4 mvp = projection * view * model;

    GLuint matrixID = glGetUniformLocation(shaderID_, "MVP");

    glUniformMatrix4fv(matrixID, 1, GL_FALSE, &mvp[0][0]);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture_);
    glUniform1i(samplerID_, 0);

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer_);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, uvBuffer_);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glDrawArrays(GL_TRIANGLES, 0, 3 * 2);

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
这是从(3,3,3)观看的原点处的精灵。

下面是从(3,3,3)查看时转换为(1,0,0)的精灵。

与OpenGL匹配,GLM以列主顺序存储矩阵。构造函数还希望元素以相同的顺序指定

但是,您的转换矩阵是按行的主要顺序指定的:

glm::mat4 trans = glm::mat4(
    1.0f, 0.0f, 0.0f, translation.x,
    0.0f, 1.0f, 0.0f, translation.y,
    0.0f, 0.0f, 1.0f, translation.z,
    0.0f, 0.0f, 0.0f, 1.0f);
要以正确的列主顺序指定矩阵,需要:

glm::mat4 trans = glm::mat4(
    1.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f, 0.0f,
    translation.x, translation.y, translation.z, 1.0f);

这张照片在我看来并没有失真,只是正常的透视投影,只是有一个大的入射角。矩形的一部分似乎被视锥体近场剪切。@sevatitov:相机在两张图片之间没有移动,唯一的区别是网格沿x轴移动了1个单位。在我看来,这会使精灵保持相同的方向,只是向右移动。我认为GLM和OpenGL一样,使用列主矩阵。您正在按行的主要顺序指定转换矩阵的元素。@RetoKoradi:啊,我真傻!确实如此。谢谢把它作为一个答案转贴出来,我会把它标记为正确的。第一段的输入错误:)@Grimmy确实!谢谢,现在修好了。实际上,“列主修”和“行主修”在这里混在一起了。在“column major”表示法中,翻译元素位于第四列,而在“row major”表示法中,这些元素位于第四行。@PeterO.No,当前版本应该是正确的。平移元素总是在最后一列中(好吧,至少只要您与右侧的列向量相乘)。如果矩阵是按行主顺序指定的,则它们将成为元素3、7和11。在列主顺序中,它们是元素12、13和14。然后应避免使用术语“列主”和“行主”以避免混淆。
glm::mat4 trans = glm::mat4(
    1.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f, 0.0f,
    translation.x, translation.y, translation.z, 1.0f);