My scene has a 1×1×1 cube, it’s blown to be 50×50×4, it’s located in (-2, -2, -2). I render the bounding box at the end of one frame and query the occlusion results at the beginning of the next frame to determine if the cube should be rendered——using glGetQueryObjecti(id, GL_QUERY_RESULT). When the cube is in my field of view, the result is sometimes normal, sometimes zero. I don’t know why.
This is my window:
My camera is close to the cube, the window’s size is 640×480. The printed query result:
glGetQueryObjectui(id, GL.GL_QUERY_RESULT_AVAILABLE) was called before the query result was retrieved.
I guess that’s what I did—— I render the bounding box at the end of one frame(frame n) and query the occlusion results at the beginning of the next frame(frame n+1) to determine if the cube should be rendered, if result of using glGetQueryObjectui(id, GL.GL_QUERY_RESULT_AVAILABLE) is false, I won’t render the bounding box at the end of frame n+1.
yes, query.isReady is implemented using GL.GL_QUERY_RESULT_AVAILABLE.
I’m not sure what you mean. I used glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0) at the end of the query, followed by glFlush. When query.isReady is true, glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, 0) is GL_ALREADY_SIGNALED. Shouldn’t I get query results at this point?
Hello,
I am wondering, you use the query to see if you should render the real or the simplified object and the problem is that your output shows a number of samples passed that is switching between 0 and exactly 4x your window size (probably multisampling) but do not observe any screen flickering? like i would expect the geometry to only render every other frame according to that output and your description
once your object was visible one time, it will always render the real object? (Looks like what you are observing)
But if you only use a query if the object is not visible, how can you get that output at all?
the general idea for the easiest approach would look quite similar to what you have
Rendering process{
if(query.isReady()){
int samples = query.getQueryResult()
beginQuery
renderBox(samples > 0 ? real : simplified)
endQuery
}else{
int samples = query.getLastValidResult()
renderBox(samples > 0 ? real : simplified)
}
}
(assuming isReady() returns true for a query that has never been started and getQueryResult() internally stores the result in a field that can be retrieved with getLastValidResult())
where you reuse the same query as soon as the query result is available (you might end up reusing the same result across several frames), which comes with the downside of a higher latency but of course never has to wait for a result of a query
no need for anything “endFrame”. if you mean this:
you dont need fences (glFenceSync, glClientWaitSync, glWaitSync) when using queries that way (fences came in 3.2 and query objects exist since 1.5) and you should avoid calling glFlush.
if you start and end the query before you place the fence, then glClientWaitSync must not neccessarily return GL_ALREADY_SIGNALED when your query result is available, but the otherway round is true of course, once the fence is signaled you can be sure the result is available. you dont need fences here though.
yes, it is flickering, because render and unrender are running alternately.
I am sorry, I made a mistake here. In fact, it is:
Rendering process{
if(query.isReady()){
if(query.getQuerryResult() > 0){
renderBox(real);
}
query.isComsumeResult = true;
}else{
int samples = query.getLastValidResult()
if(samples > 0){
renderBox(real);
}
}
if(query.isComsumeResult){
query.isComsumeResult = false;
disable some opengl attributes(for example GL_LIGHTING, GL_NORMAL, etc)
beginQuery
renderBox(simplified)
endQuery
open some opengl attributes
}
}
I just want to indicate that this is the end of a frame, that is not code.
My problem is still there: sometimes query.getQuerryResult() = 0 and sometimes query.getQuerryResult() = right value, so that object is flickering.
Since even in the second pseudo code you did not rename the method i have to ask: is your real object also a box and all you want to safe is using a more heavy-weight material, not actually the vertex count?
Because to me your new pseudo-code reads like: If the query is ready and samples passed the test, draw the box using the real material (without query), then at the end of the frame, render another box with a cheaper material using a query exactly on top of the box drawn at the beginning (definitely no samples will pass that, as long as you dont set depth compare to less than or equal to as opposed to only less than) which means the next time your query is available no more than 0 samples passed the test, meaning your renderBox(real) will not be called, resuting in the box rendered at the end being visible so the whole thing begins again and you get the output you have shown
EDIT: wait a minute “GL_LIGHTING”, “GL_NORMAL”… you are not, are you?
The real object maybe a complex object, the simplified box is real object’s bounding box. I want to use occlusion query through drawing simplified box to determine if the real object is drawn. When drawing simplified box, I disable following attributes:
Are you using jme for rendering or are we talking about your own fixed function rendering here?
tbh i dont know if query objects do work with the fixed function pipeline. i would think yes but the specs only say that lot of features wont work fit ffp
For real object(complex object), I use jme, because their data structure belong to JME. For simplified box(real object’s bounding box), I rendered them by LWJGL. I use glDrawElements essentially to render a box.
I think my fixed function of rendering is works. If it’s not, I shouldn’t get some right value sometimes.