This is my code that I use to get my mouse position in the 3d scene:
void GetOGLPos(int x, int y, GLdouble &pX, GLdouble &pY, GLdouble &pZ){
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glGetIntegerv(GL_VIEWPORT, viewport);
winX = (float)x;
winY = (float)viewport[3]-(float)y;
glReadPixels(x, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
gluUnProject(winX, winY, winZ, modelview, projection, viewport, &pX, &pY, &pZ);
}
But I noticed a bad thing... 1-2 calls to that function per frame makes CPU usage 100%, 3 or more calls 200% CPU usage (I have 4 cores, 1-2 calls = 25%, 3 or more calls = 50%, I can't make it higher than 50% I think..)
Is there any other way to do this efficiently? I'm using 4 calls to that function every frame so I know which areas I should render for my scene (I take them from each screen corner).
Also I use this to know which place I am pointing with mouse, so I need it in real time, but I would like to use less CPU, because even just 1 call makes it 100% usage for single core systems.
EDIT
I've tr开发者_如何学Cied glPushName() method but its even slower, more likely slower in my GPU than in CPU. Also my CPU usage is only like 0-1% when I don't use a single glReadPixels() call in my program. Weird thing is that I get high CPU usage, but it doesn't make the program lag as you would expect with 100% usage... only problem comes when I use other programs while my program is on, then its laggy to use them.
It seems like you try to do picking in OpenGL.
Check out this tutorial, it should come with less performance penalty than your approach: http://gpwiki.org/index.php/OpenGL:Tutorials:Picking
This place mentions other ways of doing picking in OpenGL: http://www.opengl.org/resources/faq/technical/selection.htm
Are you absolutely sure it's that single function that causes the problem? Have you tried a profiling tool to confirm? Not that I want to doubt you, I just want you to be certain before you go through the trouble of debugging or changing large bits of your code.
I am rather surprised that an OpenGL call (to read one pixel, no less) is taking up CPU time. If anything, I would think it would show 0 CPU usage but have a slow framerate. But, I hardly know enough about OpenGL to suspect that there is anything really wrong with this. It just seems unintuitive I guess.
A forum post about the performance of glReadPixels suggests that certain graphics cards (especially older ones) are simply really inefficient at moving data from GPU to CPU. Can you perhaps run your code on another computer to see if it's just your video card? This would be the best way to start, especially if you have an ATI card and run it on a friend's NVIDIA card, or vice versa.
The post also mentions the data type could make a difference. I don't see it making THIS big of a difference, but who knows.
One more thing you might try: if you call the function four consecutive times, you have three extra unnecessary sets of calls to read the current matrices. Consider taking the matrices via parameters instead. But, I doubt glGetDoublev/glGetIntegerv are really taking much time.
Depending on what you're doing, too, you might want to read about frustrum culling. This sounds like what you're trying to do by getting the four corners of the screen. It might be less expensive for you to implement the math yourself instead of using glUnProject.
glReadPixels will use CPU to convert data read from framebuffer even when you try to use PBO. For example, if you try to read color data by PBO, only when you set param to GL_BGRA then function will do no converting and return immediately. Otherwise if you set param to GL_RGBA, CPU usage will be occupied. I am also trying to read depth data from framebuffer, but glReadPixels will definitely convert data whatever param setup
精彩评论