OpenGL - 翻译拉伸和扭曲精灵
OpenGL - translation stretches and distorts sprite
我正在松散地遵循 opengl-tutorial.org 上非常方便的教程。我已经能够创建一个网格,为它绘制一个精灵,然后完美地旋转和缩放该网格。
但是,我 运行 在尝试平移网格时遇到了一些问题。 (下图)
这是精灵的更新函数:
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);
这里是 getModelMatrix 函数:
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;
}
这是从 (3, 3, 3) 看原点的精灵。
这是从 (3, 3, 3) 观看时转换为 (1, 0, 0) 的精灵。
GLM 与 OpenGL 相匹配,按列主要顺序存储矩阵。构造函数还期望以相同的顺序指定元素。
但是,您的翻译矩阵是按行主要顺序指定的:
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);
我正在松散地遵循 opengl-tutorial.org 上非常方便的教程。我已经能够创建一个网格,为它绘制一个精灵,然后完美地旋转和缩放该网格。
但是,我 运行 在尝试平移网格时遇到了一些问题。 (下图)
这是精灵的更新函数:
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);
这里是 getModelMatrix 函数:
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;
}
这是从 (3, 3, 3) 看原点的精灵。
这是从 (3, 3, 3) 观看时转换为 (1, 0, 0) 的精灵。
GLM 与 OpenGL 相匹配,按列主要顺序存储矩阵。构造函数还期望以相同的顺序指定元素。
但是,您的翻译矩阵是按行主要顺序指定的:
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);