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 |
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 |
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? |
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
|
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? |
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? |
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
|
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 |
Administrator
|
glReadPixels is not that fast.
Julien Gouesse | Personal blog | Website
|
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? |
In reply to this post by Sven Gothel
double
|
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? 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 |
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? |
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
|
Yep gouessej, ok, I will see it carefully :) |
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 |
Free forum by Nabble | Edit this page |