2016-06-07 113 views
-2

我一直在关注一些OpenGL教程,并且我的MVP矩阵计算似乎没有像他们应该那样工作。我怀疑自己在某个功能中出现了错误,但我似乎无法找到它。帮助将不胜感激,因为我仍然是3D矩阵转换领域的初学者。OpenGL MVP矩阵计算错误

我使用我的MVP计算的一部分功能:

float ToRadians(float Degrees) 
{ 
    float Result = Degrees * (PI32/180.0f); 

    return (Result); 
} 

mat4 Rotate(float Angle, vec3 Axis) 
{ 
    // Creates an identity matrix 
    mat4 Result = Mat4d(1.0f); 

    float SinTheta = sinf(ToRadians(Angle)); 
    float CosTheta = cosf(ToRadians(Angle)); 

    Result.Elements[0][0] = (Axis.X * Axis.X * (1.0f - CosTheta)) + CosTheta; 
    Result.Elements[0][1] = (Axis.X * Axis.Y * (1.0f - CosTheta)) - (Axis.Z * SinTheta); 
    Result.Elements[0][2] = (Axis.X * Axis.Z * (1.0f - CosTheta)) + (Axis.Y * SinTheta); 

    Result.Elements[1][0] = (Axis.Y * Axis.X * (1.0f - CosTheta)) + (Axis.Z * SinTheta); 
    Result.Elements[1][1] = (Axis.Y * Axis.Y * (1.0f - CosTheta)) + CosTheta; 
    Result.Elements[1][2] = (Axis.Y * Axis.Z * (1.0f - CosTheta)) - (Axis.X * SinTheta); 

    Result.Elements[2][0] = (Axis.Z * Axis.X * (1.0f - CosTheta)) - (Axis.Y * SinTheta); 
    Result.Elements[2][1] = (Axis.Z * Axis.Y * (1.0f - CosTheta)) + (Axis.X * SinTheta); 
    Result.Elements[2][2] = (Axis.Z * Axis.Z * (1.0f - CosTheta)) + CosTheta; 

    return (Result); 
} 

mat4 Translate(vec3 Translation) 
{ 
    mat4 Result = Mat4d(1.0f); 

    Result.Elements[3][0] = Translation.X; 
    Result.Elements[3][1] = Translation.Y; 
    Result.Elements[3][2] = Translation.Z; 

    return (Result); 
} 

mat4 Perspective(float FOV, float AspectRatio, float Near, float Far) 
{ 
    mat4 Result = Mat4d(1.0f); 

    float TanThetaOver2 = tanf(FOV * (PI32/360.0f)); 

    Result.Elements[0][0] = 1.0f/TanThetaOver2; 
    Result.Elements[1][1] = AspectRatio/TanThetaOver2; 
    Result.Elements[2][3] = -1.0f; 
    Result.Elements[2][2] = (Near + Far)/(Near - Far); 
    Result.Elements[3][2] = (2.0f * Near * Far)/(Near - Far); 
    Result.Elements[3][3] = 0.0f; 

    return (Result); 
} 

我的主体的相关章节:

// Model matrix 
mat4 MatModel = Rotate(-45.0f, Vec3(1.0f, 0.0f, 0.0f)); 
// View matrix 
mat4 MatView = Translate(Vec3(0.0f, 0.0f, -3.0f)); 
// Projection matrix 
mat4 MatProjection = Perspective(45.0f, 
           (GLfloat) 1024/(GLfloat) 768, 
           0.1f, 100.0f); 

GLuint LocModel = glGetUniformLocation(ShaderProgramID, "Model"); 
GLuint LocView = glGetUniformLocation(ShaderProgramID, "View"); 
GLuint LocProjection = glGetUniformLocation(ShaderProgramID, "Projection"); 

glUniformMatrix4fv(LocModel, 1, GL_TRUE, (GLfloat*) MatModel.Elements); 
glUniformMatrix4fv(LocView, 1, GL_TRUE, (GLfloat*) MatView.Elements); 
glUniformMatrix4fv(LocProjection, 1, GL_TRUE, (GLfloat*) MatProjection.Elements); 

// Bind VAO and draw from EBO 
glBindVertexArray(VAO); 
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 
glBindVertexArray(0); 

这是我的顶点着色器:

#version 330 core 

layout (location = 0) in vec3 Position; 
layout (location = 1) in vec2 CTexCoord; 

out vec2 STexCoord; 

uniform mat4 Model; 
uniform mat4 View; 
uniform mat4 Projection; 

void main() 
{ 
    gl_Position = Projection * View * Model * vec4(Position, 1.0f); 
    STexCoord = CTexCoord; 
} 

在着色器中,没有投影和视图矩阵,旋转看起来很好,但是当看起来奇怪时视图矩阵被添加。随着投影矩阵的添加,不会呈现任何东西。

映像进行比较:

Model/rotation matrix only applied

Model/rotation and View/translation matrices applied (does this look normal?)

在施加全MVP矩阵,什么也不显示除了背景。 (对不起,现在不能发布超过2个链接...)

在此先感谢! :)

+0

我不确定,你的视图矩阵是正确的。您可以使用http://glm.g-truc.net/0.9.7/index.html轻松使用矩阵。我如何知道视图矩阵包含目标点的位置和向量。 – Unick

+0

我在C编程,所以glm对我来说用处不大。如果C有一些相同的东西,我会很有兴趣知道。 :) –

+0

你可以在这里找到一些链接https://www.reddit.com/r/gamedev/comments/1u​​hnlg/good_glm_alternatives_for_c/ – Unick

回答

0

您对glUniformMatrix的调用集转置为GL_TRUE,这意味着矩阵是行优先的。这意味着OpenGL期望矩阵的每一行中的元素在内存中相邻。要设置视图矩阵平移元素是这样的:

Result.Elements[3][0] = Translation.X; 
Result.Elements[3][1] = Translation.Y; 
Result.Elements[3][2] = Translation.Z; 

既然你告诉OpenGL的,你的矩阵行重大,这意味着在元素的第一个下标是行中的元素最后一个下标柱。这意味着您要在翻译的第4列中设置第1列至第3列。这会影响到gl_Position的w分量,并且你会感到奇怪。我可以看到你在为你的投影矩阵做同样的错误。基于此,我假设你让mat4成为专栏。如果是这种情况,我建议将glUniformMatrix中的移位参数改为GL_FALSE。如果不是,你应该在平移和投影建筑物中交换行/列,如:

mat4 Translate(vec3 Translation) 
{ 
    mat4 Result = Mat4d(1.0f); 

    Result.Elements[0][3] = Translation.X; 
    Result.Elements[1][3] = Translation.Y; 
    Result.Elements[2][3] = Translation.Z; 

    return (Result); 
} 
+0

感谢bofjas。我会给它一个镜头,然后回来看看结果。 –

+0

感谢您的解释,bofjas! :D解决方案非常简单,我甚至都看不到它......:P –