Picking triangles in OpenGL core profile when using glDrawElements

ぃ、小莉子 提交于 2019-12-05 17:13:22

About the 'color coding' approach, you could use gl_PrimitiveID to fill the color coded buffer(s) using a proper fragment shader, this would basically give you the index of the drawn triangle.

About the CPU based picking, you could use an existing library that handles the acceleration structures, and ray-mesh intersection, such as Bullet or Opcode.

The 'best' option for you depends of your use case, hard to tell.

Try seeing it from this perspective: OpenGL is only meant for drawing things. Picking should be done in another way. If you insist on using OpenGL for it (not unreasonable), use a FBO with a integer 16 bit single channel color buffer attachment, into which you render the object ID. Picking reduces to read the one pixel for the ID.

Finally I could do CPU based picking by shooting a pick ray through the mouse location, but this would be quite slow since I guess I would have to transform the triangles on the CPU, so I would prefer a GPU based solution.

I recommend this. However instead of transforming all the triangles, just inversely transform your one picking ray. You should manage you scene in some spatial subdivision structure anyway, so testing against that should be trivial.

Well you can indeed provide per triangle information on a DrawElements call. You then will have to provide the corresponding arrays (the former COLOR_ARRAY, TEXTURE_COORD_ARRAY, etc., now commonly called VertexAttribArrays). This would be probably the easiest solution if you insist on the GPU.

However, usually the way to go would be to fire a ray from the click point into your scene. Consequently, what you will have to do is not to transform each triangle, but to calculate an intersection test between your ray and your triangles. If the ray intersects, you hit it, if not you didn't. This indeed could come at quite some cost if you do it brute force.

However, usually you will have your triangles contained within some spatial data structure (i.e. your scene graph will/can/should have a few representations) like a octree (http://en.wikipedia.org/wiki/Octree) for example. This will allow for a collision response in quite a few tests. Additionally you can take into account the the final size a triangle will occupy on the screen (so it would be quite meaningless to select subpixel triangles in most cases).

And if you really want to get fancy, you can put the whole process to the GPU, too (one example that sounds interesting is e.g. http://blog.xeolabs.com/ray-picking-in-scenejs, but there will be more coming up when you use google).

I personally thing the easiest to implement is solution b) Software Ray Picking, then a) and finally GPU picking. Start of with the easiest, improve if you figure it is not fast enough. Don't be caught by too much premature optimization (e.g. ray-cast picking works perfectly well on my iPhone ;). Have fun and good luck with your picking algo.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!