25.OpenGL--帧缓冲区

来源:互联网 发布:宿舍管理系统java 编辑:程序博客网 时间:2024/05/21 21:34
  • 理论基础 
    1,帧缓冲区(显存):是由像素组成的二维数组,每一个存储单元对应屏幕上的一个像素,整个帧缓冲对应一帧图像即当前屏幕画面。帧缓冲通常包括:颜色缓冲,深度缓冲,模板缓冲和累积缓冲。这些缓冲区可能是在一块内存区域,也可能单独分开,看硬件。而像素数据在进入帧缓冲之前(称为片段)必须通过一系列测试才能写入帧缓冲,如果片段在其中某个测试没有通过,后面的测试或操作都将不再进行。这些测试或操作流程是:开始(片段)-裁剪测试-alpha测试-模板测试-深度测试-混合-抖动-逻辑操作-结束(写入帧缓冲). 
    2,创建帧缓冲区对象:前面章节讲过OpenGL一般的缓冲区对象,主要是优化性能。而帧缓冲区对象除了优化性能还增加了一些功能,类似GDI中的辅助DC,和系统的帧缓冲区一样也是保存当前屏幕图像,只是它是后台保存看不见。具体它可以关联纹理对象(即颜色缓冲区)和渲染缓冲对象(Renderbuffer有深度缓冲和模板缓冲)来组成自己后台的帧缓冲区。例如,渲染动态纹理,多屏实现等。 
    这里写图片描述

注释:帧缓冲可能是GPU专属内存,也可能是GPU和CPU共享内存,看硬件。手机一般是共享内存,PC独立显卡一般是专属内存,集成显卡是共享内存。


  • 实例代码 
    完整源码地址入口

1,创建帧缓冲区对象

void init(){    // 创建纹理对象内存空间    glGenTextures(1, &textureId);    glBindTexture(GL_TEXTURE_2D, textureId);    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);//开启多级纹理    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);    glBindTexture(GL_TEXTURE_2D, 0);//解除绑定(好的习惯:用完就关闭,哪里用哪里开)     // 创建帧缓冲对象    glGenFramebuffers(1, &fboId);//没有空间的,需要关联纹理对象或渲染缓冲对象才有意义    glBindFramebuffer(GL_FRAMEBUFFER, fboId);    //用渲染缓冲对象创建了一个深度缓冲区    glGenRenderbuffers(1, &rboId);    glBindRenderbuffer(GL_RENDERBUFFER, rboId);    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, TEXTURE_WIDTH, TEXTURE_HEIGHT);    glBindRenderbuffer(GL_RENDERBUFFER, 0);//临时解绑    // 关联到纹理    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);    // 关联到深度缓冲区    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId);    glBindFramebuffer(GL_FRAMEBUFFER, 0);//临时解绑}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

2,使用

//动态纹理贴图:使用帧缓冲对象效率要明显提高void displayCB(){    //使用帧缓冲对象(直接渲染到绑定的纹理对象)    if(fboUsed)    {        // 激活当前帧缓冲对象        glBindFramebuffer(GL_FRAMEBUFFER, fboId);        glClearColor(1, 1, 1, 1);        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);        glPushMatrix();        glRotatef(angle*0.5f, 1, 0, 0);        glRotatef(angle, 0, 1, 0);        glRotatef(angle*0.7f, 0, 0, 1);        glTranslatef(0, -1.575f, 0);        drawTeapot();//绘制动态茶壶        glPopMatrix();        glBindFramebuffer(GL_FRAMEBUFFER, 0); // 用完解绑    }    // 没有使用帧缓冲对象(先渲染到后天缓冲再copy到纹理)    else    {        glClearColor(1, 1, 1, 1);        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);        glPushAttrib(GL_COLOR_BUFFER_BIT | GL_PIXEL_MODE_BIT);        glDrawBuffer(GL_BACK);        glReadBuffer(GL_BACK);        glPushMatrix();        glRotatef(angle*0.5f, 1, 0, 0);        glRotatef(angle, 0, 1, 0);        glRotatef(angle*0.7f, 0, 0, 1);        glTranslatef(0, -1.575f, 0);        drawTeapot();        glPopMatrix();        // copy缓冲区的像素到纹理        glBindTexture(GL_TEXTURE_2D, textureId);        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT);        glBindTexture(GL_TEXTURE_2D, 0);        glPopAttrib();    }    glClearColor(0, 0, 0, 0);    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);    // 绘制立方体(纹理贴图)    draw();    glutSwapBuffers();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

这里写图片描述

0 0
原创粉丝点击