I will explain, how in Poseidon Picking method works.
First of all, the method of picking in OpenGL using glRenderMode(GL_SELECT) and co. are not available under OpenGL ES.
After googling, I found this solution :
- When the mouse is pressed I make a quick render of the scene. The texture are disabled, color shading is disabled and other effects are also disabled.(fog, lights, dither ...)
When a GLObject is rendered a color is associated to this object. Ex: (0A,05,00). As there is the GLWrapper, the color used for rendering is bypass here.
- Once the scene is rendered, I read the pixel at the clicked position. Then, we can compare the read color and GLObject color. We look if color are similar, not exactly match. When you are in 16 bits color rendering, colors may be scaled. That's why when we assign a color to GLObject, we step the next color value of 32(edit : explaination after).
- After that, we render the scene normaly and swap buffers.
Here a rendering using this
picking method.(Not visible on screen)
picking method.(Not visible on screen)
And now the visible rendering.
Here the computation to select GLObject color :
- Select a Red, Green and Blue unique value. Each channel value should be in [0..32[
- Left Shift Bit each channel by 3
When a color is read, compare each channel of read color(Cr) and object color(Co).
For each channel C :
if (abs(Cr-Co) < D)
{
// Channel match !
}
Where D is equal to 5 8. For each color you can have an error of 10 (Co +5 or -5).
EDIT :
To sum up :
- each R/G/B values are in [0..32[
- After the bit shift of 3, the result R/G/B are in [0..256[
But in 16-bits colors mode (for instance 565) :
- When you read back the pixel, R is coded on 5 bits, G on 6 and B on 5 bits.
Let's look on Red channel. The possibles values are limited to 2⁵ = 32.
So the red value is fitted from 256 to 32 ranged.
The way that the value is scaled is obscur for me but if you draw with
red value of 200 and you read back the value, it will be 206.
But anyway, this difference cannot exceed 8 = 256 / 32.
To sum up :
- each R/G/B values are in [0..32[
- After the bit shift of 3, the result R/G/B are in [0..256[
When you are in 24-bits colors :
- When you read back the pixel, you will get the exact same value.
But in 16-bits colors mode (for instance 565) :
- When you read back the pixel, R is coded on 5 bits, G on 6 and B on 5 bits.
Let's look on Red channel. The possibles values are limited to 2⁵ = 32.
So the red value is fitted from 256 to 32 ranged.
The way that the value is scaled is obscur for me but if you draw with
red value of 200 and you read back the value, it will be 206.
But anyway, this difference cannot exceed 8 = 256 / 32.