首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用glBlendFunc掩蔽,没有帧缓冲区

使用glBlendFunc掩蔽,没有帧缓冲区
EN

Stack Overflow用户
提问于 2014-03-19 19:43:18
回答 1查看 324关注 0票数 0

我希望这是可能的,不使用帧缓冲区或着色器,只要直接使用glBlendFunc或glBlendFuncSeparate。

我通常用我的标准混合模式渲染我的场景:

代码语言:javascript
复制
glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);

在那个场景的顶部,我想画一个被其他纹理掩盖的纹理。这些画是在任意位置画的(不一定是长方形的,也不一定大小/位置相同)。

顺序是:渲染蒙面纹理,然后掩码纹理。

蒙面纹理是一个规则的图像,与阿尔法。

蒙版纹理要么是黑色的RGBA(0,0,0,255),要么是透明的RGBA(0,0,0,0)

我想要任何黑色不接触的东西,让它看不见。基本上,最终的结果应该是:

RGBA(masked.r, masked.g, masked.b, masked.a * mask.a)

下面是排序的图像,来解释我的意思。我真的在寻找一种解决方案,以避免使用不同的着色器或将东西粘贴到一个框架缓冲区。如果这绝对不可能,请告诉我。

EN

回答 1

Stack Overflow用户

发布于 2014-03-20 23:57:46

我会解释为什么这不可能。混合掩蔽需要三次传递,因为它有三个部分:目的地、源和掩码。无论您做什么,您都必须将源和掩码混合到一个框架缓冲区中,然后呈现到目的地。

但是,模具缓冲区是内置在默认窗口框架缓冲区中的,前提是您告诉OpenGL提供它(就像深度缓冲区一样),并且看起来完全符合您的要求。作为一个过剩调用,在双缓冲窗口中初始化窗口中的模具缓冲区以及启用alpha的颜色和深度缓冲区时,应该是这样的:

代码语言:javascript
复制
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL);

模板缓冲区能够完全满足您的需要--您可以在其中绘制形状,并有选择地告诉它丢弃或保留该形状中的像素。下面是从OpenGL红皮书中修改的如何使用它的示例:

代码语言:javascript
复制
GLdouble dRadius = 0.1; // Initial radius of spiral
GLdouble dAngle;        // Looping variable

// Use 0 for clear stencil, enable stencil test
glClearStencil(0);
glEnable(GL_STENCIL_TEST);

// Clear stencil buffer
glClear(GL_STENCIL_BUFFER_BIT);

// All drawing commands fail the stencil test, and are not
// drawn, but increment the value in the stencil buffer.
// glStencilFunc takes three arguments: the stencil function, the reference value, and the mask value. Whenever the stencil function is tested (for example GL_LESS), both the reference and the stencil value being tested from the buffer is bitwise ANDed with the mask: GL_LESS returns true if (ref & mask) < (stencil & mask).
glStencilFunc(GL_NEVER, 0x0, 0x0);
// glStencilOp takes three arguments: the stencil operation to call when the stencil test fails, the stencil operation to call when the stencil test passes but the depth test fails, and the stenciloperation to call when the stencil test passes AND the depth test passes (or depth test is disabled or no depth buffer is allocated).
glStencilOp(GL_INCR, GL_INCR, GL_INCR);

// Spiral pattern will create stencil pattern
// Draw the spiral pattern with white lines. We
// make the lines  white to demonstrate that the
// stencil function prevents them from being drawn
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_LINE_STRIP);
    for(dAngle = 0; dAngle < 400.0; dAngle += 0.1)
        {
        glVertex2d(dRadius * cos(dAngle), dRadius * sin(dAngle));
        dRadius *= 1.002;
        }
glEnd();

// Now, allow drawing, except where the stencil pattern is 0x1
// and do not make any further changes to the stencil buffer
glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

// Now draw red square
glColor3f(0.0f, 1.0f, 0.0f);
glRectf(0, 0, 200, 200);

这个绘图代码的输出是一个红色的正方形,从(1,1)开始有一个螺旋形。螺旋由丢弃的像素组成,其颜色与已清除的颜色缓冲区相同。如果要将此代码用于您的目的,则可以在您希望纹理位于编写螺旋代码的地方绘制方格,然后使用GL_EQUAL作为模板函数,在绘制红色方块的地方绘制蒙面纹理。有关模具缓冲区的更多信息可以找到这里

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22516526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档