Multiple Stencil Buffers

I have three classes, Blue, Green, and Red. Each class can have children and each of them can be anyone’s child. A child’s shape is masked by their parent’s shape.

So for example in the first row, Green is a child of Blue. The first pic shows no stencil and the second pic shows Blue’s shape masking out some Green as it should. That works fine.

The problem I’m having is when adding a child to a class that is a child of someone else such as the example in the second row where Red is a child of Green and Green is a child of Blue. First pic is with stencil test disabled. Second pic is if Blue’s class enables stencil test and so Red’s and Green’s shape are masked out. The third pic is Green masking out Red and then Blue masking out Green. Third pic is the outcome I want but can’t seem to get to.

so if render functions are something like:


void Blue::render()
{
glEnable(GL_STENCIL_TEST);
...
bchild->render();
glDisable(GL_STENCIL_TEST);
}

void Green::render()
{
glEnable(GL_STENCIL_TEST);
...
gchild->render();
glDisable(GL_STENCIL_TEST);
}

void Red::render()
{
...
}

and red is a child of green and green a child of blue then once the code gets ran it goes:


void Blue::render()
{
glEnable(GL_STENCIL_TEST);
...

//bchild->render(); replace bchild render with green's render()
glEnable(GL_STENCIL_TEST);
...
gchild->render();
glDisable(GL_STENCIL_TEST);

glDisable(GL_STENCIL_TEST);
}

Clearly there are problems with that code. I was thinking of checking if GL_STENCIL_TEST is enabled first and that’s easy enough but I don’t know how to ‘combine’ the stencil buffers so that the result looks like the third pic in the second row. My results usually end up Red being clipped properly by Green but then Green isn’t properly clipped by Blue.

Apologies if this has been answered before, I couldn’t figure out what terms to use in the search and everything I tried resulted in something I couldn’t use. Also thanks in advanced for reading

glEnable and glDisable do not nest so, so remember the first call to glDisable cancels stencils until another glEnable is made