Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

How to remove (cut-out) a transparent rectangle in a Texture, so that the hole will be translucent.

On Android I would use the Xfermodes approach:

http://stackoverflow.com/questions/8115732/how-to-use-masks-in-android

But in libgdx I will have to use opengl. So far I almost achieved what I was looking for, by using the the glBlendFunc From this nice and very helpful page I learend that

glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);

should solve my problem, but I tried it out, and it did not quite work as expected:

batch.end();
batch.begin();

batch.setBlendFunction(GL20.GL_ZERO,
        GL20.GL_ONE_MINUS_SRC_ALPHA);
// Draw the background
super.draw(batch, x, y, width, height);
// draw the foreground
mask.draw(batch, x + innerButtonTable.getX(), y
        + innerButtonTable.getY(), innerButtonTable.getWidth(),
        innerButtonTable.getHeight());
// result = {foreground}*{0,0,0,0} +
// {background}*(1-sourceAlpha)

batch.end();
batch.setBlendFunction(GL20.GL_SRC_ALPHA,
        GL20.GL_ONE_MINUS_SRC_ALPHA);
batch.begin();

It is just making the mask area plain black, whereas I was expecting transparency, any ideas.

This is what I get:

Mask will be drawn black

This is what I expected:

Mask area should be transparent

share|improve this question
    
Is there any particular reason your first 'batch.setBlendFunction()' is inside 'batch.begin(); ... batch.end();' and your second call is outside of the ''batch.begin(); ... batch.end();'? –  Benjamin Danger Johnson Mar 8 '13 at 17:34
    
Also, to me it looks like the second 'batch.setBlendFunction()'s parameters should be used before drawing the mask (since it mentions the alpha source) rather than after. Maybe try switching the two calls you make. –  Benjamin Danger Johnson Mar 8 '13 at 17:35
    
thanks for the comment, but it did not help, I updated my code above, maybe I just missunderstood something. –  joecks Mar 8 '13 at 20:56
    
um this may sound silly, but you are enabling Blend right? batch.glEnable(GL_BLEND); –  Benjamin Danger Johnson Mar 8 '13 at 21:59
    
I just tried with: Gdx.gl.glEnable(GL20.GL_BLEND);, same same –  joecks Mar 9 '13 at 11:55
add comment

1 Answer

up vote 3 down vote accepted

I solved my problem by using the stencil buffer:

Gdx.gl.glClear(GL_STENCIL_BUFFER_BIT);
batch.end();
//disable color mask
Gdx.gl.glColorMask(false, false, false, false);
Gdx.gl.glDepthMask(false);
//enable the stencil
Gdx.gl.glEnable(GL20.GL_STENCIL_TEST);
Gdx.gl.glStencilFunc(GL20.GL_ALWAYS, 0x1, 0xffffffff);
Gdx.gl.glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

batch.begin();
//draw the mask
mask.draw(batch, x + innerButtonTable.getX(), y
        + innerButtonTable.getY(), innerButtonTable.getWidth(),
        innerButtonTable.getHeight());

batch.end();
batch.begin();

//enable color mask 
Gdx.gl.glColorMask(true, true, true, true);
Gdx.gl.glDepthMask(true);
//just draw where outside of the mask
Gdx.gl.glStencilFunc(GL_NOTEQUAL, 0x1, 0xffffffff);
Gdx.gl.glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
//draw the destination texture
super.draw(batch, x, y, width, height);
batch.end();
//disable the stencil
Gdx.gl.glDisable(GL20.GL_STENCIL_TEST);
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.