进一步使用 模板缓冲(stencil)

  

  最近作课题的时候须要计算一个 view(就是一次渲染获得的帧) 下的重叠像素个数(两个物体或更多的物体重叠)。ui

  • 最开始个人想法是渲染一个物体输出一张纹理,这样对比物体之间的纹理就知道重叠了。可是这样当物体不少的时候须要输出太多的纹理到CPU,太慢了,也很麻烦。
  • 后来和同窗讨论了一下,以为是否是可使用一张纹理做为帧缓冲的输出,同时做为片断着色器的输入,这样能够每渲染一个像素点加1,最终大于1的位置表示重叠。可是后来这样试了,在片断着色器中采样这张纹理的时候,采样出来的值明显不对,没有随着渲染一个物体后再次采样会逐步积累增长。(感受由于是同一张纹理,可是是输入和输出,在GPU中分配了两个存储位置,各自使用本身的,因此没有叠加,我瞎猜的……)
  • 后来查到仿佛可使用累积缓冲,每次渲染的结果叠加在一块儿,可是须要加权,value = α*value + (1-α)*newvalue ,感受不太好操做,放弃了。
  • 最后看了一下stencil,发现能够实现我须要的功能。虽然几个月前看过一次,可是当时没有太懂,此次算是理解了。

  

  如今再来回顾一下 Stencil 的用法:this

  • glStencilMask(value) 位遮罩, value=0x00表示模板缓冲不可写入;value=0xFF表示能够写入。
  • void glStencilFunc(GLenum func, GLint ref, GLuint mask)  指定ref值与存储的模板值对比
  • void glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) 指定模板值的写入策略

  

  流程代码spa

        glEnable(GL_DEPTH_TEST);
        glEnable(GL_STENCIL_TEST);
        glStencilMask(0xFF); //开启模板写入 (清空模板缓冲须要开启模板写入!!!)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // 咱们如今使用模板缓冲
        glStencilOp(GL_INCR, GL_INCR, GL_INCR);
        glStencilMask(0x00); //关闭模板写入
        this->DrawSkyBox(false);
        this->DrawFloor(false);
        glStencilFunc(GL_ALWAYS, 1, 0xFF);
        glStencilMask(0xFF); //开启模板写入
        this->DrawBuildings(false);  // 先渲染building,shader中的编号保持一致,可是sky必定在前
        glStencilMask(0x00); //关闭模板写入

  遇到的坑是清空模板缓冲前必定要开启模板写入!!!code

 

  模板值读取:blog

    这个耽搁了好久,开始是附加模板纹理到帧缓冲中,而后从纹理中读取值,可是怎么都读出来不对……ci

    后来发现能够直接使用其API读取   glReadPixels 。模板

    使用此API读取时,其是直接面向当前帧缓冲获取模板值数据,故与模板生成方式无关,能够是默认屏幕的帧缓冲,也可使本身生成的帧缓冲(能够是RBO模板缓冲、模板缓冲纹理、深度-模板缓冲纹理)。class

float* WKS::Texture::GetStencilData(GLuint width, GLuint height) {
    float* pixels = new float[width * height];
    glReadPixels(0, 0, width, height, GL_STENCIL_INDEX, GL_FLOAT, pixels);
    return pixels;
}

  必定要记得在对应的帧缓冲中使用。渲染

相关文章
相关标签/搜索