什么是此类模型失真的来源

时间:2016-05-03 08:24:58

标签: c++ opengl glfw

我将代码从旧项目变为新项目。旧版基于GLFW,新版基于GLFW3。对用于存储数据的对象进行了一些修改,乍一看最终结果不应该被改变,但实际上它会产生扭曲的图像。我认为它与MVP矩阵有关。

the glitch的屏幕截图。它应该是两个盒子^ _ ^

draw方法绘制具有指定基色和光源的对象(目前硬编码):

glm::mat4 view, model, mvp, projection;

Mesh* mesh = (Mesh*)rm.Get(renderable->model);
Position* frame = (Position*)positions->Get( renderable->owner );
int program_id = ((Shader*)rm.Get(renderable->program))->program_id;

//vertex buffer
glEnableVertexAttribArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, mesh->vertex.buffer_id );
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0 );

//normal buffer
glEnableVertexAttribArray( 1 );
glBindBuffer( GL_ARRAY_BUFFER, mesh->normal.buffer_id );
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_TRUE, 0, (void*)0 );

//texture uv buffer
glEnableVertexAttribArray( 2 );
glBindBuffer( GL_ARRAY_BUFFER, mesh->uv.buffer_id );
glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 );

glUseProgram( program_id );

view = camera->view;
projection = camera->projection;
mvp = projection * view * frame->mat4;

//set color
GLint base_color = glGetUniformLocation( program_id, "base_color" );
if( base_color != -1 )
    glUniform3f( base_color, renderable->diffuse_color.r, 
                             renderable->diffuse_color.g, 
                             renderable->diffuse_color.b );

glm::vec4 light_pos = glm::vec4( 0.0f, 5.0f, 0.0f, 1.0f );
glm::vec4 light = glm::normalize( glm::inverse( frame->mat4 ) * light_pos );

GLint light_position = glGetUniformLocation( program_id, "light_position" );
if( light_position != -1 )  glUniform3f( light_position, light.x, light.y, light.z );

GLint light_ambient = glGetUniformLocation( program_id, "light_ambient" );
if( light_ambient != -1 )   glUniform3f( light_ambient, 0.4f, 0.4f, 0.4f );

GLint light_diffuse = glGetUniformLocation( program_id, "light_diffuse" );
if( light_diffuse != -1 )   glUniform3f( light_diffuse, 0.7f, 0.7f, 0.7f );

GLint mvp44 = glGetUniformLocation( program_id, "MVP" );
glUniformMatrix4fv( mvp44, 1, GL_FALSE, &mvp[0][0] );

// Starting from vertex 0; 3 vertices total -> 1 triangle
glDrawArrays( GL_TRIANGLES, 0, mesh->vertex.size / 3 );

glDisableVertexAttribArray( 0 );
glDisableVertexAttribArray( 1 );
glDisableVertexAttribArray( 2 );

视图和投影矩阵计算方法:

camera->target = glm::vec3(position->x_axis) - glm::vec3{1.0f, 0.0f, 0.0f};
camera->view = glm::lookAt( glm::vec3( position->position ), camera->target, glm::vec3( position->y_axis ) );
camera->projection = glm::perspective( camera->fovy, camera->aspect, camera->near_r, camera->far_r );

相机结构:

struct Camera: public Component {
    glm::mat4       projection;
    glm::mat4       view;
    glm::vec3       target;
    glm::vec3       up;

    float       fovy;
    float       aspect;
    float       near_r;
    float       far_r;

    bool        directed;

};

职位结构:

struct Position: public Component {
    union {
        struct {
            glm::mat4 mat4;
        };

        struct {
            glm::vec4 x_axis;
            glm::vec4 y_axis;
            glm::vec4 z_axis;
            glm::vec4 position;
        };

        struct {
            glm::vec4 fwd;
            glm::vec4 up;
            glm::vec4 right;
            glm::vec4 position;
        };
    };
};

网格结构仅包含相应的缓冲区ID及其大小。

相机初始化数据:

camera->up = glm::vec3( 0.0f, 1.0f, 0.0f );

camera->fovy = 65.0f;
camera->aspect = 4.0f / 3.0f;
camera->near_r = 0.1f;
camera->far_r = 100.0f;
camera->directed = true;

职位启动数据:

position->position = glm::vec4{ 5.0f, 0.0f, 0.0f, 1.0f };
position->fwd = glm::vec4{ 1.0f, 0.0f, 0.0f, 1.0f };
position->up = glm::vec4{ 0.0f, 1.0f, 0.0f, 1.0f };
position->right = glm::vec4{ 0.0f, 0.0f, 1.0f, 1.0f };

着色器和模型数据及其加载/绑定功能与之前的项目相同,不会造成麻烦。

MVP矩阵的内容:

r=0.000000000 g=0.000000000 b=7.81581593 a=8.00000000
r=0.000000000 g=1.56968546  b=6.81381416 a=7.00000000
r=1.17726409  g=0.000000000 b=6.81381416 a=7.00000000
r=0.000000000 g=0.000000000 b=5.01000977 a=5.00000000

对于职位:

r=1.000000000 g=0.000000000 b=0.000000000 a=1.00000000
r=0.000000000 g=1.000000000 b=0.000000000 a=1.00000000
r=0.000000000 g=0.000000000 b=1.000000000 a=1.00000000
r=5.000000000 g=0.000000000 b=0.000000000 a=1.00000000

2 个答案:

答案 0 :(得分:1)

看起来你用矩阵重写了Vertex属性

GLint mvp44 = glGetUniformLocation( program_id, "MVP" ); glUniformMatrix4fv( 0, 1, GL_FALSE, &mvp[0][0] );

尝试使用您查询过的统一位置: GLint mvp44 = glGetUniformLocation( program_id, "MVP" ); glUniformMatrix4fv( mvp44, 1, GL_FALSE, &mvp[0][0] );

答案 1 :(得分:0)

问题中的图片是两个问题的结果。首先是我使用位置的模型矩阵。对于我的情况,应该是:

r=1.000000000 g=0.000000000 b=0.000000000 a=0.00000000
r=0.000000000 g=1.000000000 b=0.000000000 a=0.00000000
r=0.000000000 g=0.000000000 b=1.000000000 a=0.00000000
r=1.000000000 g=1.000000000 b=1.000000000 a=1.00000000

它描述了位于1.1.1坐标处的物体的位置。 Normaly,最后一列用于存储位置,但是当我两年前编写代码时,我使用了转置矩阵,并愉快地忘记了它。因此,初始矩阵对于正常模型矩阵是正确的,但对于转置则不正确。

修好后,它会this。那些文物负责出现奇怪的形状。通过启用GL_DEPTH_TEST,这是fixed