Opengl es 使用glBlendFunc屏蔽,不带帧缓冲区

Opengl es 使用glBlendFunc屏蔽,不带帧缓冲区,opengl-es,opengl-es-2.0,Opengl Es,Opengl Es 2.0,我希望不使用帧缓冲区或着色器就可以做到这一点,只需直接使用glBlendFunc或glBlendFuncSeparate 我使用标准混合模式正常渲染场景: glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); 在那个场景的顶部,我想画一个被其他纹理掩盖的纹理。它们在任意位置绘制(不一定为矩形,也不一定为彼此相同的大小/位置) 顺序是;渲染遮罩纹理,然后遮罩纹理 遮罩纹理是带有alpha的常规图像 遮罩纹理可以是黑色RGBA(0,0,0

我希望不使用帧缓冲区或着色器就可以做到这一点,只需直接使用glBlendFunc或glBlendFuncSeparate

我使用标准混合模式正常渲染场景:

glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
在那个场景的顶部,我想画一个被其他纹理掩盖的纹理。它们在任意位置绘制(不一定为矩形,也不一定为彼此相同的大小/位置)

顺序是;渲染遮罩纹理,然后遮罩纹理

遮罩纹理是带有alpha的常规图像

遮罩纹理可以是黑色RGBA(0,0,0,255)或透明RGBA(0,0,0,0)

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

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

下面是订购的图片,来解释我的意思。我真的在寻找一种解决方案,以避免使用不同的着色器或将内容粘贴到帧缓冲区上。如果绝对不可能,请告诉我


我将解释为什么这是不可能的。混合遮罩需要三个过程,因为它有三个部分:目标、源和遮罩。无论执行何种操作,都必须将源和遮罩混合到帧缓冲区中,然后渲染到目标

但是,模具缓冲区内置在默认的窗口帧缓冲区中,前提是您告诉OpenGL为其提供(就像深度缓冲区一样),并且似乎完全按照您的要求执行。作为GLUT调用,在双缓冲窗口中,初始化窗口中的模具缓冲区以及启用alpha的颜色和深度缓冲区如下所示:

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL);
模具缓冲区能够完全满足您的需要-您可以在其中绘制一个形状,并有选择地告诉它放弃或保留该形状内的像素。下面是一个如何使用它的示例,从OpenGL红皮书修改而来:

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);
GLdouble dRadius=0.1;//螺旋的初始半径
GLdouble-dAngle;//循环变量
//使用0清除模具,启用模具测试
gltencil(0);
glEnable(GL_模板试验);
//清除模板缓冲区
glClear(GL模具缓冲位);
//所有图形命令均未通过模具测试,因此不会被删除
//绘制,但增加模具缓冲区中的值。
//glStencilFunc接受三个参数:stencil函数、引用值和掩码值。无论何时测试模具函数(例如GL_LESS),从缓冲区测试的参考和模具值都将与掩码按位and:GL_LESS在(参考和掩码)<(模具和掩码)时返回true。
glStencilFunc(GL_NEVER,0x0,0x0);
//glStencilOp有三个参数:当模具测试失败时调用的模具操作,当模具测试通过但深度测试失败时调用的模具操作,以及当模具测试通过且深度测试通过(或深度测试被禁用或未分配深度缓冲区)时调用的模具操作。
glStencilOp(GL_INCR,GL_INCR,GL_INCR);
//螺旋图案将创建模具图案
//用白线绘制螺旋图案。我们
//将线条变为白色,以证明
//模具功能可防止绘制它们
GL3F(1.0f,1.0f,1.0f);
glBegin(GL_线_带);
对于(悬挂=0;悬挂<400.0;悬挂+=0.1)
{
glVertex2d(德拉迪乌斯*科斯(悬挂),德拉迪乌斯*罪恶(悬挂));
德拉迪乌斯*=1.002;
}
格伦德();
//现在,允许绘图,除非模具图案为0x1
//并且不要对模具缓冲区进行任何进一步的更改
glStencilFunc(GL_NOTEQUAL,0x1,0x1);
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
//现在画红方块
GL3F(0.0f,1.0f,0.0f);
glRectf(0,0,200,200);

此图形代码的输出是一个红色正方形,其上有一个从(1,1)开始的螺旋。螺旋线由丢弃的像素组成,因此与清除的颜色缓冲区颜色相同。如果要使用此代码,请在编写螺旋代码的位置绘制纹理所需的正方形,然后使用GL_EQUAL作为模具函数,在绘制红色正方形的位置绘制遮罩纹理。可以找到有关模具缓冲区的更多信息。

您是否考虑过使用模具缓冲区?如果我必须先绘制遮罩纹理,是否可能?我认为我必须创建模具,将遮罩绘制到模具上,然后将遮罩纹理绘制到屏幕上,然后关闭模具?使用模具缓冲区,您应该能够将遮罩写入模具缓冲区,清除模具缓冲区,绘制要修改像素的正方形,然后将“模具”功能设置为仅在模具缓冲区具有绘制正方形区域时设置的值的位置绘制。然后,取消遮罩颜色/深度缓冲区,遮罩写入模具缓冲区,绘制纹理,然后禁用模具测试。听起来比它更复杂,比混合模式掩蔽更简单。这很有意义,我读了一些书,我想这正是我想要的。我试过了,但不是我想要的。你知道有什么像样的教程或指南吗?我试着遵循我在这里找到的一个例子;这里有一个近乎完美的例子(据我所知),你想做什么:是的,它使用了一个圆形,而不是纹理,但所有的代码都只与模板相关。