Mouse selection

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

Mouse selection

elect
Hi,

I would need that when I click somewhere on my render, my program could know where I clicked (more or less), let's say a kind of selection

I tried to read and understand at the best this

http://www.opengl.org/resources/faq/technical/selection.htm#sele0020

Basically there are three options:

- selection render mode

- render each primitive in an unique color

- generate a pick ray


I opened this 3d to ask you guys, since that page has some years, if all of them are still valid, or there is a new method that is not listed there
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

Demoscene Passivist
Administrator
>if all of them are still valid, or there is a new method that is not listed there

Yep they are all still valid, but I would suggest going for "render each primitive in an unique color" as its the most performant way todo reliable picking. U can simply do it with a FBO and a multiple-rendertarget fragment-shader.

Bug if u have to support very very old hardware then "selection render mode" maybe the way to go ... just my 2 cents  
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

elect
Demoscene Passivist wrote
>if all of them are still valid, or there is a new method that is not listed there

Yep they are all still valid, but I would suggest going for "render each primitive in an unique color" as its the most performant way todo reliable picking. U can simply do it with a FBO and a multiple-rendertarget fragment-shader.

Bug if u have to support very very old hardware then "selection render mode" maybe the way to go ... just my 2 cents
Thanks for the replay :)

No, I dont need to support old hw

But do you have any link to some good tutorial or examples for that?
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

gouessej
Administrator
In reply to this post by Demoscene Passivist
Demoscene Passivist, I'm not sure to understand what you mean. Color picking is not reliable as some computers (especially laptops) may emulate a part of the palette and in such a case, color picking does not work at all.

Elect, I gave you an example of picking using JOGL on javagaming.org. However, hardware accelerated picking should not be used anymore because it relies on deprecated features of OpenGL and anyway, I observed important slowdowns when mixing shaders with it on some machines. Software picking might be slower but it is often more reliable.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

elect
gouessej wrote
Elect, I gave you an example of picking using JOGL on javagaming.org. However, hardware accelerated picking should not be used anymore because it relies on deprecated features of OpenGL and anyway, I observed important slowdowns when mixing shaders with it on some machines. Software picking might be slower but it is often more reliable.
Wait, im a nub :D what do you mean by hardware/software picking? What do they refer to? And the why shader?


Ps: trying to understand which are the picking methods, I went backward some page of the link you gave me

http://www.lighthouse3d.com/opengl/picking/

and I found the "name stack"

Trying to figure out the limitation of this one and the color one, I calculated that with the unique-color I could have at maximum 2^(8+8+8) = 16777216 possible different colors.

Now for the "name stack"

The stacks maximum dimension is implementation dependent, however according to the specs it must contain at least 64 names which should prove to be more than enough for the vast majority of applications. Nevertheless if you want to be sure you may query the state variable GL_NAME_STACK_DEPTH (use glGetIntegerv(GL_NAME_STACK_DEPTH)). Pushing values onto the stack beyond its capacity causes an overflow error GL_STACK_OVERFLOW.

Then I coded:

int test[] = new int[1];
       
        gl.glInitNames();
        gl.glGetIntegerv(GL2.GL_NAME_STACK_DEPTH, test, 0);
       
        System.out.println("GL_NAME_STACK_DEPTH: "+test[0]);


But I am getting this:

GL_NAME_STACK_DEPTH: 0

Why?
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

elect
That was wrong, I modified as follow

int test[] = new int[1];
       
        gl.glInitNames();
        gl.glGetIntegerv(GL2.GL_MAX_NAME_STACK_DEPTH, test, 0);
       
        System.out.println("GL_MAX_NAME_STACK_DEPTH: "+test[0]);


And now I get:

GL_MAX_NAME_STACK_DEPTH: 128

Is that possible? So few?
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

gouessej
Administrator
In reply to this post by elect
Ok... Hardware accelerated picking relies on hardware acceleration, in our case with OpenGL. Software picking is done without OpenGL. Some methods required to use OpenGL picking work badly when you use some shaders, I haven't found why. The Khronos Group started deprecating some methods since OpenGL 3.0; as far as I know, glInitNames and glSelectBuffer are deprecated.

Therefore, using OpenGL picking has some pedagogical interests but I don't advise you to rely on it for real programs.

I advise you to look at the "man" of each method you don't know. The "man" is available in command line on GNU Linux and online too:
http://www.opengl.org/sdk/docs/man/

This doc contains only methods still supported in OpenGL 4.2:
http://www.opengl.org/sdk/docs/man4/
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

Sven Gothel
Administrator
In reply to this post by Demoscene Passivist
On 02/29/2012 09:18 PM, Demoscene Passivist [via jogamp] wrote:
>
>
>> if all of them are still valid, or there is a new method that is not listed
> there
>
> Yep they are all still valid, but I would suggest going for "render each
> primitive in an unique color" as its the most performant way todo reliable
> picking. U can simply do it with a FBO and a multiple-rendertarget
> fragment-shader.

<http://jogamp.org/git/?p=jogl.git;a=blob;f=src/test/com/jogamp/opengl/test/junit/graph/demos/ui/SceneUIController.java;h=c6d43480ae61b479d72232586dc0ebefd0030468;hb=HEAD#l133>

Utilizes false color rendering for selection and
glReadPixels(..) from the default buffer 'GL_BACK'.

It injects a GLRunnable into the drawable 'stream', which 'boolean run()'
method returns 'false'. The latter causes the GLAutoDrawable to re-render
the frame with proper colors.

This is hw accelerated and as precise as 'you can see it' :)

Of course 'shooting a ray' maybe also something here
but for sure it would take more CPU time than this little piece of code,
which runs on any device (ES1/ES2/>=GL2).

~Sven

>
> Bug if u have to support very very old hardware then "selection render mode"
> maybe the way to go ... just my 2 cents  


signature.asc (910 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

gouessej
Administrator
glReadPixels is not that fast.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

elect
In reply to this post by Sven Gothel
And what about the idea suggest by Demon in the first answer?

http://stackoverflow.com/questions/5543401/opengl-mouse-picking-strategy

Reading depth of 1 pixel (the one corresponding to the mouse position) and then use gluUnProject to get all the other coordinates...

It looks easy and simple.. what you think about?
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

elect
In reply to this post by Sven Gothel
double
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

Sven Gothel
Administrator
In reply to this post by elect
On 03/01/2012 05:07 PM, elect [via jogamp] wrote:

>
>
> And what about the idea suggest by Demon in the first answer?
>
> http://stackoverflow.com/questions/5543401/opengl-mouse-picking-strategy
>
> Reading depth of 1 pixel (the one corresponding to the mouse position) and
> then use gluUnProject to get all the other coordinates...
>
> It looks easy and simple.. what you think about?
This differs w/ the type of detection only, ie. false color vs. view/model
coordinate transformation.

As Julien pointed out, sure, glReadPixel takes a roundtrip (glFinish/sync ..
read .. ). As mentioned, one could use PBO on desktop when rendering is done
in a seperate buffer and if the click result can wait 1 frame let's say.
even though this would not blocking fluent rendering, the click response
would be '1 frame late':

Event based selection async w/ PBO and FBO

frame 1 - render to dedicated FBO for selection
          and start glReadPixel w/ PBO (async)

frame 2 - sync data of glReadPixel (probably done by now)
          and analyze it via false color per object
          -or-
          glUnProject of winx/winy and depth (winz).

If glReadPixel becomes an performance issue (1 pixel read),
I would do actual test on those different
refinements of the technique. Guess it's use-case dependent.

Good discussion.

~Sven


signature.asc (910 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

elect
If we are speaking about milliseconds is totally acceptable ;)

Moreover, why I need a dedicated FBO and a PBO? Couldnt I just retrieve the pixel depth and pass it to the gluUnProject?

Do you have some link to any guide/tutorial?
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

gouessej
Administrator
Why don't you try to understand the example code I gave you on javagaming.org, it already uses gluUnproject, etc...
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

elect
gouessej wrote
Why don't you try to understand the example code I gave you on javagaming.org, it already uses gluUnproject, etc...
Yep gouessej, ok, I will see it carefully :)
Reply | Threaded
Open this post in threaded view
|

Re: Mouse selection

Sven Gothel
Administrator
In reply to this post by elect
On 03/02/2012 02:09 PM, elect [via jogamp] wrote:
>
>
> If we are speaking about milliseconds is totally acceptable ;)
>
> Moreover, why I need a dedicated FBO and a PBO? Couldnt I just retrieve the
> pixel depth and pass it to the gluUnProject?
>

As I mentioned, you can do this - but w/o async read access.

Synchronous read is very simple and w/o an additional FBO, as pointed
out in the link to our demo code, and others.

The pseudo code just covers the async read access using FBO/PBO.
You need an extra render target here (FBO), otherwise the result
would be overwritten by the next frame's back-buffer write operation.
Sure, you might be able to use the front buffer to read it out before swap
- sill having the 1-frame-lag allowing PBO async read to be finished.
PBO is currently the only way to issue async read.

> Do you have some link to any guide/tutorial?

We haven't tried the async PBO glReadBuffer in our code yet,
since it's not ES2 compliant. Julien has some code I assume.

However, all the given pointers here should enable you to impl. it.
If you are willing to create some selection unit test
utilizing the different techniques I will help w/ that.

~Sven


signature.asc (910 bytes) Download Attachment