有条件的渲染

时间:2019-08-20 11:30:15

标签: c++ opengl glm-math

我要渲染的网格很多,有些很大。所以我想使用条件渲染。

下面是代码摘录

glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);    //  not written in the framebuffer
glBeginQuery(GL_SAMPLES_PASSED, QueryName); // Beginning of the samples count query
    // render simple bounding box
glEndQuery(GL_SAMPLES_PASSED);

// render only if a sample pass the occlusion query.
glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);    // written in the framebuffer
glBindBufferRange(..);
glBeginConditionalRender(QueryName, GL_QUERY_WAIT);
    glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f)[0]); // ****** all other meshes will be erased *******
    // render complex and heavy mesh
glEndConditionalRender();

它可以工作,但是问题在于在第二次渲染之前清除帧缓冲区会擦除以前的任何网格。

那么我如何使用其他深度缓冲区或任何缓冲区绑定在所有网格上使用遮挡查询?

我正在使用OpenGL core 4.5

1 个答案:

答案 0 :(得分:2)

按照Botje的建议,我使用“深度预传递”来确定要完全渲染哪些网格。 每个网格都有一个布尔值(bOcclusion)以跟踪深度测试结果 它工作正常。 一些伪代码

// Main rendering loop
// setup matrix and options...........
 // ** not writing in the framebuffer
glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 

foreach(mesh,vectorMesh){ // first pass
     mesh->render(glm::dmat4,uint optionOcclusion);
      }

glClearDepth(1.0f);
// ** writing in the framebuffer
glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 

foreach(mesh,vectorMesh){ // second pass
     mesh->render(glm::dmat4,uint optionRender);
      } 

// **************  mesh rendering  *************
// mesh has a boolean (bOcclusion) showing depth test result 

void mesh::render(glm::dmat4,uint options)
{
 if(options & RENDER_MODE_OCCLUSION){
  glClearDepth(1.0f);
  glBeginQuery(GL_ANY_SAMPLES_PASSED, queryOcclusion);
   // ....setup VAO  and buffers for bounding box
   // render bounding box
  glEndQuery(GL_ANY_SAMPLES_PASSED);
  glFinish();  // make sure GL_QUERY_RESULT is available
  uint nb;
  glGetQueryObjectuiv(queryOcclusion,GL_QUERY_RESULT,&nb);
  bOcclusion = (nb>0);
  return;
  }
 else if(!bOcclusion)
  return;

 // normal complete rendering
 // ....setup VAO  and buffers for full mesh
 // render full mesh
}