O objeto Framebuffer não é realmente um buffer, mas um objeto agregador que contém um ou mais anexos que, por sua vez, são os buffers reais. Você pode entender o Framebuffer como estrutura C, onde cada membro é um ponteiro para um buffer. Sem nenhum anexo, um objeto Framebuffer tem uma pegada muito baixa.
Agora, cada buffer anexado a um Framebuffer pode ser um Renderbuffer ou uma textura .
O Renderbuffer é um buffer real (uma matriz de bytes, números inteiros ou pixels). O Renderbuffer armazena valores de pixel em formato nativo, por isso é otimizado para renderização fora da tela. Em outras palavras, desenhar em um Renderbuffer pode ser muito mais rápido que desenhar em uma textura. A desvantagem é que os pixels usam um formato nativo dependente da implementação, de modo que a leitura de um Renderbuffer é muito mais difícil do que a leitura de uma textura. No entanto, uma vez que um Renderbuffer tenha sido pintado, pode-se copiar seu conteúdo diretamente para a tela (ou para outro Renderbuffer , eu acho), muito rapidamente, usando operações de transferência de pixels. Isso significa que um Renderbuffer pode ser usado para implementar eficientemente o padrão de buffer duplo que você mencionou.
Renderbuffers são um conceito relativamente novo. Antes deles, um Framebuffer era usado para renderizar em uma textura , que pode ser mais lenta porque uma textura usa um formato padrão. Ainda é possível renderizar uma textura, e isso é bastante útil quando é necessário executar várias passagens sobre cada pixel para criar uma cena ou desenhar uma cena na superfície de outra cena!
O wiki do OpenGL possui esta página que mostra mais detalhes e links.