6 Introduce stencil buffer

    技术2022-05-20  33

    模板测试: 模板测试最经典的用途是,将屏幕上不规则的区域屏蔽掉,防止在该区域中绘图。比如需要在场景中绘制一面镜子及它反射的物体。即可以绘制镜子以形成模板缓存,然后绘制场景中的物体,只有可以通过模板测试(也即是在镜子中)的东西才会绘制出来。 流程如下:http://www.cppblog.com/lovedday/archive/2008/03/19/44875.html 1、正常渲染所有的场景——地板,墙,镜子和茶壶——不包含反射的茶壶。注意这一步没有修改模板缓存。 2、清除模板缓存为0。图8.3显示了后台缓存和模板缓存。 3、渲染只有镜子部分的图元到模板缓存中。设置模板测试总是成功,并且假如测试成功就指定模板缓存入口为1。我们仅仅渲染镜子,在模板缓存中的所有像素都将为0,除了镜子部分为1以外。图8.4显示了更新以后的模板缓存。也就是说,我们在模板缓存中对镜子像素做了标记。 4、现在我们渲染被反射的茶壶到后台缓存和模板缓存中。但是假如模板测试通过,我们就只渲染后台缓存。假如在模板缓存中的值为1,那么我们设置模板测试通过。这样,茶壶就仅仅被渲染到模板缓存为1的地方了。因为只有镜子对应的模板缓存值为1,所以反射的茶壶就只能被渲染到镜子里。 下面这个例子:

    先画圆柱体外面的球,然后通过“画”圆柱体来生成模板,再绘制球(只有通过前面生成的模板的测试能被画出来,并且这次选择显示球的内表面。),再画了两次圆柱体(这次是真正的画,而且要画两次是由于半透的原因,要画一次正面一次反面)。 OpenGL ES 示例代码: RenderLoop: {     // Clear the color, depth and stencil buffers     // 清空一些buffer     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);             // render Sphere outside the stencil volume     // 画球     m_Sphere.DrawMesh(0);         // only the stencil test and depth test pass will mark the stencilbuffer value !0.     // 得到模板缓存,只有嵌入到圆柱体的部分才被标记     glEnable(GL_STENCIL_TEST);     glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );     glDepthMask(GL_FALSE);     glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);     glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP);     glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);     glUniformMatrix4fv(m_ShaderProgram.auiLoc[eMVPMatrix], 1, GL_FALSE, mCylinder.ptr());     m_Cylinder.DrawMesh(0);         // render the sphere again, only the pixel inside the stencil volume will been draw     // 画球,只有在圆柱体内部分才会被显示     glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);     m_Sphere.DrawMesh(0);         // Draw back faces of the cylinder     // 绘制圆柱体     glCullFace(GL_FRONT);     m_Cylinder.DrawMesh(0);     // Draw the front faces     glCullFace(GL_BACK);     m_Cylinder.DrawMesh(0); }

     


    最新回复(0)