What is the best method to select objects that have been drawn in OpenGL ES 2.0 (iOS)?
I am drawing points.
Here is how i do, based on the above solution, with depth buffer for 3D picking and GLKVector3 signature to retrieve the seal :
In the Shader (vertex or fragment as you want)
add a picking boolean which tell you if you do the pick pass or not
uniform bool picking;
and the GLKVector3
uniform vec3 color;
if the boolean picking is activated so the color will be the GLKVector3
if(picking)
{
colorVarying = vec4(color, 1.0);
}
In the ViewController
the method which create the GLKVector3 from a seal (when i create a new 3D object) :
-(GLKVector3)pack:(uint)seal
{
GLKVector3 hash;
float r = seal % 255;
float g = (seal / 255) % 255;
float b = (seal / (255 * 255)) % 255;
hash = GLKVector3Make(r/255, g/255, b/255);
return hash;
}
And the view controller code where you get the pixel from the touch position and get the selected seal from the selected color :
-(uint)getSealByColor:(GLKVector3)color
{
color = GLKVector3DivideScalar(color, 255);
for (MyObject *o in _objects) {
if(GLKVector3AllEqualToVector3(o.color, color))
{
return o.seal;
}
}
return 0;
}
-(void)tap:(UITapGestureRecognizer*)recognizer
{
CGPoint p = [recognizer locationInView:self.view];
GLKVector3 i = [self pickingAt:p];
_sealSelected = [self getSealByColor:i];
}
-(GLKVector3)pickingAt:(CGPoint)position
{
CGFloat scale = [UIScreen mainScreen].scale;
GLsizei w = self.view.bounds.size.width * scale;
GLsizei h = self.view.bounds.size.height * scale;
GLuint fb;
GLuint rb;
GLuint db;
Byte pixelColor[4] = {0,};
glGenFramebuffers(1, &fb);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glGenRenderbuffers(1, &rb);
glBindRenderbuffer(GL_RENDERBUFFER, rb);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, w, h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb);
//here we also create a depth buffer for 3D objects picking
glGenRenderbuffers(1, &db);
glBindRenderbuffer(GL_RENDERBUFFER, db);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, w, h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, db);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
NSLog(@"Framebuffer status: %x", (int)status);
return GLKVector3Make(0.0, 0.0, 0.0);
}
//we render the scene with our picking boolean activated
[self render:YES];
glReadPixels(position.x * scale, (h - (position.y * scale)), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixelColor);
glDeleteRenderbuffers(1, &db);
glDeleteRenderbuffers(1, &rb);
glDeleteFramebuffers(1, &fb);
return GLKVector3Make(pixelColor[0], pixelColor[1], pixelColor[2]);
}
Hope this help someone, this is how i do to allow color picking for more than 255 objects.