Has anyone had any luck using the stencil buffer in LWJGL? I've tried whipping up a sample using NeHe's tutorials and my red book, but it just doesn't seem to work. In the code below, I'm drawing a simple spinning colored cube. I create my stencil buffer by drawing a small plane in front of the cube. I expect my cube to have its edges cut to the area of the little plane. But instead, I always see the full cube.
Oh, and this code is based on the examples that come with LWJGL, so the class it extends (BaseWindow) is defined there. Can anyone spot what's wrong with this code?
public class StencilTest extends BaseWindow {
private float xrot;
private float yrot;
private float zrot;
//* Creates a new instance of Lesson
public StencilTest() {
}
protected void initGL() throws Exception {
try {
gl.enable(GL.STENCIL_TEST);
gl.clearStencil(0);
// Call parent to finish setting up GL
super.initGL();
}
catch (Exception e) {
throw new Exception("Problem initialising GL", e);
}
}
protected boolean drawGLScene(float frameTime) {
// Clear The Screen And The Depth Buffer
gl.clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT | GL.STENCIL_BUFFER_BIT);
// Reset The Current Modelview Matrix
gl.loadIdentity();
// Build the stencil
buildStencil();
drawCube();
// rotate 15pps on the X Axis
xrot += frameTime * 30f ;
// rotate 20pps on the Y Axis
yrot += frameTime * 20f;
// rotate 10pps on the Z Axis
zrot += frameTime * 40f;
return true;
}
public void drawCube() {
gl.pushMatrix();
gl.translatef(0.0f,0.0f,-5.0f);
gl.rotatef(xrot,1.0f,0.0f,0.0f);
gl.rotatef(yrot,0.0f,1.0f,0.0f);
gl.rotatef(zrot,0.0f,0.0f,1.0f);
gl.begin(GL.QUADS);
// Front Face
gl.color4f(0.0f, 0.0f, 1.0f, 1.0f);
// Bottom Left
gl.vertex3f(-1.0f, -1.0f, 1.0f);
// Bottom Right
gl.vertex3f( 1.0f, -1.0f, 1.0f);
// Top Right
gl.vertex3f( 1.0f, 1.0f, 1.0f);
// Top Left
gl.vertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
gl.color4f(0.0f, 1.0f, 0.0f, 1.0f);
// Bottom Right
gl.vertex3f(-1.0f, -1.0f, -1.0f);
// Top Right
gl.vertex3f(-1.0f, 1.0f, -1.0f);
// Top Left
gl.vertex3f( 1.0f, 1.0f, -1.0f);
// Bottom Left
gl.vertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
// Top Left
gl.vertex3f(-1.0f, 1.0f, -1.0f);
// Bottom Left
gl.vertex3f(-1.0f, 1.0f, 1.0f);
// Bottom Right
gl.vertex3f( 1.0f, 1.0f, 1.0f);
// Top Right
gl.vertex3f( 1.0f, 1.0f, -1.0f);
// Bottom Face
gl.color4f(1.0f, 0.0f, 0.0f, 1.0f);
// Top Right
gl.vertex3f(-1.0f, -1.0f, -1.0f);
// Top Left
gl.vertex3f( 1.0f, -1.0f, -1.0f);
// Bottom Left
gl.vertex3f( 1.0f, -1.0f, 1.0f);
// Bottom Right
gl.vertex3f(-1.0f, -1.0f, 1.0f);
// Right face
gl.color4f(1.0f, 1.0f, 0.0f, 1.0f);
// Bottom Right
gl.vertex3f( 1.0f, -1.0f, -1.0f);
// Top Right
gl.vertex3f( 1.0f, 1.0f, -1.0f);
// Top Left
gl.vertex3f( 1.0f, 1.0f, 1.0f);
// Bottom Left
gl.vertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
gl.color4f(1.0f, 0.0f, 1.0f, 1.0f);
// Bottom Left
gl.vertex3f(-1.0f, -1.0f, -1.0f);
// Bottom Right
gl.vertex3f(-1.0f, -1.0f, 1.0f);
// Top Right
gl.vertex3f(-1.0f, 1.0f, 1.0f);
// Top Left
gl.vertex3f(-1.0f, 1.0f, -1.0f);
gl.end();
gl.popMatrix();
}
public void buildStencil() {
// Set our stencil func and op to fill up the buffer
gl.stencilFunc(GL.ALWAYS, 1, 1);
gl.stencilOp(GL.REPLACE, GL.REPLACE, GL.REPLACE);
// Disable color and depth, so we don't actually draw to the screen.
gl.colorMask(false, false, false, false);
gl.disable(GL.DEPTH_TEST);
// Draw the stencil object
gl.pushMatrix();
gl.color4f(1.0f, 1.0f, 1.0f, 1.0f);
gl.translatef(0.0f,0.0f,-3.0f);
gl.begin(GL.QUADS);
// Bottom Left
gl.texCoord2f(0.0f, 0.0f); gl.vertex3f(-0.5f, -0.5f, 0.0f);
// Bottom Right
gl.texCoord2f(1.0f, 0.0f); gl.vertex3f( 0.5f, -0.5f, 0.0f);
// Top Right
gl.texCoord2f(1.0f, 1.0f); gl.vertex3f( 0.5f, 0.5f, 0.0f);
// Top Left
gl.texCoord2f(0.0f, 1.0f); gl.vertex3f(-0.5f, 0.5f, 0.0f);
gl.end();
gl.popMatrix();
// Re-enable depth and color
gl.enable(GL.DEPTH_TEST);
gl.colorMask(true, true, true, true);
// Set the stencil func and op and use the buffer but not overwrite it.
gl.stencilFunc(GL.EQUAL, 1, 1);
gl.stencilOp(GL.KEEP, GL.KEEP, GL.KEEP);
}
public static void main(String[] arguments) {
int err = 0;
StencilTest test = new StencilTest();
try {
test.start(640, 480, 16, false);
}
catch (Exception e) {
err = 1;
e.printStackTrace();
}
System.exit(err);
}
}
Paul