Outlining objects with OpenGL stencil testing

Arkwood puffed his herbs. ‘Just need to know when the grass is good, maaaaann,’ he drawled.

I opened my Microsoft Visual Studio C++ application (with OpenGL graphics library and the Oculus SDK for Windows) and pondered. How should the grass in the virtual world indicate that it is good to harvest?

Thankfully the Learn OpenGL article Stencil testing offered a helping hand. I will use stencil testing to draw a blue outline around my grass, to show that it is ripe for plucking.

First, I need to attach both a depth buffer and a stencil buffer as a single texture:

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, size.w, size.h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, dbuffer->texId, 0);

Next, I set up stencil testing to draw my grass:

glEnable(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

glStencilMask(0xFF);
glClear(GL_STENCIL_BUFFER_BIT);

glStencilFunc(GL_ALWAYS, 1, 0xFF);

for (int i = 0; i < numMyGrasses; ++i) {
    MyGrasses[i]->UseOutline = false;
    MyGrasses[i]->Render(view, proj);
}

But I only use stencil testing to draw an outline around my grass if I stroll close to it (i.e. a Z coordinate greater than 19.0):

if (position_z > 19.0) {
    glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
    glStencilMask(0x00);

    for (int i = 0; i < numMyGrasses; ++i) {
        MyGrasses[i]->UseOutline = true;
        MyGrasses[i]->Render(view, proj);
    }
}

glDisable(GL_STENCIL_TEST);

Notice the UseOutline struct member. This allows for scaling of the grass, to define an outline:

if (UseOutline) {
    float scale = 1.2;
    Mat = Mat * Matrix4f::Scaling(scale, scale, scale);
}

And for drawing the outline in the fragment shader:

"if (uIsOutline == true) {\n"
    "   FragColor = vec4(0.0, 0.0, 1.0, 1.0);\n"
"} else {\n"
    "   FragColor = texColor;\n"
"}\n"

Splendid. I asked Arkwood to put on the Oculus Rift virtual reality headset and pluck his grass. Here’s the grass some distance away:

But as Arkwood strolls closer, the grass suddenly sports a blue outline:

With a blue outline, the virtual world has indicated to my buddy that the grass is selected, ready to gather for his illicit use.

‘That’s heavy, man,’ he slurred, rolling up a joint.

He was smoking thin air. High on placebo.

Hung a kidney dish from his ear. ‘Yam yam! Tree treacle…’ And he slept.

https://myspace.com/rdmilligan/music/album/bones-ep-19172460