views:

706

answers:

2

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 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 cant 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: Ive tried 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 dont use a single glReadPixels() call in my program. Weird thing is that i get high CPU usage, but it doesnt 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.

+4  A: 

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

Laserallan
ive tried glPushName() method, its even slower. actually i think it doesnt use CPU, but my GPU, and i get like 10fps instead of 500fps...
Newbie
note that im not picking just like 3 possible objects, i have unlimited amount of possible objects...
Newbie
Added another link about picking in GL and how to approach it. Hopefully you find something useful there.
Laserallan
Why would you ever need to do this more than once per frame?
spurserh
Even once per frame is too much...
Newbie
A: 

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.

Ricket
Yep, i tested with and without glReadPixels() function, and that function was the cause for slowness. Im not sure about the CPU usage, it may be only my CPU model that has this problem.I go the 4 corner thing working more efficiently when i removed the glReadPixels() call completely, i dont know how it works, but it works lol. Yeah i was also thinking i could calculate the view area rectangle myself, but i dont know where to start, and this seems to work well enough.
Newbie