Problem with coplanar surfaces

I tried to render some impacts on my walls. I use an image with an alpha channel for the texture of the impacts.I want to use blending to draw the impacts onto the walls. I tried to do it as below:

public final void init(GLAutoDrawable drawable){

gl.glBlendFunc(GL.GL_ONE,GL.GL_ZERO);
}

public final void display(GLAutoDrawable drawable){

//bind the texture of the walls
//draw the walls
gl.glEnable(GL.GL_BLEND);
//bind the texture of the impacts
//draw the impacts
gl.glDisable(GL.GL_BLEND);
}

It doesn’t work very good. Sometimes, the effect is fine and often the impact is flickering. erikd told me that it comes from a problem called Z-Fighting. How can I do to solve this? I would like an impact on a wall to have the same value in the z-buffer than the wall itself and then use blend functions to replace all the wall texture pixels by the opaque texture pixels of the impact. I looked at glPolygonOffset, glTexEnvf, glBlend but I don’t know what to do now. Does anyone have an idea?

when you enable blend, call glPolygonOffset(1,1).
When you disable blend, re-set it to glPolygonOffset(0,0).

Thanks. I have tested this and it doesn’t solve the problem. I still have some Z-fighting.

There’s an associated glEnable(), possibly GL_POLYGON_OFFSET, but I couldn’t be sure without checking. The man page fro glPolygonOffset should tell you.
In any case, polygon offset will definitely cure z-fighting when it’s active.

The depth-values will also exactly match, if your impacts share the exact same vertices as the wall-geometry. If your geometry is simple, you can use some extreme-texcoords with CLAMP enabled, to get your impact-image in the right position on your wall.

You’re right. I’m stupid. Thanks. I’m going to try it again.

With CLAMP enabled? What do you mean precisely? One of the previous solution was to change the texture coordinates in order to replace a clean section of wall by a dirty section of wall but it was inaccurate: when the player shot into a wall, the impact appeared always in the center of the wall.

I need a accurate solution as I will reuse it to display the blood on the clothes like in Goldeneye 007 on Nintendo 64.

Texture-repeat is either CLAMP or WRAP (or something-like that)

If your impacts where always in the center… shift your tex-coords until it’s where you want it.

I’m going to try this in order to clamp the values in [0;1] :
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP);

But does this work too in my case? :
gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);

I used this, it still doesn’t work. :frowning:
gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
gl.glEnable(GL.GL_POLYGON_OFFSET_LINE);
gl.glEnable(GL.GL_POLYGON_OFFSET_POINT);

What parameters are you using in glPolygonOffset()?

When rendering a wireframe over a rendered object, I use glPolygonOffset( 1, 1 ) to bump the filled triangles a bit further away from the camera that the GL_LINE stuff.

Don’t forget to disable the polygon offset when you’re done rendering the special geometry. Else everything will be rendered with the offset, and there will still be fighting.

Other options include modifying the world-space coordinates, or modifying the projection matrix, or modifying the glDepthRange(). However, if the problem really is Z fighting, then proper polygon offset should solve it.

Here is what I did:

class GameGLEventController implements GLEventListener{

public final void init(GLAutoDrawable drawable){

gl.glBlendFunc(GL.GL_ONE,GL.GL_ZERO);

}

public final void display(GLAutoDrawable drawable){

//draw the walls

gl.glEnable(GL.GL_BLEND);
gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
gl.glEnable(GL.GL_POLYGON_OFFSET_LINE);
gl.glEnable(GL.GL_POLYGON_OFFSET_POINT);
gl.glPolygonOffset(1.0f,1.0f);
//draw the impacts
gl.glPolygonOffset(0.0f,0.0f);
gl.glDisable(GL.GL_POLYGON_OFFSET_POINT);
gl.glDisable(GL.GL_POLYGON_OFFSET_LINE);
gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
gl.glDisable(GL.GL_BLEND);

}

}

I already did this.

Until now, it hasn’t solved my problem.

I would like to do the opposite with the impacts, idem est to bump them a bit closer from the camera.

Try using glPolygonOffset( -1, -1 ) when drawing the decals.

It is better but it doesn’t solve everything. I think that I’m close to the aim. Thanks, really ;D
I’m going to tinker the coefs.

It works!!! ;D ;D ;D I use now gl.glPolygonOffset( -20.0f, -20.0f );

The solution is explained below:

class GameGLEventController implements GLEventListener{

public final void init(GLAutoDrawable drawable){

gl.glPolygonOffset(-20.0f,-20.0f);

}

public final void display(GLAutoDrawable drawable){

//draw the walls

gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
//draw the impacts
gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);

}

}

I decreased the factor and the unit through the keyboard while playing to find the good value. It is not necessary to put gl.glPolygonOffset(0,0) as I disable it when I don’t need it anymore. Thank you very very much for your help. Now I need to find a way to get the value of r when using glPolygonOffset to be sure to use the good factor everywhere:
offset = m * factor + r * units
where m is the maximum depth slope of the polygon and r is the smallest value guaranteed to produce a resolvable difference in window coordinate depth values. The value r is an implementation-specific constant.