具有OpenGL混合功能的LibGDX纹理混合 [英] LibGDX texture blending with OpenGL blending function

查看:119
本文介绍了具有OpenGL混合功能的LibGDX纹理混合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In libGdx, i'm trying to create a shaped texture: Take a fully-visible rectangle texture and mask it to obtain a shaped textured, as shown here:

在这里,我在矩形上对其进行测试,但我将要在任何形状上使用它.我研究了本教程,并想到了首先绘制纹理的想法,然后是具有去污功能的面膜:

Here I test it on rectangle, but i will want to use it on any shape. I have looked into this tutorial and came with an idea to first draw the texture, and then the mask with blanding function:

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();
    

    可以很好地选择纹理的中心,但是我看到的不是黑色周围的透明颜色:

    The center ot the texture get's selected well, but instead of transparent color around, i see black:

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

    Why is the result blank and not transparent?

    (完整代码-警告:非常混乱)

    推荐答案

    您正在尝试做的事情看起来像是对混合的巧妙运用.但是我相信,应用它的确切方式是被设计所打破".让我们逐步执行以下步骤:

    What you're trying to do looks like a pretty clever use of blending. But I believe the exact way you apply it is "broken by design". Let's walk through the steps:

    1. 您用红色和绿色方块渲染背景.
    2. 您在背景上方渲染了不透明的纹理.
    3. 通过应用蒙版擦除在步骤2中渲染的部分纹理.

    问题在于,对于在步骤3中删除的部分,以前的背景不会恢复.确实不能,因为您在第2步中将其擦除了.在第2步中替换了整个纹理区域的背景,一旦消失,就无法将其恢复.

    The problem is that for the parts you erase in step 3, the previous background is not coming back. It really can't, because you wiped it out in step 2. The background of the whole texture area was replaced in step 2, and once it's gone there's no way to bring it back.

    现在的问题当然是如何解决此问题.我可以想到两种常规方法:

    Now the question is of course how you can fix this. There are two conventional approaches I can think of:

    • 您可以通过将纹理和蒙版渲染到未布满画面的帧缓冲对象(FBO)中来组合它们.您可以像现在一样执行步骤1和2,但是将其渲染到带有纹理附件的FBO中.这样,渲染到的纹理就是一个具有可反映蒙版的alpha值的纹理,您可以使用该纹理通过标准混合将其渲染到默认的帧缓冲区中.
    • 您可以使用模板缓冲区.掩盖渲染的某些部分是模板缓冲区的主要应用程序,对于您的用例,使用模板肯定是一个非常好的解决方案.在此答案中,我将不详细介绍如何将模板缓冲区准确应用于您的情况.如果您搜索"OpenGL模具",则应该可以在网上和书籍中找到大量示例,包括本网站上的其他答案.例如,这个最近的问题涉及使用模板缓冲区执行类似的操作: OpenGL模板(剪辑实体).

    因此,这些将是标准解决方案.但是受您尝试中的想法的启发,我认为实际上仅通过混合就可以使它起作用.我想出的方法使用的序列和混合功能略有不同.我还没有尝试过,但是我认为它应该可以工作:

    So those would be the standard solutions. But inspired by the idea in your attempt, I think it's actually possible to get this to work with just blending. The approach that I came up with uses a slightly different sequence and different blend functions. I haven't tried this out, but I think it should work:

    1. 您像以前一样渲染背景.
    2. 渲染蒙版.为防止其擦去背景,请禁用对帧缓冲区的颜色分量的写入,而仅对alpha分量进行写入.这样会将遮罩留在帧缓冲区的alpha分量中.
    3. 使用帧缓冲区(DST_ALPHA)中的alpha分量进行混合来渲染纹理.
    1. You render the background as before.
    2. Render the mask. To prevent it from wiping out the background, disable writing to the color components of the framebuffer, and only write to the alpha component. This leaves the mask in the alpha component of the framebuffer.
    3. Render the texture, using the alpha component from the framebuffer (DST_ALPHA) for blending.

    您将需要一个带有alpha组件的帧缓冲区,此缓冲区才能正常工作.设置上下文/表面时,请确保请求帧缓冲区的Alpha位.

    You will need a framebuffer with an alpha component for this to work. Make sure that you request alpha bits for your framebuffer when setting up your context/surface.

    代码序列如下所示:

    // 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.
    

    这篇关于具有OpenGL混合功能的LibGDX纹理混合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆