简单了解 VBO,FBO

作者: osbornZ | 来源:发表于2018-09-16 12:18 被阅读6次

    OpenGL是个状态机,我们通常见到的glEnable - glDisable函数就是通知OpenGL开启/关闭某种状态的,譬如光照、深度检测等等,故此得名。

    VBO (Vertex buffer object)

    VBO就是通过几个函数,是显卡存储空间里一块缓存区BUFFER,用于存储和顶点以及其属性相关的信息(顶点信息,颜色信息,法线信息,纹理坐标信息和索引信息等),那么为什么会产生这种方式呢?

    解决什么问题: 由于最早的openGL不支持实例化绘制,导致在绘制大量相似图元的时候,需要反复向GPU提交代码渲染,这点在OpenGL中的二次方图元和实例化绘制已经提到过了,会严重导致瓶颈效应。

    VBO其实就是显卡中的显存,为了提高渲染速度,可以将要绘制的顶点数据缓存在显存中,这样就不需要将要绘制的顶点数据重复从CPU发送到GPU, 浪费带宽资源。

    VBO + IBO

    const GLubyte Indices[] = {
    0, 1, 2,
    2, 3, 0
    };

    初始化:

     1. glGenBuffers(1, &_vboID);  //生成一个句柄
     2. glBindBuffer(GL_ARRAY_BUFFER, _vboID); //绑定
       //copy the data into the buffer object
    3. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    

    使用:

    glEnableVertexAttribArray(_positionSlot);
    glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
    
    glEnableVertexAttribArray(_colorSlot);
    glVertexAttribPointer(_colorSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), NULL+sizeof(GL_FLOAT)*3);
    
    glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]),
                   GL_UNSIGNED_BYTE, 0);
    

    清除:

    glDeleteBuffers(1,&nVBOVertices); //删除句柄,同时删除server端顶点缓冲
    

    Demo-新增VBO绘制方式

    VAO (Vertex Array object)

    在 GL3.0开始的新标准,你大概会留意到传统的绘图方式(glVertex)已经要被废掉了,不仅如此,以最高绘制速度为标记的显示列表方式也已经被印上deprecated了。
    GL3.0时代新增了很多辅助役,VAO则是一个容器,可以包括多个VBO, 它类似于以前的call list, 由于它进一步将VBO容于其中,所以绘制效率将在VBO的基础上更进一步。

    使用方式上,也是和 VBO 大抵差不多。

    FBO (Frame Buffer Object)

    FBO

    FBO出现之前,我们是怎么离屏渲染的呢?

    1. 前面提到的glCopyTexImage2D;
    2. glDrawBuffers(size, *p)。

    可以把在帧缓冲渲染转移到离屏off screen中, 使用FBO的优点

    • FBOs aren’t limited to the size of your window.
    • Textures can be attached to FBOs, allowing direct rendering to textures without an explicit glCopyTexImage.
    • FBOs can contain multiple color buffers, which can be written to simultaneously from a fragment shader.

    “帧缓存关联图像”

    纹理图像(texture images)和渲染缓存图像(renderbuffer images)。如果纹理对象的图像数据关联到帧缓存,OpenGL执行的是“渲染到纹理”(render to texture)操作。如果渲染缓存的图像数据关联到帧缓存,OpenGL执行的是离线渲染(offscreen rendering).

    整个过程是这样的:

    在预处理中,新建一个FBO对象,用Bind绑定到当前(这些BIND之类函数一般是表示“你接下来要处理这个对象啦”的意思),给FBO输入渲染缓存或纹理,检查FBO状态是否正确,再脱离绑定。渲染过程,在需要它时再一次绑定,指定把接下来的内容渲染到它里面的哪一个渲染缓存或纹理......脱离绑定,使用之。

    glGenFramebuffers(1, &_framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
    

    注意点:

    • 切换渲染到屏幕和FBO需要, glBindFramebuffer(GL_FRAMEBUFFER,0)
    • openGL渲染的东西会保留,所以切换也需要进行 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT|...)

    RBO (Render Buffer Object)

    RBO 是一块2D图像缓存,能够用于存储color,depth,stencil值,也就是可以作为
    fbo的color或depth或stencil attachment。但是这个rbo不能直接作为纹理使用。

    http://blog.csdn.net/ldpxxx/article/details/17304273

    renderbufferStorage 关联屏幕渲染, 缓冲区中最后显示在屏幕[_context presentRenderbuffer: GL_RENDERBUFFER ];

    PBO (Pixel Buffer Object)

    待续......

    参考:
    VBO
    FBO
    PBO

    相关文章

      网友评论

        本文标题:简单了解 VBO,FBO

        本文链接:https://www.haomeiwen.com/subject/pdnxnftx.html