GL_TRUE is not a “valid” input to glStencilFunc(), but in this case it works since GL_TRUE=1. I’m gonna assume you’re setting glStencilOp() to something sane before that loop. My guess at what’s happening is that you mark pixels belonging to a cube with the value 1 in the stencil buffer and then try to draw the outline on pixels that are not equal to 1. This means that every time you draw a cube, the pixels it’s covering will be marked to 1 for all following cubes too, so even if the outline of a later cube is closer to the camera it will still be removed since the pixel is marked with a 1. What you need to do is to reset the stencil buffer between each cube so that it is all 0s again.
You can do this by adding a glClear(GL_STENCIL_BUFFER_BIT) after you’ve drawn each box, but this will get slow. Still, try this to confirm that you’re on the right track. It’d be faster to use the entire 8-bit precision of the stencil buffer and first mask with 1, then 2 for the second box, 3 for the third, etc until you reach to 256, when you clear the stencil buffer to 0 again. That way you could draw 255 boxes between every clear, but you’d still have a rather big number of clears if you draw lots of boxes.
A faster but less precise way of doing this would be to reset the stencil buffer to 0 when drawing the outline. In the marking pass you mark the pixels with a 1, and in the outline drawing pass you reset them back to 0 again. Since the outline is bigger than the original model, all pixels will get changed back to 0. This could be done like this:
//glStencilMask() is always set to 0xFF here.
//Render cube
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); //Mark all pixels that the original box touches the box regardless of depth testing.
renderCube();
//Render outline
glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); //Reset all pixels to 0
renderCube();
This has some major drawbacks. It will have artifacts if the box and/or its outline intersects the near plane (pixels won’t be reset back to 0), and it also won’t work with complex (concave) models that overlap themselves in any way as the first overdraw will reset it to 0 and the second overdraw will be allowed to place the outline over the model itself. For cubes however this is the fastest way.
The best solution by far would be to just use a depth-detecting shader to compute an outline per pixel. This is what most games nowadays (like Borderlands) do.