GL缓冲区设置为GL_STATIC_DRAW但需要发送每一帧

时间:2013-05-27 15:23:58

标签: c++ opengl vbo

我正准备一些带有2f顶点,2f texvertices和4f颜色的缓冲区。它显示正确。整件事都在一堂课上。如果我有更多的实例(每个生成它自己的缓冲区id,从未传递过函数,所以它没有被清理,只在第一次绘制时被包装为std :: list中的指针)(在第一次使用gdb绘制后暂停,我看到所有缓冲的东西)所有缓冲的数据都是可见的。在下一次绘制中,只有最后绘制的缓冲区可见。

我通过生成,绑定然后使用此调用用数据填充缓冲区来准备它们:

glBufferData( GL_ARRAY_BUFFER, Size * 8 * sizeof( float ), f, GL_STATIC_DRAW );

其中Size是std :: size_t,其顶点数为f,float-Array为f。要绘制缓冲区,我将其绑定,激活客户端状态:GL_VERTEX_ARRAY,GL_TEXTURE_COORD_ARRAY,GL_COLOR_ARRAY。

glDrawArrays( Mode, 0, Size );

其中Mode是带有GL_TRIANGLES的GLenum。

我通过在glDrawArrays每帧之前调用glBufferData来修复它,但这不是它应该如何。它应该是生成,绑定,填充,然后通过绑定和调用glDrawArrays来绘制,不是吗?

如有必要:我在Windows 7 x64上使用C ++,gcc。 我被要求提供更多代码:

void Buffer::CopyToGPU( )
{
    glBindBuffer( GL_ARRAY_BUFFER, Object );
    float* f = new float[ Size * 8 ];
    for ( std::size_t s( 0 ) ; s < Size ; ++s )
        CopyVertexToFloatArray( &f[ s * 8 ], Vortex[ s ] );
    glBufferData( GL_ARRAY_BUFFER, Size * 8 * sizeof( float ), f, GL_STATIC_DRAW );
    delete[] f;

    glVertexPointer( 2, GL_FLOAT, 8 * sizeof( float ), NULL );
    glTexCoordPointer( 2, GL_FLOAT, 8 * sizeof( float ), (char*)( 2 * sizeof( float ) ) );
    glColorPointer( 4, GL_FLOAT, 8 * sizeof( float ), (char*)( 4 * sizeof( float ) ) );
}
void Buffer::Render( )
{
    glBindBuffer( GL_ARRAY_BUFFER, Object );
    glEnableClientState( GL_VERTEX_ARRAY );
    glEnableClientState( GL_TEXTURE_COORD_ARRAY );
    glEnableClientState( GL_COLOR_ARRAY );

    //Actually draw the triangle, giving the number of vertices provided
    glDrawArrays( Mode, 0, Size );

    glDisableClientState( GL_VERTEX_ARRAY );
    glDisableClientState( GL_TEXTURE_COORD_ARRAY );
    glDisableClientState( GL_COLOR_ARRAY );
}
int main( ... ) // stripped buffer sfml2 initialization etc.
{
    glClearColor( 0, 0, 0, 1 );

    glEnable( GL_ALPHA_TEST );
    glAlphaFunc( GL_GREATER , 0.1 );
    glEnable( GL_TEXTURE_2D );
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

    while ( win.isOpen( ) ) // sf::Window
    {
        /// draw
        glClear( GL_COLOR_BUFFER_BIT );
        MVP.Apply( );
        CallDraw( );
        win.display( );
    }
}

1 个答案:

答案 0 :(得分:2)

您似乎在更新缓冲区对象时指定了attrib指针。这不是它的工作原理。顶点属性指针(取决于GL版本)是全局状态或每个VAO状态,但从不是每个VBO状态。目前,当您执行类似

的操作时
bufferA.CopyToGPU();
bufferB.CopyToGPU();
while(true) {
    bufferA.render();
    bufferB.render();
}

只使用缓冲区B(在渲染时你可以使用缓冲区A保留外部边界访问的可能性),因为顶点数组状态在第二次调用中设置为缓冲区B,覆盖任何attrib指针在第一个电话中设置。您需要在绘制每个对象时重新指定指针,或使用“顶点数组对象”来封装这些指针。请注意,后一个路径在GL&gt; = 3.X核心配置文件中是必需的。