OpenGL Picking Tutorial

- Introduction
Hi, MGD here with a tutorial for OpenGL picking. Ever make a 3D scene, but you want the user to be interactive with the 3D objects in it using the mouse, but just cant seem how to dectect what the user clicks? Well listen up! First, what is picking? Well, picking is the process of the user clicking on a 3D scene, the program processing which clickable geometry and/or OpenGL primative was clicked, then sending that "hit record" to the list of events to be processed later. You can do this 2 ways from what I know. Either way uses both the SDL and GLU libraries. Theres the coding way to do this where glu detects which primative was hit by storing the name assigned to the primative and some depth info to a hit list. But thats not the way we will be doing in this tutorial so forget everything I said about that. The way we will be focusing on is detecting which primative was hit by assigning a different color to each object and finding out which object was hit by detecting the pixel color where the scene was clicked. I like this way better because you can have more clickable objects than what the coding way would allow. The language for this tutorial will be FB, though it is easily ported to C.
- Process

- SDL Detects that the user has clicked somewhere on the 3D scene
- Program passes mouse coordinates from SDL to our Picking Sub
- Picking sub renders scene again as it was when user clicked, except using no lighting, materials, and renders the scene with all clickable objects a different color and those that arn't clickable black
- GL gets the pixel RGB value of mouse coordinates
- Program checks that value to every object's "color code" that you rendered the scene with
- Sub sends the results to wherever or whatever you need them for
- You pop your matix, do not switch the buffers (so the user doesnt see it), load your identity and continue as usual

- How we do it
First thing is that I will be explaining a few commands that we will need:
-SDL_MOUSEBUTTONDOWN
This is the value that the SDL_PollEvent function gives when the user has the mouse button down
-SDL_GetMouseState @X, @Y
This will give us the X and Y coordinate of the cursor position (Note: The Y axis is flipped, with the Y increasing from top to bottom, therefore we will need to flip it later)
-glDisable GL_DITHER
This will disable GL Dithering which can affect colors (It turns off the checkerboard patterns that some adapters use to make a color that it cant do as a solid 1...an example is checkering red and white to make pink, note: because of turning this off the adapter will make the color outputed the closest to the color that was specified, this is a problem when trying to read back the colors in the buffer...If you specify pink as a color for an object and the adapter can only output a red color then when you try to read it back it will read as red and not pink...to advoid this error make sure the monitor is in true color mode and 24-32 million colors are being used, if you cant then at the beginning of the program, output each color for your objects to the screen and read them back, then use those values that you read back as the values you check with later on)
-glEnable GL_DITHER
Guess :P
-glGetIntegerv GL_VIEWPORT, @viewport(0)
Gets info from the current viewport that we will need later on to read the pixels and will store them in the second parameter
-glReadPixles Cursor_X, Cursor_Y, width, height, GL_RGB, GL_UNSIGNED_BYTE, @pixel(0)
Get the pixel color from the X, Y position specified, at the width and height specified (Like a keyhole), in RBG format, with the UByte datatype into the pixel() (Our cursor position will be the X, Y coordinate and the width and height will be 1px*1px)
- This Might Explain Better (Pictures are good):
Rendered Picking Buffer Our Rendered Scene
So, ok...Now I know a bunch of GL commands, how do I put them together? Here's a workin example of all you need to know Picking Example.