2016-06-07 2 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); 
} 

관련 섹션 :

#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 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); 

이 내 버텍스 쉐이더입니다

쉐이더에서 투영 및 뷰 매트릭스가 없으면 회전이 잘된 것처럼 보일 수 있지만 상황이 이상하게 보입니다. View 행렬이 추가됩니다. 투영 행렬을 추가하면 아무 것도 렌더링되지 않습니다. 비교

이미지 :인가 전체 MVP 행렬

Model/rotation matrix only applied

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

는 아무런 배경 이외에는 보이지 않는다. (죄송합니다. 지금은 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/1uhnlg/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에서 transposed 인수를 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 –