opengl每一个物体添加完整的边框
简述:通过控制深度测试,及模板缓冲的清除。当开启边框绘制后,可绘制完整物体边框或物体连接的整体边框。
问题:轮廓物体绘制后,如果再次绘制物体需要另外处理。
代码流程:
//先进行模板缓冲测试,在进行深度测试
glEnable(GL_DEPTH_TEST); //深度测试
glEnable(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilMask(0x00); // 保证绘制其他物品的时候不会更新模板缓冲
//---绘制其他物品-----//
drawOther();
//--绘制轮廓物品--//
is_border = true; //开启边框绘制
is_all_connect_border = false; //是否连接所有边框
if (is_border)
{
glStencilFunc(GL_ALWAYS, 1, 0xFF);;//物体片段被渲染时(设为总是通过),将模板缓冲更新为1
glStencilMask(0xff);
shader.use();
model = glm::scale(model, glm::vec3(1.0f, 1.0f, 1.0f)); //重复绘制时,重置model大小
shader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
outShader.use();
glStencilFunc(GL_NOTEQUAL, 1, 0xff); //物体片段被渲染时,不等于1的部分(上一个立方体绘制时将片段模板缓冲更新为1)被绘制,其他部分丢弃
//为了模板缓冲不被改变
glStencilMask(0x00);//禁止写入模板缓冲
if (is_all_connect_border)//需要所有轮廓链接时,关闭深度测试,丢弃挡在其他物体前的轮廓-与绘制的先后顺序有关
{
glDisable(GL_DEPTH_TEST);//不开启深度测试,即深度测试结果总为不通过
}
glDrawArrays(GL_TRIANGLES, 0, 36);
//-------end
glStencilMask(0xFF);
glEnable(GL_DEPTH_TEST);
if (!is_all_connect_border)
glClear(GL_STENCIL_BUFFER_BIT);//清除模板缓冲
}
else
glDrawArrays(GL_TRIANGLES, 0, 36);
shader.use();
//----------end-----------//