Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
libgdx open gles 2.0模板alpha掩蔽_Libgdx_Opengl Es 2.0_Stencil Buffer - Fatal编程技术网

libgdx open gles 2.0模板alpha掩蔽

libgdx open gles 2.0模板alpha掩蔽,libgdx,opengl-es-2.0,stencil-buffer,Libgdx,Opengl Es 2.0,Stencil Buffer,我正在寻找一种解决方案,用OpenGles 2.0在libgdx中使用模具缓冲区实现alpha掩蔽 我已经设法用模具缓冲区和着色器实现了简单的alpha掩蔽,其中,若片段的alpha通道大于某个指定值,它就会被分解。那很好 问题是,当我想使用一些渐变图像遮罩,或是带边框的png遮罩时,我没有得到我想要的(我得到的是没有alpha通道的“填充”矩形遮罩),而是想要平滑的淡出遮罩 我知道问题是,在模具缓冲区中只有0和1,但我想写入模具中的其他一些值,它们表示在片段着色器中传递的片段的实际alpha值

我正在寻找一种解决方案,用OpenGles 2.0在libgdx中使用模具缓冲区实现alpha掩蔽

我已经设法用模具缓冲区和着色器实现了简单的alpha掩蔽,其中,若片段的alpha通道大于某个指定值,它就会被分解。那很好

问题是,当我想使用一些渐变图像遮罩,或是带边框的png遮罩时,我没有得到我想要的(我得到的是没有alpha通道的“填充”矩形遮罩),而是想要平滑的淡出遮罩

我知道问题是,在模具缓冲区中只有0和1,但我想写入模具中的其他一些值,它们表示在片段着色器中传递的片段的实际alpha值,并使用模具中的该值以某种方式进行一些混合。 如果可能的话,我希望我已经解释了我想要得到什么

我最近开始使用OpenGL ES,所以我仍然有一些误解

我的问题是:如何设置和模板缓冲区来存储0和1以外的值,以及如何在以后将这些值用于alpha掩蔽

提前通知Tnx

这是当前我的模具设置:

    Gdx.gl.glClearColor(1, 1, 1, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_STENCIL_BUFFER_BIT |   GL20.GL_DEPTH_BUFFER_BIT);

    // setup drawing to stencil buffer
    Gdx.gl20.glEnable(GL20.GL_STENCIL_TEST);
    Gdx.gl20.glStencilFunc(GL20.GL_ALWAYS, 0x1, 0xffffffff);
    Gdx.gl20.glStencilOp(GL20.GL_REPLACE, GL20.GL_REPLACE, GL20.GL_REPLACE);
    Gdx.gl20.glColorMask(false, false, false, false);
    Gdx.gl20.glDepthMask(false);

    spriteBatch.setShader(shaderStencilMask);
    spriteBatch.begin();

    // push to the batch
    spriteBatch.draw(Assets.instance.actor1, Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2, Assets.instance.actor1.getRegionWidth(), Assets.instance.actor1.getRegionHeight());

    spriteBatch.end();

    // fix stencil buffer, enable color buffer
    Gdx.gl20.glColorMask(true, true, true, true);
    Gdx.gl20.glDepthMask(true);
    Gdx.gl20.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_KEEP);

    // draw where pattern has NOT been drawn
    Gdx.gl20.glStencilFunc(GL20.GL_EQUAL, 0x1, 0xff);

    decalBatch.add(decal);
    decalBatch.flush();

    Gdx.gl20.glDisable(GL20.GL_STENCIL_TEST);

    decalBatch.add(decal2);
    decalBatch.flush();

我能想到的唯一方法就是使用帧缓冲区

选项1

将场景的背景(不会被遮罩的内容)绘制到帧缓冲区。然后在屏幕上绘制不带遮罩的整个场景。然后使用帧缓冲区的颜色附件将遮罩贴花绘制到屏幕上。这种方法的缺点是,在Android上的OpenGL ES 2.0中,帧缓冲区可以有RGBA4444,而不是RGBA8888,因此在颜色位深度变化的遮罩边缘会有可见的接缝

选项2

将遮罩贴花绘制为黑白不透明到帧缓冲区。然后在屏幕上绘制背景。绘制任何可以遮罩的对象时,请使用多重纹理绘制,乘以帧缓冲区的颜色纹理。潜在的缺点是,任何可以遮罩的东西都必须使用自定义着色器绘制多重纹理。但是如果你只是使用贴花,那么这并不比选项1更复杂

以下内容未经测试…可能需要进行一些调试

在这两个选项中,我都会将绘制遮罩贴花时要与贴花批次一起使用的CameraGroupStrategy子类化,并覆盖
beforeGroups
以同时设置第二个纹理

public class MaskingGroupStrategy extends CameraGroupStrategy{

    private Texture fboTexture;

    //call this before using the DecalBatch for drawing mask decals
    public void setFBOTexture(Texture fboTexture){
        this.fboTexture = fboTexture;
    }

    @Override
    public void beforeGroups () {
        super.beforeGroups();
        fboTexture.bind(1);
        shader.setUniformi("u_fboTexture", 1);
        shader.setUniformf("u_screenDimensions", Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    }
}
在着色器中,可以获得如下所示的FBO纹理颜色:

vec4 fboColor = texture2D(u_fboTexture, gl_FragCoord.xy/u_screenDimensions.xy);
那么对于选项1:

gl_FragColor = vec4(fboColor.rgb, 1.0-texture2D(u_texture, v_texCoords).a);
或选择2:

gl_FragColor = v_color * texture2D(u_texture, v_texCoords);
gl_FragColor.a *= fboColor.r;

模板不允许部分alpha值。要在两个值之间进行转换,我认为您必须将内容绘制到帧缓冲区中,然后使用帧缓冲区的颜色纹理和表示alpha的纹理使用多重纹理绘制到屏幕上。但根据您的具体需要,可能会有一个更简单的解决方案。我正在尝试遮罩3d平面,例如,一个平面表示遮罩,另一个平面位于遮罩平面后面。我想在平面后面,当遮罩的纹理是透明的时候,得到透明。Im目前正在Libgdx中使用贴花。在没有fps下降的情况下,这是可能的吗?所谓平面,你是指3D空间中的矩形?如果两个矩形在大小、方向和位置上完全相同,则可以使用多重纹理进行处理,尽管这需要对贴花进行一些处理。是的,平面基本上是三维空间中的矩形。遮罩应该是静态的,遮罩后面的平面可以移动。重叠部分应该被屏蔽。我只能想到涉及帧缓冲区的方法。它是否影响FPS取决于你的瓶颈是什么。嘿,它在桌面上工作得很好!但在安卓上,什么都不会被吸引。你知道为什么吗?我试过使用帧缓冲区格式8888和4444,但都是一样的。我已经调试过了…绘制到帧缓冲区是可行的,但使用自定义组策略的步骤不会在屏幕上绘制任何内容。这是我以前的分组方法:Gdx.gl.glEnable(GL20.gl\u DEPTH\u TEST);begin();setUniformMatrix(“u_projTrans”,camera.combined);graphics.getGL20().glActiveTexture(GL20.GL_TEXTURE1);fboTexture.bind(1);着色器.setUniformi(“u_fboTexture”,1);setUniformf(“u_屏幕尺寸”,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());graphics.getGL20().glActiveTexture(GL20.GL_TEXTURE0);着色器.setUniformi(“u_纹理”,0);当某些东西在桌面上工作但在Android上不工作时,对我来说,这通常是因为着色器中的某些东西导致着色器无法编译。编译着色器后,将其用于调试目的:
if(!shader.isCompiled())Gdx.app.log(“着色器编译失败”,shader.getLog())。这将告诉您编译时发生的任何警告或错误。它实际上给出了错误发生的行号和列号,但不知道它们是发生在顶点着色器还是片段着色器中,所以有时你必须同时检查这两个。嘿,我在电话上尝试了我的代码,它工作了……我也在STB设备上试过,但什么都没画出来。着色器中没有错误或警告日志。我甚至试着替换它来画一个简单的红色方框,但这并没有什么区别。你知道一些可能有用的设置吗?机顶盒设备是我的目标平台,所以它必须在上面工作。有什么建议吗?这是Jelly Bean 4.2.2。我找到了解决方案:我唯一需要添加的是calulus中的v_颜色,用于碎片着色器中的碎片颜色。事件它是无用的,我猜STB上的编译器版本有问题或类似的东西。