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.