2d Picking with overlapping, transparent images

Started by
5 comments, last by BornToCode 9 years ago

Hi guys,

I read many tutorials in the last few days, but unfortunately I was unable to figure out, how to do the following...

The following 3 sample images are loaded during the startup of my game:

4g3mvt.png
2qbuq74.png
23ra0ko.png
In the game they are displayed as illustrated below:
25q9i8p.png
As you can see, it is possible that the images are overlapping. The question is, how do I know which image is picked? glReadPixels() is not fast enough. The images are having a transparent border... How to know which object was picked and what is the fastest method?
Thanks for any suggestions :)
Advertisement

You could store a collision map in memory and just check if the the picked pixel is transparent. Then you can just check from front to back and the first image with an opaque pixel is the one you want. The collision map can just be an array of bools or uint8_t (0 for transparent, 1 for opaque). Don't know if this is the fastest way, but it's definitely faster than reading from the GPU.

You want to do mouse picking 100% on the cpu (except for some rare situations).

The 2d brute force method is to iterate through your objects, if the stacking depth is closer than the current hit; check the bounds; if the bounds hit; check the pixels by having the CPU look in the image data. (Or by making a 1bit per pixel hit testing image)

The 3d brute force method is to iterate through your objects, testing a mouse ray against a bounding sphere; if the hit is closer than the current hit, test the ray against the mesh, or a simllified capsule mesh.

In both cases, if there are too many objects, put the objects in some type of space partitioning (quadtree, octree, bvh) to avoid testing all objects.

what do you mean by transparent borders? anti aliased ?how is your scene? are you using a Z buffer to decide which one is on the top?

if so I guess one way (for complex scenes otherwise I guess as DaveSF said it's better to do it on CPU) is to render the scene into a texture. and whilst drawing objects, give them an ID (sent to frag shader as a uniform and shader will draw objects in color of their ID) and then draw the scene (use depth test) and read the color of the point you want to check , to which object it belongs. and check it with you objects' IDs

Color buffer picking, as IYP describes, is an alternative to stencil picking..

Either way, it is typically done *after* the click. A small buffer and transform matrix is setup that only renders pixels *very* near the mouse click, and each object is a different color. Sometimes multiple objects per pixel are recorded.

Stencil/color picking techniques are most useful for 3d modeling tools, or other situations where the model complexity is very high and dynamic, making it hard to do picking with the CPU. They are not typically used in games.
you create a collision map that map whether a point is part of an object or not by first projecting the point on each plane of the objects that you are interested in. Then when you are done you can do distance check and grab the one with the smallest Value.
Another faster way you can do it is that as you project the point and checking if a point is withing an object bound. Just keep track of the smallest value. Then once you are done you can map that smallest value to a map. Kind of like map<int,object>. I hope this make sense to you otherwise I can post some sample code to show you what I mean.

This topic is closed to new replies.

Advertisement