3
\$\begingroup\$

My system: Catalyst 15.12, mesa 11.2.1, Archlinux, kernel 4.5.1

Depending on camera position I get inconsistent occlusion query results. Following scene contains wall, objects behind wall and objects on sides. Objects behind wall are always invisible(correct). Objects on sides should be always visible but sometimes marked as invisible. Why? On screenshots green means visible, red boundary means occluded: Correct results Totally incorrect

This is the code that I use:

void gems_render_objects(Scene *scene) {
    int i = 0, j = 0, res;
    AssetInstance *inst;

    if(!s_queryIds) {
        s_queryIds = (GLuint*)malloc(sizeof(GLuint)*(scene->numInstances));
        glGenQueries(scene->numInstances, s_queryIds);
    }

    //draw everything
    for(i = 0; i < scene->numInstances; i++) {
        glc_draw_inst(scene, scene->instances+i, &s_curProgramId, &s_curVaoId);
    }

    //query everything
    glDepthMask(GL_FALSE);
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    for(i = 0; i < scene->numInstances; i++) {
        inst = scene->instances+i;

        glBeginQuery(GL_SAMPLES_PASSED, s_queryIds[i]);
        glc_draw_inst(scene, inst->bbInst, &s_curProgramId, &s_curVaoId);
        glEndQuery(GL_SAMPLES_PASSED);
    }
    glDepthMask(GL_TRUE);
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

    //draw bounding boxes of invisible
    glDepthMask(GL_FALSE);
    glDisable(GL_DEPTH_TEST);
    for(i = 0; i < scene->numInstances; i++) {
        inst = scene->instances+i;

        res = 0;
        glGetQueryObjectiv(s_queryIds[i], GL_QUERY_RESULT, &res);

        if(res == 0) {
            GLenum prevDrawType = inst->bbInst->asset->drawType;
            inst->bbInst->asset->drawType = GL_LINE_STRIP;
            glc_draw_inst(scene, inst->bbInst, &s_curProgramId, &s_curVaoId);
            inst->bbInst->asset->drawType = prevDrawType;
        }
    }
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
}
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

I needed to use glDepthFunc(GL_LEQUAL) for queries because bounding boxes have the same size as objects size (z-fighting).

//query everything
    glDepthMask(GL_FALSE);
    glDepthFunc(GL_LEQUAL); //this is critical
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    for(i = 0; i < scene->numInstances; i++) {
        inst = scene->instances+i;

        glBeginQuery(GL_SAMPLES_PASSED, s_queryIds[i]);
        glc_draw_inst(scene, inst->bbInst, &s_curProgramId, &s_curVaoId);
        glEndQuery(GL_SAMPLES_PASSED);
    }
    glDepthMask(GL_TRUE);
    glDepthFunc(GL_LESS);
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .