OpenGL(九)使用 FrameBufferObject

栏目: 编程工具 · 发布时间: 7年前

内容简介:OpenGL(九)使用 FrameBufferObject

在OpenGL中所有的图形,都会绘制到 FrameBufferObject 上。如果想使用界面的做分屏渲染,或需要屏幕图像制成贴图以备后期处理,就需要用到 FrameBufferObject 技术,这种方式也被称为 RTT (Render to Texture)。

原理

通过

glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,colorBuffer,0);
 

可以将ColorBuffer绑定到一张Texture上。当然也可以绑定到多张贴图中。另外使用这个函数也可以取出深度贴图。

当生成了自己的fbo之后,即可将图元绘制到贴图上面,可以理解为是一个预渲染的过程。

glBindFramebuffer(GL_FRAMEBUFFER,fbo);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
draw();
glBindFramebuffer(GL_FRAMEBUFFER,0);
 

然后在实际渲染时使用fbo中的贴图进行绘制。

实现

创建一个产生fbo的函数,并返回ColorBuffer与depthBuffer

GLuintCreateFrameBufferObject(GLuint &colorBuffer,int width,int height)
{
    GLuintfbo;
    glGenFramebuffers(1,&fbo);
    glBindFramebuffer(GL_FRAMEBUFFER,fbo);
 
    //color buffer
    glGenTextures(1,&colorBuffer);
    glBindTexture(GL_TEXTURE_2D,colorBuffer);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,nullptr);
    glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,colorBuffer,0);
    glBindTexture(GL_TEXTURE_2D,0);
 
    GLenumstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if(status != GL_FRAMEBUFFER_COMPLETE)
    {
        printf("FBO Create Fail\n");
    }
    glBindFramebuffer(GL_FRAMEBUFFER,0);
    return fbo;
}
 

接着创建另一个program来做平面承接fbo中的texture。

//create fbo
GLuintcolorBuffer;
GLuintfbo = CreateFramebufferObject(colorBuffer, width, height);
 
//main draw
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
RenderFullScreenQuad();
glFlush();
 
autodraw = [&]()->void
{
    //draw work
}
 
autoRenderFullScreenQuad = [&]()->void
{
    glUseProgram(fsqprogram);
 
    glBindTexture(GL_TEXTURE_2D, colorBuffer);
    glUniform1i(fsqtextureLocation, 0);
    glBindVertexArray(fsqvao);
 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, fsqibo);
    glDrawElements(GL_TRIANGLES, fsqindexCount, GL_UNSIGNED_INT, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
    glBindVertexArray(0);
    glUseProgram(0);
};
 
 

最后在shader中做一个全屏的面片,如果是标准的0.5为模型空间坐标的Quad可以简单的使用:

attributevec3pos;
attributevec2texcoord;
attributevec3normal;
 
uniformmat4 M;
uniformmat4 V;
uniformmat4 P;
 
varyingvec2V_Texcoord;
 
void main()
{
    vec4position=vec4(pos.x*2,pos.y*2,pos.z,1.0);
    V_Texcoord=texcoord;
    gl_Position=position;
}
 

来制作一个全屏的面片,最终将贴图贴到面片上即可。这部分的实现可以参考之前的文章: OpenGL(三) 加载贴图

总结

通过 FrameBufferObject (或称为RTT) 可以将画面抓到一张贴图中,有了这张图,我们就可以做很多后期处理的效果。

OpenGL(九)使用 FrameBufferObject

本文出自松阳论道 转载必须注明出处


以上所述就是小编给大家介绍的《OpenGL(九)使用 FrameBufferObject》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

测试驱动的JavaScript开发

测试驱动的JavaScript开发

Christian Johansen / 赵勇、程德、凌杰、高博 / 机械工业出版社 / 2012-2-9 / 69.00元

本书是一本完整的、基于最佳实践的JavaScript敏捷测试指南,同时又有着测试驱动开发方法(TDD)所带来的质量保证。领先一步的JavaScript敏捷开发者Christian Johansen的讨论涵盖了将最先进的自动化测试用于JavaScript开发环境的方方面面,带领读者走查整个开发的生命周期,从项目启动到应用程序部署。本书的主要内容包括:掌握自动化测试和TDD;构建有效的自动化测试工作流......一起来看看 《测试驱动的JavaScript开发》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具