2016-06-07 61 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 –