1
\$\begingroup\$

Hello I tried to implement occlusiong culling to my engine in opengl using java & lwjgl. Occlusion works but... performance drop is huge I mean from 60-70 fps to 3-6 fps. Here is my question what I'am doing wrong ? Here is my code:

                    //this code is after frustrum culling if object passed 

                    glColorMask(false, false, false, false); 
                    glDepthMask(false);                     

                    glBeginQuery(GL_SAMPLES_PASSED, query_id);
                    //renderable is cube not normal object
                    renderable.render();
                    glEndQuery(GL_SAMPLES_PASSED); 

                    int iSamplesPassed = GL15.glGetQueryObjecti(query_id, GL15.GL_QUERY_RESULT);
                    if(iSamplesPassed == 0) {
                        //object is not visible don't render it
                        renderable.setVisible(false);
                    }
                    glColorMask(true, true, true, true); 
                    glDepthMask(true); 

query_id is simply:

query_id = glGenQueries(); //it is called only once on start

I look on some examples and I don't see any diffrences in code. Only diffrence is their and my framerate.

\$\endgroup\$
  • \$\begingroup\$ Its easier, and for reasons answered better, to implement CPU-side bound-frustum culling unless you really know what you're doing \$\endgroup\$ – Khlorghaal Mar 22 '16 at 21:20
5
\$\begingroup\$

You are stalling the GL pipeline with the glGetQueryObjecti() call. The pipeline helps OpenGL render fast because it lets you call new functions while the previous ones are still executing. In some cases however, such as when you do a glGet*() call, it needs to wait for all the previous calls to finish before returning the result. A pipeline stall is so bad that, as you are yourself experiencing, it’s a lot slower to wait for the occlusion query to return than to actually render the object. And this happens for each and every object you draw. This defeats the purpose of a pipeline and needs to be addressed.

One solution could be to send N queries in parallel, then call glGetQueryObjecti N times. This will divide the number of slowdowns by N. Another solution is to ask whether the query has actually finished, using GL_GET_QUERY_AVAILABLE, and if it hasn’t, just render the primitive (because, as established, it’s faster to render the object than to wait for the query result). This will get rid of the stalls, at the expense of a few unnecessary draw calls. You could have a look at Listings 12.3 and 12.4 in the OpenGL Superbible book for a combination of both methods.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.