JOGL, color picking

If you would like to be able to select objects in your scene, color picking is one possibility. Not that difficult and complex to realize.

OpenGL has two buffers, a back and a front one. This is useful to avoid that a scene not yet rendered completely could be delivered to the screen and shown to the user. So OpenGL renders in the back buffer and then “swap” all the content in the front one.

All what you have to do is simply disable the automatic buffer swapping when you are creating the canvas, by typing:

//  Disable auto swapping for buffers

with autoSwapBuffers equals to false.

Then add at the end of the display() something like:

if (!autoSwapBuffers) {
    if (disableManualBufferSwapping) {
        disableManualBufferSwapping = false;
    } else {

To manually swap buffer when the autoSwapBuffers is false. Moreover you can temporary disable it.

Supposing to have a unique pipeline containing all the elements you want to render, each of them may use its own index to generate a specific color.

Color index = new Color(-selection_index);
gl2.glColor3f(index.getRed() / 255.0f, index.getGreen() / 255.0f, 
index.getBlue() / 255.0f);

Each object will use this color to render itself only in the back buffer for picking purposes. User won’t see any strange color because we will disable temporary the buffer swapping by setting disableManualBufferSwapping to true.

Then in the mouse listener whenever the user click to select we need to:
– save the point
– set backBufferRenderingOnly to true
– refresh (I suppose you call the refresh every time you need, so no animator)

In the display() if backBufferRenderingOnly is true, we know we have to render only in the back buffer.

if (backBufferRenderingOnly) {
   //  Rendering into the back buffer for color picking
   Color index;
   int i;
   backBufferRenderingOnly = false;
   FloatBuffer pixels = FloatBuffer.allocate(4);
   RenderingObject object;

   //  Select the back buffer, once for all

   ArrayList objects = getRenderingObjects();

   if (!objects.isEmpty()) {
       * Rendering all objects.
       for (int j = 0; j < objects.size(); j++) {
       int[] viewport = new int[4];

       gl2.glGetIntegerv(GL2.GL_VIEWPORT, viewport, 0);

       gl2.glReadPixels(picking.x, viewport[3] - picking.y, 
                             1, 1, GL2.GL_RGBA, GL2.GL_FLOAT, pixels);

       index = new Color(pixels.get(0), pixels.get(1), pixels.get(2));

       i = index.getRGB();

       // -1 means click in the background
       if (i != -1) {

          // This will deselect all the previous selected items
          for (int j = 0; j < objects.size(); j++) {
              object = objects.get(j);

          object = getRenderingObjects().get(-i - 2);

          this.selectedObject = object;
       // Click user is on nothing
       else {
          this.selectedObject = null;
          for (int j = 0; j < objects.size(); j++) {
             object = objects.get(j);
       //  Disable manual buffer swapping for one time
       disableManualBufferSwapping = true;

And then you should be done 🙂



Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:


Stai commentando usando il tuo account Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...