LibGDX纹理与OpenGL混合功能混合

时间:2014-07-04 14:49:08

标签: opengl libgdx textures blender alphablending

在libGdx中,我正在尝试创建一个形状纹理:采用完全可见的矩形纹理并对其进行遮罩以获得形状纹理,如下所示:

Shaped texture creation

这里我在矩形上测试它,但我想在任何形状上使用它。我调查了this tutorial并提出了一个想法,首先绘制纹理,然后是带有淡化功能的蒙版:

batch.setBlendFunction(GL20.GL_ZERO, GL20.GL_SRC_ALPHA);
  • GL20.GL_ZERO - 因为我真的不想从面具中绘制任何像素
  • GL20.GL_SRC_ALPHA - 来自原始纹理我只想绘制那些像素,其中蒙版是可见的(=白色)。

测试代码的关键部分:

batch0.enableBlending();
batch0.begin();

batch0.draw(original, 0, 0); //to see the original
batch0.draw(mask, width1, 0); //and the mask

batch0.draw(original, 0, height1); //base for the result

batch0.setBlendFunction(GL20.GL_ZERO, GL20.GL_SRC_ALPHA);
batch0.draw(mask, 0, height1); //draw mask on result
batch0.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);

batch0.end();

中心或纹理得到的选择很好,但不是透明的颜色,我看到黑色:

Screenshot

为什么结果为空白且不透明?

Full code - 警告:非常混乱)

1 个答案:

答案 0 :(得分:3)

您尝试做的事情看起来非常巧妙地使用混合。但我相信你应用它的确切方式是"被设计打破"。让我们来看看这些步骤:

  1. 使用红色和绿色方块渲染背景。
  2. 在背景上渲染不透明纹理。
  3. 通过应用蒙版擦除在步骤2中渲染的部分纹理。
  4. 问题是,对于您在步骤3中删除的部分,之前的背景不会返回。它真的不能,因为你在第2步中擦除了它。整个纹理区域的背景在步骤2中被替换了,一旦它消失了,就无法将它带回来。

    现在问题当然是如何解决这个问题。我能想到两种常规方法:

    • 您可以通过将纹理和蒙版渲染为离线帧缓冲对象(FBO)来组合它们。您可以像现在一样执行步骤1和2,但渲染到带有纹理附件的FBO中。您渲染的纹理是具有反映您的蒙版的Alpha值的纹理,您可以使用此纹理渲染到默认的帧缓冲区中,使用标准混合。
    • 您可以使用模板缓冲区。屏蔽部分渲染是模板缓冲区的主要应用,使用模板绝对是一个非常好的解决方案。在这个答案中,我不会详细说明如何将模板缓冲区应用到您的案例中。如果你搜索" OpenGL模板"你应该能够在网上和书中找到大量的例子,包括本网站的其他答案。例如,最近的一个问题涉及使用模板缓冲区执行类似操作:OpenGL stencil (Clip Entity)

    所以这些将成为标准解决方案。但是在你的尝试中受到这个想法的启发,我认为实际上可以通过混合来实现这一点。我想出的方法使用了稍微不同的序列和不同的混合函数。我没有试过这个,但我认为它应该有效:

    1. 您像以前一样渲染背景。
    2. 渲染蒙版。要防止它擦除背景,请禁用写入帧缓冲区的颜色组件,并仅写入alpha组件。这会将掩码保留在帧缓冲区的alpha分量中。
    3. 使用帧缓冲区(DST_ALPHA)中的alpha分量渲染纹理以进行混合。
    4. 你需要一个带有alpha组件的帧缓冲区才能工作。设置上下文/表面时,请确保为帧缓冲区请求alpha位。

      代码序列如下所示:

      // Draw background.
      glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
      glDisable(GL_BLEND);
      // Draw mask.
      glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
      glEnable(GL_BLEND);
      glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
      // Draw texture.