1

我正在准备一些带有 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 是浮点数组。要绘制我绑定的缓冲区,请激活客户端状态: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( );
    }
}
4

1 回答 1

2

您似乎在更新缓冲区对象时指定了属性指针。这不是它的工作方式。顶点属性指针是(取决于 GL 版本)全局状态或每个 VAO 状态,但绝不是每个 VBO 状态。目前,当你做类似的事情时

bufferA.CopyToGPU();
bufferB.CopyToGPU();
while(true) {
    bufferA.render();
    bufferB.render();
}

只有缓冲区 B 将被使用(留下超出边界访问的可能性,因为您认为在渲染它时使用缓冲区 A),因为顶点数组状态在第二次调用中设置为缓冲区 B,覆盖在第一次打电话。您需要在绘制每个对象时重新指定指针,或者使用顶点数组对象来封装这些指针。请注意,后一个路径在 GL >= 3.X 核心配置文件上是必需的。

于 2013-05-27T22:22:20.467 回答