1

This might appear as a related question:

OpenGL ES 2.0 Object Picking on iOS

Which says Color picker is a good solution, and in deed after reading about it:

http://www.lighthouse3d.com/opengl/picking/index.php?color1

It does seem like a very simple solution so this brings me to this question

OpenGL ES color picking on the iPhone

Which unfortunately uses opengl es 1.0, I am trying to do it in 2.0 so I have no access to the functions described in that question.

But the theory seems simple and here is what I think I should do:

On touches begin I render my objects with a unique color.

On touches ended I get the pixel from that position and check it for the color to get my object. (probably with glReadPixels)

The problem is that I dont know how to do the "Render to the back buffer and read from it".

My code so far simply uses "Draw", I suspect I have to do something like glBindthe other buffer but I would appreciate some help.

My Drawing code is like this:

glClearColor(0, 0, 0, 0.0); 
glClear(GL_COLOR_BUFFER_BIT);

// Set the Projection Matrix
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(60), 2.0/3.0, 0, 50);


glUseProgram(_programHD);

glBindVertexArrayOES(_vao);

glActiveTexture(GL_TEXTURE1); 
glBindTexture(GL_TEXTURE_2D, _textureBuffer[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glUniform1i(uniforms[UNIFORM_TEXTURE_HD], 1);

// Drawing starts here //

// Pass the Model View Matrix to Open GL
_modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix,rotationMatrix);

glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX_HD], 1, GL_FALSE, _modelViewProjectionMatrix.m);

// Change texture coordinates to draw a different image

glUniform2fv(uniforms[TEXTURE_OFFSET_HD], 1, offSet.v);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);

//glUniform2i(uniforms[TEXTURE_OFFSET], 7, -5);
glUniform2fv(uniforms[TEXTURE_OFFSET_HD], 1, borderHD.v);

glDrawElements(GL_LINE_STRIP, 6, GL_UNSIGNED_SHORT, 0);



glBindVertexArrayOES(0);
glUseProgram(0);

I have stripped the drawing calculations to make it more understandable. The point is I do not see anywhere where I specify to "where" am i drawing.

Thanks for your help.

Community
  • 1
  • 1
Pochi
  • 13,391
  • 3
  • 64
  • 104

1 Answers1

0

I've actually just finished implementing a colour picking function into my iPhone game, using openGL ES 2.0, using the lighthouse tutorial funny enough.

You should be drawing to the frame buffer.

If you want to read from the frame buffer, then you're correct in that you want to use glReadPixels. More information is here:

http://www.opengl.org/sdk/docs/man/xhtml/glReadPixels.xml

The only thing that's different from the lighthouse tutorial is that you also want to store the alpha values. Here's a quick function to get the colour of a specific pixel. Feel free to improve it or change it, but it does the job.

+ (void) ProcessColourPick : (GLubyte*) out : (Float32) x : (Float32) y
{
    GLint viewport[4];
    //Get size of screen
    glGetIntegerv(GL_VIEWPORT,viewport);

    GLubyte pixel[4];
    //Read pixel from a specific point
    glReadPixels(x,viewport[3] - y,1,1,
             GL_RGBA,GL_UNSIGNED_BYTE,(void *)pixel);

    out[0] = pixel[0];
    out[1] = pixel[1];
    out[2] = pixel[2];
    out[3] = pixel[3];
}

Hope this helps.

Ben
  • 84
  • 1
  • 7
  • How do you write to this frame buffer but only present the other frame buffer during the same rendering loop? Is it something like you Bind the first buffer, draw, read color pixel, then bind the other, draw, present to screen? could you show me the code for this please? – Pochi Apr 27 '12 at 00:49
  • Sorry, I don't fully understand what you're trying to do. Are you using two different buffers and swapping between them? Are you trying to set up a deferred renderer? As in, outputting from the shader to a render target, to use in another pass? Or are you just trying to pick the colour. – Ben Apr 27 '12 at 02:18
  • I am trying to render some objects on screen, but at the same time render the same objects completely filled with a certain color "off screen" so that when the user touches the screen i can call the read pixel method on the "off screen" render and based on the color i can see what object was touched. – Pochi Apr 27 '12 at 02:35
  • i think i succeded in rendering into 2 different framebuffers, but i just cant get your function to work. I want to NSLog the color (to see if its green) when the user touches the screen, How do i implement your class method? I am guessing that since its outside the rendering cycle i have to bind the buffer and then call the read pixels, but then how do i display the result since its ubyte? – Pochi Apr 27 '12 at 09:45
  • Ok I figured out how to add this to my code, thx. (turned out it was simply an integer) – Pochi Apr 30 '12 at 01:18
  • How do you render 2 different framebuffers? – Michael Chourdakis Oct 12 '12 at 20:07