顶点缓冲区对象和数据缓冲区[OpenGL]

wixjitnu  于 2022-10-18  发布在  其他
关注(0)|答案(1)|浏览(248)

我正在试图弄清楚如何使用与单个顶点数组对象相关联的多个缓冲区,基于每个对象模型(例如,垂直度、法线、纹理)一个缓冲区。为了简单起见,在下面的示例代码中,我有两个对象,它们只由一个三角形(3个顶点)和相关颜色组成。由ArrayBuffer1索引的缓冲区元素接收顶点坐标(均匀坐标)和RGBA颜色向量。由ArrayBuffer2索引的缓冲区元素也是如此。
顶点着色器是一个通过,如下所示


# version 400 core

    layout( location = 0 ) in vec4 vPosition;
    layout( location = 1 ) in vec4 vColor;
    out vec4 color;
    void
    main()
    {
        color= vColor;
        gl_Position = vPosition;
    }

碎片着色器是一种很好的穿透


# version 450 core

    in vec4 color;
    out vec4 fColor;

    void main()
    {
        fColor = color; 
    }

我想传递数据,每个对象有一个缓冲区,将顶点属性分组在同一缓冲区中。
我想不出这两件东西是怎么加工的。以下是客户端代码(init部分)

enum VertexDim { xDim, yDim, zDim, wDim, NumDim};
    enum VAO_IDs { Triangles, NumVAOs };
    enum Buffer_IDs { ArrayBuffer1, ArrayBuffer2, NumBuffers };
    enum Attrib_IDs { vPosition = 0, vColor=1 };

    GLuint  VAOs[NumVAOs];
    GLuint  Buffers[NumBuffers];

    const GLuint  NumVertices = 6;
    const GLuint curDim= NumDim;
    // first triangle 
    GLfloat  static_vertices1[NumVertices/2][NumDim] = {
        { -0.90f, -0.90f, 0.5f, 1}, {  0.85f, -0.90f, 0.3f, 1 }, { -0.90f,  0.85f, 0.0f, 1 }  // Triangle 1
    };
    // second triangle
    GLfloat  static_vertices2[NumVertices/2][NumDim] = {
        {  0.90f, -0.85f, -0.1f, 1 }, {  0.90f,  0.90f, -0.5f, 1 }, { -0.85f,  0.90f, -0.8f, 1 }   // Triangle 2
    };
    // a base color from which to compute different vertex colors
    GLfloat infColor_value[4]= {0.9f, 0.7f, 0.5f, 1.0f};  

    //----------------------------------------------------------------------------
    //
    // init
    //

    void
    init( void )
    {   
        const unsigned int n=NumVertices/2;
        GLfloat infColor_values1[n][curDim];    
        GLfloat infColor_values2[n][curDim];  
        // compute different vertex colors from base color   infColor_value
        // .. loop over    infColor_values1 and infColor_values2

        ShaderInfo  shaders[] =
        {
            { GL_VERTEX_SHADER, "media/shaders/triangles/triangles2.vert" },
            { GL_FRAGMENT_SHADER, "media/shaders/triangles/triangles2.frag" },
            { GL_NONE, NULL }
        };
        // LoadShaders is a wrapper to load, compile code and link shaders
        GLuint program = LoadShaders( shaders );
        if( program == 0) { std::cerr<<"shader program failed to build" << std::endl; }
        glUseProgram( program );

        glGenVertexArrays( NumVAOs, VAOs );
        glBindVertexArray( VAOs[Triangles] );
        glCreateBuffers( NumBuffers, Buffers );

        // vertex 1
        glBindBuffer( GL_ARRAY_BUFFER, Buffers[ArrayBuffer1] );
        glNamedBufferData( Buffers[ArrayBuffer1], sizeof(static_vertices1)+sizeof(infColor_values1) , NULL, GL_STATIC_DRAW);
        glNamedBufferSubData( Buffers[ArrayBuffer1], 0,  sizeof(static_vertices1), static_vertices1);
        glNamedBufferSubData( Buffers[ArrayBuffer1], sizeof(static_vertices1),  sizeof(infColor_values1), infColor_values1);

        GLuint64 offset = 0;
        glVertexAttribPointer( vPosition, NumDim, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
        glEnableVertexAttribArray( vPosition );
        offset = sizeof(static_vertices1);
        glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)offset );
        glEnableVertexAttribArray( vColor );

        // vertex 2 
        glBindBuffer( GL_ARRAY_BUFFER, Buffers[ArrayBuffer2] );       
        glNamedBufferData( Buffers[ArrayBuffer2], sizeof(static_vertices2)+sizeof(infColor_values2) , NULL, GL_STATIC_DRAW);
        glNamedBufferSubData( Buffers[ArrayBuffer2], 0,  sizeof(static_vertices2), static_vertices1);
        glNamedBufferSubData( Buffers[ArrayBuffer2], sizeof(static_vertices2),  sizeof(infColor_values2), infColor_values2);

        offset = 0;
        glVertexAttribPointer( vPosition, NumDim, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
        glEnableVertexAttribArray( vPosition );
        offset = sizeof(static_vertices2);
        glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)offset );
        glEnableVertexAttribArray( vColor );

        glBindBuffer( GL_ARRAY_BUFFER, 0 );
        glBindVertexArray(0);
    }

下面是要呈现的代码

void
display( void )
{
    static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };

    glClearBufferfv(GL_COLOR, 0, black);

    glBindVertexArray( VAOs[Triangles] );
    glDrawArrays( GL_TRIANGLES,  0, NumVertices );
    glBindVertexArray(0);    
}

总而言之:**如何将对象的顶点属性存储在单个缓冲区中,同时仍然显示多个对象?**我可以在相同的子缓冲区中获取所有内容(一个用于顶点坐标,一个用于vetex颜色),但我想不出一个解决方案来减少要渲染的对象。
我已经阅读了与这个问题相关的封闭答案(Architecture to draw many different objects in OpenGLWhat are Vertex Array Objects?),但它没有回答我的问题。

tpgth1q7

tpgth1q71#

为每个对象定义一个VAO使其遵循@Rabbid76建议
更改初始化代码

enum Buffer_IDs { Mesh, NumBuffers };

    //....

        // triangle 1
        glBindBuffer( GL_ARRAY_BUFFER, Buffers1[Mesh] );
        glNamedBufferData( Buffers1[Mesh], sizeof(static_vertices1)+sizeof(infColor_values1) , NULL, GL_STATIC_DRAW);
        glNamedBufferSubData( Buffers1[Mesh], 0,  sizeof(static_vertices1), static_vertices1);
        glNamedBufferSubData( Buffers1[Mesh], sizeof(static_vertices1),  sizeof(infColor_values1), infColor_values1);

        GLuint64 offset = 0;
        glVertexAttribPointer( vPosition, NumDim, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
        glEnableVertexAttribArray( vPosition );
        offset = sizeof(static_vertices1);
        glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)offset );
        glEnableVertexAttribArray( vColor );

        glBindBuffer( GL_ARRAY_BUFFER, 0 );
        glBindVertexArray(0);

        // triangle 2
        glBindVertexArray( VAOs[Triangle2] );
        glCreateBuffers( NumBuffers, Buffers2 );
        glBindBuffer( GL_ARRAY_BUFFER, Buffers2[Mesh] );
        glNamedBufferData( Buffers2[Mesh], sizeof(static_vertices2)+sizeof(infColor_values2) , NULL, GL_STATIC_DRAW);
        glNamedBufferSubData( Buffers2[Mesh], 0,  sizeof(static_vertices2), static_vertices2);
        glNamedBufferSubData( Buffers2[Mesh], sizeof(static_vertices2),  sizeof(infColor_values2), infColor_values2);

        offset = 0;
        glVertexAttribPointer( vPosition, NumDim, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
        glEnableVertexAttribArray( vPosition );
        offset = sizeof(static_vertices2);
        glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)offset );
        glEnableVertexAttribArray( vColor );

对呈现代码进行更改

void
    display( void )
    {
        static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };

        glClearBufferfv(GL_COLOR, 0, black);

        glBindVertexArray( VAOs[Triangle1] );
        glDrawArrays( GL_TRIANGLES,  0, NumVertices/2 );
        glBindVertexArray( VAOs[Triangle2] );
        glDrawArrays( GL_TRIANGLES,  0, NumVertices/2 );   
        glBindVertexArray(0);    
    }

相关问题