简体   繁体   中英

OpenGL - translation stretches and distorts sprite

I am loosely following the very handy tutorial at opengl-tutorial.org . I've been able to create a mesh, draw a sprite to it, and rotate and scale that mesh perfectly fine.

However, I'm running into some issues when trying to translate the mesh. (pictures below)

Here's an update function on the sprite:

    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);

And here's the getModelMatrix function:

glm::mat4 Transform::GetModelMatrix()
{
    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);

    float xCos = glm::cos(rotation.x);
    float xSin = glm::sin(rotation.x);
    float yCos = glm::cos(rotation.y);
    float ySin = glm::sin(rotation.y);
    float zCos = glm::cos(rotation.z);
    float zSin = glm::sin(rotation.z);

    glm::mat4 xRotation = glm::mat4(
        1.0f, 0.0f, 0.0f, 0.0f,
        0.0f, xCos, -xSin, 0.0f,
        0.0f, xSin, xCos, 0.0f,
        0.0f, 0.0f, 0.0f, 1.0f);

    glm::mat4 yRotation = glm::mat4(
        yCos, 0.0f, ySin, 0.0f,
        0.0f, 1.0f, 0.0f, 0.0f,
        -ySin, 0.0f, yCos, 0.0f,
        0.0f, 0.0f, 0.0f, 1.0f);

    glm::mat4 zRotation = glm::mat4(
        zCos, -zSin, 0.0f, 0.0f,
        zSin, zCos, 0.0f, 0.0f,
        0.0f, 0.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 0.0f, 1.0f);

    glm::mat4 rot = xRotation * yRotation * zRotation;

    glm::mat4 sca = glm::mat4(
        scale.x, 0.0f, 0.0f, 0.0f,
        0.0f, scale.y, 0.0f, 0.0f,
        0.0f, 0.0f, scale.z, 0.0f,
        0.0f, 0.0f, 0.0f, 1.0f);

    return trans * rot * sca;
}

Here is the sprite at the origin viewed from (3, 3, 3). 第一张图片

Here is the sprite translated to (1, 0, 0) viewed from (3, 3, 3). 第二张图片

Matching OpenGL, GLM stores matrices in column major order. The constructors also expect elements to be specified in the same order.

However, your translation matrix is specified in row major order:

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);

To specify the matrix in the correct column major order, this needs to be:

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM