GLSL 中的矩阵变换不起作用

Matrix Transformation in GLSL not working

本文关键字:变换 不起作用 GLSL      更新时间:2023-10-16

所以我要做的是为2D GUI对象制作一个转换矩阵。当我将三个变换矩阵相乘时,旋转和缩放实际上会影响对象的旋转和缩放,但不会影响位置。我在GDebugger中检查了,并且正在正确计算矩阵,但是由于某种原因,该位置似乎不会以任何方式影响顶点。

下面是相关的 c++ 代码:

void GUIRenderer::setPosition(float x, float y)
{
    Position = glm::vec2(x, y);
    Pos_Mat = glm::mat3(
        1, 0, x,
        0, 1, y,
        0, 0, 1
        );
    Transformation = Sca_Mat*Rot_Mat*Pos_Mat;
}
void GUIRenderer::setRotation(float _Rot)
{
    Rotation = _Rot;
    Rot_Mat = glm::mat3(
        cos(Rotation), sin(Rotation), 0,
        -sin(Rotation), cos(Rotation), 0,
        0, 0, 1
        );
    Transformation = Sca_Mat*Rot_Mat*Pos_Mat;
}
void GUIRenderer::setScale(float x, float y)
{
    Scale = glm::vec2(x, y);
    Sca_Mat = glm::mat3(
        x, 0, 0,
        0, y, 0,
        0, 0, 1
        );
    Transformation = Sca_Mat*Rot_Mat*Pos_Mat;
}
void GUIRenderer::Update()
{
    glDisable(GL_DEPTH_TEST);
    glUseProgram(GUI_material->Program);
    glUniform3f(GUI_material->Color_Uniform, 1.0f, 1.0f, 1.0f);
    pos++;
    setPosition(pos, 0.0f);
    glUniformMatrix3fv(GUI_material->Trans_Uniform, 1, GL_FALSE, &Transformation[0][0]);
    GUI_material->RefreshTexture();
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, mesh->Vertices.size()*sizeof(glm::vec3), &mesh->Vertices[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(GUI_material->Position_Attribute);
    glVertexAttribPointer(GUI_material->Position_Attribute, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glBindBuffer(GL_ARRAY_BUFFER, UVBO);
    glBufferData(GL_ARRAY_BUFFER, mesh->UVs.size()*sizeof(glm::vec2), &mesh->UVs[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(GUI_material->TexCoord_Attribute);
    glVertexAttribPointer(GUI_material->TexCoord_Attribute, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh->Triangles.size()*sizeof(int), &mesh->Triangles[0], GL_STATIC_DRAW);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}

这是相关的 GLSL 代码:

#version 330 core
in vec3 position;
in vec2 texcoord;
uniform mat3 Trans;
out vec2 Texcoord;
void main() {
   Texcoord = texcoord;
   vec3 _pos = Trans*vec3(position.xy, 1.0);
   gl_Position = vec4(_pos.xy, 0.0, 1.0);
}

这是发送到着色器的内容的 gDebugger 输出发送到着色器的内容的 GDebugger 输出

Trans GL_FLOAT _MAT3
{0.00014815529, 0.49999997, 562}
{-0.49999997, 0.00014815529, 0}
{0, 0, 1}

我是在什么地方出错了吗?

您在着色器中使用"矩阵 * 向量"乘法顺序。必须按照此约定生成矩阵。OpenGL 将对矩阵使用列主顺序,因此您的 setPosition 函数会创建一个矩阵,在该矩阵中,它将xy翻译部分放入最后一行而不是最后一。现在这根本没有效果,因为在着色器中,您完全忽略了_pos.z值,该值会被此搞砸。

有趣的是,您在构建旋转矩阵时考虑了换位(减号位于第一行,第二列),因此只有您的平移矩阵被转置,其余部分将按原样工作。