如何根据触摸的其他对象裁剪纹理?

时间:2017-09-30 20:40:43

标签: libgdx

我有一个行演员可能有其他与之相交的对象,我需要裁剪掉那部分。

enter image description here

上面是影像演员

enter image description here

这个矩形也是一个图像演员可能沿着线条随机出现。

enter image description here 这是我想得到的结果的样本。我需要有关如何使用libgdx实现此目的的建议。

[编辑]

建议我尝试使用fbo绘制缓冲区。以下是我目前正在处理的代码。

@Override
public void draw(Batch batch, float parentAlpha) {

    fbo.begin();
    getStage().getViewport().apply();

    Gdx.gl.glClearColor(0f,0f,0f,0f);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    batch.draw(trLine,position.x,position.y);
    batch.flush();

    fbo.end();
    getStage().getViewport().apply();

    batch.draw(fbo.getColorBufferTexture(),0,0);

}

我可以将绘图缓冲到缓冲区中并稍后绘制,但它恰好是不同的大小。下面是创建和处理fbo的代码。并且它在绘制循环之外。

fbo = new FrameBuffer(Pixmap.Format.RGBA8888,getStage().getViewport().getWidth(),getStage().getViewport().getHeight(),false,true);

[已解决的FBO]

下面是有效工作的编码,但混合没有按预期工作。将继续努力直到它起作用。

fbo.begin();

Gdx.gl.glClearColor(0f,0f,0f,0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

batch.begin();
batch.draw(trLine,position.x,position.y);
batch.end();


int srcFunc = batch.getBlendSrcFunc();
int dstFunc = batch.getBlendDstFunc();

batch.enableBlending();
batch.begin();
batch.setBlendFunction(GL20.GL_ONE, GL20.GL_FUNC_REVERSE_SUBTRACT);
for(int i = 0 ; i < cropRectangles.size() ; i++){   batch.draw(cropTexture.get(i),cropRectangles.get(i).x,cropRectangles.get(i).y);
}
batch.end();

fbo.end();

getStage().getViewport().apply();

//reset blending before drawing the desire result
batch.begin();
batch.setBlendFunction(srcFunc, dstFunc);
batch.draw(fbo.getColorBufferTexture(),0,0);
batch.end();

但输出没有任何混合效果。它仍然是一个白色填充的矩形。

enter image description here

[已解决的完整代码]

我最终正确应用了等式并能够重置它,因此它不会影响我在此之后绘制的其他内容。

fbo.begin();

Gdx.gl.glClearColor(0f,0f,0f,0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

batch.begin();
batch.draw(trLine,position.x,position.y);
batch.end();


int srcFunc = batch.getBlendSrcFunc();
int dstFunc = batch.getBlendDstFunc();



batch.enableBlending();

batch.begin();
batch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glBlendEquation(GL20.GL_FUNC_REVERSE_SUBTRACT);

for(int i = 0 ; i < cropRectangles.size() ; i++){

                batch.draw(cropTexture.get(i),cropRectangles.get(i).x,cropRectangles.get(i).y);

}

batch.end();
batch.flush();

fbo.end();

Gdx.gl.glBlendEquation(GL20.GL_FUNC_ADD);

getStage().getViewport().apply();

batch.begin();
batch.setBlendFunction(srcFunc, dstFunc);
batch.draw(fbo.getColorBufferTexture(),0,0);
batch.end();

2 个答案:

答案 0 :(得分:1)

您可以使用混合模式来实现此目的。您的矩形应该有2个部分。 外部和透明部分。

外部部件是您照常绘制的实际部分。

透明部分将是另一个具有完整alpha的矩形,您应该使用此部分的混合。

Visual Blending Tool

examplemode

glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);

此模式清除交叉区域,似乎正确模式。

您可以轻松找到libgdx中混合的示例用法。

    SpriteBatch sb = (SpriteBatch)batch;

    // draw our destination image
    sb.draw(dst, 0, 0);
    sb.end();

    // remember SpriteBatch's current functions
    int srcFunc = sb.getBlendSrcFunc();
    int dstFunc = sb.getBlendDstFunc();

    // Let's enable blending
    sb.enableBlending();
    sb.begin();

    // blend them
    sb.setBlendFunction(GL20.GL_ONE, GL20.ONE_MINUS_SRC_ALPHA);
    sb.draw(src, 0, 0);

    // Reset
    sb.end();
    sb.begin();
    sb.setBlendFunction(srcFunc, dstFunc);

此外,您还必须更改混合方程式。 它并不是精灵批量的独特之处所以我们需要改变所有游戏。

//Equation for effect you want    
Gdx.gl.glBlendEquation(GL20.GL_FUNC_REVERSE_SUBTRACT);

//After draw you should also reset this
Gdx.gl.glBlendEquation(GL20.GL_FUNC_ADD);

现在我们应该将其绘制到FrameBufferObject,因为透明区域将显示您的spritebatch的背景颜色。 如果它对你而言已经完成了,但你想在这个透明区域看到另一个纹理,如背景图像或其他东西,那么我们还有一步。

你应该阅读这篇文章,了解FBO(FrameBufferObject)

的目的

Frame Buffer from official wiki

您需要使用它来合并您的精灵和透明区域,以便您可以将它们用作整个图像并透过透明区域的背景图像。

根据你的游戏,使用第二个视口或精灵批处理可能更容易,也更有效率。

答案 1 :(得分:0)

针对这种情况的一种解决方案,用实心背景颜色填充该矩形(我的意思是在该矩形环内制作一个矩形)。它会裁掉那部分。