Color picking is a simple method to implement the object selection. It is very accurate as well, actually pixel accurate.
However since it involves read back the frame buffer data the performance won't be that good.
Steps involved in the implementation,
1. Draw your 2d or 3d object as you would normally do
2. Setup a frame buffer object
3. Assign unique ID and color to each object
4. Draw the object with the unique color assigned
5. Using the given screen coordinate retrieve the color.
6. Use the color to identify the object, and you are done
Frame buffer object creation
glGenFramebuffers(1, &mChoose.mFrameBuffer); glGenRenderbuffers(1, &mChoose.mDepthRenderbuffer); glGenTextures(1, &mChoose.mTexture); glBindTexture(GL_TEXTURE_2D, mChoose.mTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mW, mH, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBindRenderbuffer(GL_RENDERBUFFER, mChoose.mDepthRenderbuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mW, mH); glBindFramebuffer(GL_FRAMEBUFFER, mChoose.mFrameBuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mChoose.mTexture, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mChoose.mDepthRenderbuffer);
Object selection
Let the mesh to be drawn are stored in vector objects and let px and py be the screen coordinates.
unsigned char data[4] = {0.0f}; glReadPixels(px, mH-py, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data); for (ObjectMapIter iter = objects.begin(); iter != objects.end(); ++iter) { if (iter->mR == data[0] && iter->mG == data[1] && iter->mB == data[2]) { clickedItem = iter->mObject; break; } }
Complete source code is available at https://github.com/trsquarelab/glexamples
No comments:
Post a Comment