【问题标题】:Opengl Translation on Model Matrix malforms result模型矩阵错误结果的 Opengl 翻译
【发布时间】:2019-06-17 10:43:07
【问题描述】:

我正在尝试构建一个模型矩阵,在其中应用一些常见的转换,例如缩放、旋转和平移。我在这里学习了一个教程:https://solarianprogrammer.com/2013/05/22/opengl-101-matrices-projection-view-model/。我知道矩阵不是可交换的,所以我想我注意得到正确的转换顺序。

但是当我尝试翻译我的模型时,它会拉伸到相应的轴而不是平移。 这是它的外观:

如果有任何帮助,我将不胜感激。 :)

顶点着色器

# version 330

in vec3 in_pos;
in vec3 in_col;
in vec3 in_norm;

// uniform wie eine konstante, kann einmal per frame geaender werden und gillt fuer alle vertices
uniform mat4 mvp; // mat4 = 4x4 Matrix

// out stream to fragment shader
out vec4 frag_pos;
out vec4 frag_col;
out vec4 frag_norm;

// column major
void main() {
    gl_Position = mvp * vec4(in_pos, 1.0);
    frag_pos = vec4(in_pos,1.0);
    // transparent frag_col = vec4(in_col,0.5);
    frag_col = vec4(in_col,1);
    frag_norm = vec4(in_norm,1.0);
}

Java 转换

float aspectRatio = (float) HEIGHT /(float)WIDTH;

float[][] rotX = new float[][] {
        {1.0f,0.0f,0.0f,0.0f},
        {0.0f,(float)Math.cos(thetaX),(float)-Math.sin(thetaX),0.0f},
        {0.0f,(float)Math.sin(thetaX),(float)Math.cos(thetaX),0.0f},
        {0.0f,0.0f,0.0f,1.0f}
};

float[][] rotY = new float[][] {
        {(float)Math.cos(thetaY),0.0f,(float)Math.sin(thetaY),0.0f},
        {0.0f,1.0f,0.0f,0.0f},
        {(float)-Math.sin(thetaY),0.0f,(float)Math.cos(thetaY),0.0f},
        {0.0f,0.0f,0.0f,1.0f}
};

float[][] rotZ = new float[][] {
        {(float)Math.cos(thetaZ),(float)-Math.sin(thetaZ),0.0f,0.0f},
        {(float)Math.sin(thetaZ),(float)Math.cos(thetaZ),0.0f,0.0f},
        {0.0f,0.0f,1.0f,0.0f},
        {0.0f,0.0f,0.0f,1.0f}
};

float[][] translation = new float[][] {
        {1.0f,0.0f,0.0f,transX},
        {0.0f,1.0f,0.0f,transY},
        {0.0f,0.0f,1.0f,transZ},
        {0.0f,0.0f,0.0f,1.0f}
};

float[][] scaleMatrix = new float[][] {
        {scale,0.0f,0.0f,0.0f},
        {0.0f,scale,0.0f,0.0f},
        {0.0f,0.0f,scale,0.0f},
        {0.0f,0.0f,0.0f,1.0f}
};

float[][] aspect = new float[][] {
        {aspectRatio,0.0f,0.0f,0.0f},
        {0.0f,1.0f,0.0f,0.0f},
        {0.0f,0.0f,1.0f,0.0f},
        {0.0f,0.0f,0.0f,1.0f}
};

float[][] rotationMatrix = Matrix.matMult(rotZ,Matrix.matMult(rotY,rotX));
float[][] matrix = Matrix.matMult(translation,Matrix.matMult(rotationMatrix,scaleMatrix));

float[] model = Matrix.matrixToFloatVector(Matrix.matMult(matrix,aspect));

FloatBuffer fb = BufferUtils.createFloatBuffer(16);
fb.put(model);

fb.flip();  // Reset pointer
// "upload" to graphics card
glUniformMatrix4fv(uLocMVP, false, fb);

【问题讨论】:

  • 你必须转置矩阵。 glUniformMatrix4fv(uLocMVP, true, fb)
  • 是的,确实有效,谢谢,如果您觉得可以,可以向我解释一下为什么在转置后有效吗?
  • @Rabbid76 是不是因为 opengl 与专栏专业合作?

标签: java opengl glsl shader lwjgl


【解决方案1】:

参见The OpenGL Shading Language 4.6, 5.4.2 Vector and Matrix Constructors,第 110 页:

要通过指定向量或标量来初始化矩阵,组件会按列优先顺序分配给矩阵元素。

mat4(float, float, float, float,  // first column
     float, float, float, float,  // second column
     float, float, float, float,  // third column
     float, float, float, float); // fourth column

这意味着您必须在设置 mat4 类型的统一变量之前转置矩阵。

这可以通过设置glUniformMatrix4fvtrue的第三个参数自动完成:

glUniformMatrix4fv(uLocMVP, true, fb)

相反,您也可以转置初始化并交换矩阵乘法 (Matrix.matMult)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多