Constructive solid geometry (CSG)

Hello,

Please, how can I make boolean operations (CSG) between two solid models?

Thanks

CSG is basically just merging BSP trees and then simplifying resulting geometry, and depending on the operation, reversing the winding order of some faces.

Kevin B

You can do CSG in OpenGL through the stencil buffer.

This example code is a bit old.

	// Inside Occluder, Horizon
	GLenum face = GL_FRONT;
	GLenum test = GL_NOTEQUAL;
	glEnable(GL_DEPTH_TEST);
	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
	glCullFace(face);
	RenderOccluder();

	glDepthMask(GL_FALSE);
	glEnable(GL_STENCIL_TEST);
	glStencilFunc(GL_ALWAYS, 0, 0);
	glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
	glCullFace(GL_BACK);

	RenderHorizon();
	glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
	glCullFace(GL_FRONT);
    RenderHorizon();

	/* now draw the part of A that is inside of B */
	glDepthMask(GL_TRUE);
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	glStencilFunc(test, 0, 1);
	glDisable(GL_DEPTH_TEST);
	glCullFace(face);
	RenderOccluder();

	/* reset stencil test */
	glDisable(GL_STENCIL_TEST);

	// Fixup Occluder
	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
	glEnable(GL_DEPTH_TEST);
	glDisable(GL_STENCIL_TEST);
	glDepthFunc(GL_ALWAYS);
	RenderOccluder();

	/* reset depth func */
	glDepthFunc(GL_LESS);

	// Inside Horizon, Occluder
	face = GL_BACK;
	test = GL_EQUAL;
	glEnable(GL_DEPTH_TEST);
	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
	glCullFace(face);
	RenderHorizon();

	glDepthMask(GL_FALSE);
	glEnable(GL_STENCIL_TEST);
	glStencilFunc(GL_ALWAYS, 0, 0);
	glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
	glCullFace(GL_BACK);

	RenderOccluder();
	glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
	glCullFace(GL_FRONT);
    RenderOccluder();

	/* now draw the part of A that is inside of B */
	glDepthMask(GL_TRUE);
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	glStencilFunc(test, 0, 1);
	glDisable(GL_DEPTH_TEST);
	glCullFace(face);
	RenderHorizon();

	/* reset stencil test */
	glDisable(GL_STENCIL_TEST);

I’m afraid I forgot what it did, and it won’t compile without a dozen errors. :smiley:

In any case, if I remember corrently, it was on flipcode.

Hmmm… I guess I forgot to ask about whether or not you want a rendering based CSG solution or to actually perform CSG on geometry (like you would in a CSG modeller). Don’t expect CSG to run well as a rendering based solution. The fillrate requirements can get rediculous. Also, it forces you to use the stencil buffer, so if you need it for anything else, you’re pretty much screwed.

Kevin B

I recently read an interesting paper on using OpenGL to perform CSG and I thought it might be useful.

http://www.gvu.gatech.edu/~jarek/blister/

DN.

Tree merging is definitely the way to go if you’re serious about CSG in a game environment, not just for speed but for primitive generalization. The image-based stuff is wonderful for pictures–you can get complexity that would be hard to match with split-polygon soup :slight_smile: