glVertexAttribPointer:绘制法线而不是顶点

时间:2014-02-21 22:19:54

标签: opengl assimp

我有一个Vertex数据类型,包括position(3),texture(2)和vertex normal(3)。我使用glVertexAttribPointer将这些传递给vertex shader(请参阅here)。

不幸的是,无论我加载什么模型,它都给了我死星 - 基本上是一个顶点球体,只有当我切换到线框渲染时才能看到它。

我尝试从我的模块中删除一堆顶点,最终得到了部分构造的死星。在这一点上,很明显它正在绘制法线,好像它们是顶点。我不知道顶点是否正在绘制。

我通过drawing two additional triangles确认了我的假设 - 一个代表顶点应该的位置,另一个代表法线。我还将它们缩放到1.1,这样它们就可以与物体本身区分开来。是的,它肯定是绘制法线而不是顶点。

有谁知道为什么?我已经尝试在着色器中切换属性的顺序,但这没有帮助(奇怪)。

Here's the complete minimum working example以及两个测试对象(完整,n20r4_d5.obj;非常局部,test11.obj)。

1 个答案:

答案 0 :(得分:4)

您正在使用OpenGL 2.1,因此您必须使用glGetAttribLocation()来提取属性索引。你不能只希望GLSL编译器将0和texcoords放在2上的顶点:

void render(Shader* shader_program = NULL) 
{
    if (shader_program) 
        shader_program->bind();

    GLint position_loc = glGetAttribLocation( shader_program->id(), "position" );
    GLint tex_loc = glGetAttribLocation( shader_program->id(), "tex" );
    GLint normal_loc = glGetAttribLocation( shader_program->id(), "normal" );

    glEnableVertexAttribArray( position_loc );
    glEnableVertexAttribArray( normal_loc );
    glEnableVertexAttribArray( tex_loc );

    for (size_t i = 0; i < entries.size(); ++i) 
    {
        glBindBuffer(GL_ARRAY_BUFFER, entries[i].vb);

        // I think this tells it where to look for the vertex information we've loaded.
        glVertexAttribPointer(position_loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
        glVertexAttribPointer(normal_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12); // starts at 12 because 3 floats for position before 2 floats for normal
        glVertexAttribPointer(tex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)20); // makes room for 5 floats
        ...

在链接着色器之前,你也可以告诉 OpenGL把它们放在哪里(glBindAttribLocation()),但是你设置的东西会让你有点混乱。

在OpenGL 3.1+中,您可以强制编译器通过layout qualifier将属性放在特定索引上。