如何在客户端顶点数组中指定顶点属性?

How to specify vertex attributes in client-side vertex array?

我正在将 OpenGL 3.X 代码移植到 OpenGL 2.1,其中没有可用的 VAO。下面的代码使我的程序在 glDrawElements 调用时立即在图形驱动程序中崩溃。

部分代码在3.X和2.1模式之间共享,在上面的OpenGL3.X中可以正常工作。

struct StrokeVertex
{
    glm::vec2 position;
    glm::vec2 tangent;
    float center_dist;
};

if (use_gl3)
    bind_vao();

bind_vbo();
bind_ibo();
send_data();
bind_program();
set_uniforms();

// setup client-side vertex array here
if (!use_gl3)
{
    glEnableClientState( GL_VERTEX_ARRAY );
    GLHELPER_CHECK;
        
    glEnableVertexAttribArray( 0 );
    GLHELPER_CHECK;
    glVertexAttribPointer( get_attribute_location( "tangent" ) /* got 1 here */, 2, GL_FLOAT, GL_FALSE, sizeof( StrokeVertex ), (void*) offsetof( StrokeVertex, tangent ) );
    GLHELPER_CHECK;
        
    glEnableVertexAttribArray( 1 );
    GLHELPER_CHECK;
    glVertexAttribPointer( get_attribute_location( "center_dist" ) /* got 2 here */, 1, GL_FLOAT, GL_FALSE, sizeof( StrokeVertex ), (void*) offsetof( StrokeVertex, center_dist ) );
    GLHELPER_CHECK;

    // I also tried call this before setting the two attributes
    glVertexPointer( 2, GL_FLOAT, sizeof( StrokeVertex ), (void*) offsetof( StrokeVertex, position ) );
    GLHELPER_CHECK;
}

// immediately crash here
glDrawElements( GL_TRIANGLES, GLsizei( n_elem ), GL_UNSIGNED_INT, nullptr );
GLHELPER_CHECK;

if (!use_gl3)
{
    glDisableClientState( GL_VERTEX_ARRAY );
}
else
{
    unbind_vao();
}

以及OpenGL的vertex shader部分3.X和2.X。大部分都是相同的期望属性声明:

in vec2 logic_pos;
in vec2 tangent;
in float center_dist;

OpenGL 2.X:

// builtin gl_Vertex is used, so we omit logic_pos
attribute vec2 tangent;
attribute float center_dist;

启用哪些顶点属性和绑定哪些数据似乎不匹配:

下面的代码告诉 OpenGL 它应该启用顶点属性 0,但数据被绑定到属性 1(至少根据注释)。

glEnableVertexAttribArray( 0 );
glVertexAttribPointer( get_attribute_location( "tangent" ) /* got 1 here */, 2, GL_FLOAT, GL_FALSE, sizeof( StrokeVertex ), (void*) offsetof( StrokeVertex, tangent ) );

总的来说,您的代码看起来好像启用了属性 0 和 1,但将数据绑定到 1 和 2。

如果您启用了属性但未将任何数据绑定到它们,这可能会导致您描述的崩溃。