Loading...
Logo
Processing Forum
Has anyone had success getting a color buffer picker (for picking shapes) in processing 2.0 with open gl?  I'm trying to use my old scripts that employ the picker library.  I get this error:

The type processing.core.PGraphics3D cannot be resolved. It is indirectly referenced from required .class file.

Or use one of the other code snippets out there.  I get these errors when I use this library:


2012-05-23 11:20:23.585 java[2128:1f07] invalid drawable
OpenGL error 1286 at top beginDraw(): invalid framebuffer operation
OpenGL error 1286 at bot beginDraw(): invalid framebuffer operation
OpenGL error 1286 at top endDraw(): invalid framebuffer operation
java.lang.NullPointerException
at processing.mode.java.runner.Runner.findException(Runner.java:618)

Any luck with getting this to work?

Thanks!

Alex

Replies(18)

Anyone?  Thanks.
I've been trying to just import the library directly into processing, but I haven't figured out how to get around an error I get from "createGraphics":

"You need to use "Import Library" to add picking.Buffer to your sketch.

Here is the code:

Copy code
  1. public class Picker {
  2.   
  3.   /**
  4.    * Processing applet
  5.    */
  6.   protected PApplet parent;
  7.   
  8.   /**
  9.    * Main picking buffer
  10.    * Direct access to the buffer is allowed so you can draw shapes that
  11.    * you wouldn't like to draw on the main screen (like bounding boxes).
  12.    */
  13.   public Buffer buffer;
  14.   
  15.   public Picker(PApplet parent) {
  16.     this.parent = parent;
  17.     buffer = (Buffer) parent.createGraphics(parent.width, parent.height, "picking.Buffer");
  18.     buffer.callCheckSettings();
  19.     if (parent.recorder == null) {
  20.       parent.recorder = buffer;
  21.     }
  22.     buffer.background(0);
  23.     parent.registerPre(this);
  24.     parent.registerDraw(this);
  25.   }
  26.   
  27.   public void pre() {
  28.     buffer.beginDraw();
  29.     if (parent.recorder == null) {
  30.       parent.recorder = buffer;
  31.     }
  32.   }
  33.   
  34.   public void draw() {
  35.     buffer.endDraw();
  36.   }
  37.   
  38.   /**
  39.    * Begins recording object(s)
  40.    * 
  41.    * @param i Object ID
  42.    */
  43.   public void start(int i) {
  44.     if (i < 0 || i > 16777214) {
  45.       PApplet.println("[Picking error] start(): ID out of range");
  46.       return;
  47.     }
  48.     if (parent.recorder == null) {
  49.       parent.recorder = buffer;
  50.     }
  51.     buffer.setCurrentId(i);
  52.   }
  53.   
  54.   /**
  55.    * Stops/pauses recording object(s)
  56.    */
  57.   public void stop() {
  58.     parent.recorder = null;
  59.   }
  60.   
  61.   /**
  62.    * Resumes recording object(s)
  63.    */
  64.   public void resume() {
  65.     if (parent.recorder == null) {
  66.       parent.recorder = buffer;
  67.     }
  68.   }
  69.   
  70.   /**
  71.    * Reads the ID of the object at point (x, y)
  72.    * -1 means there is no object at this point
  73.    * @param x X coordinate
  74.    * @param y Y coordinate
  75.    * @return Object ID
  76.    */
  77.   public int get(int x, int y) {
  78.     return buffer.getId(x, y);
  79.   }
  80.   
  81.   /**
  82.    * Get the buffer
  83.    * @return Buffer
  84.    */
  85.   public PGraphics getBuffer() {
  86.     return buffer;
  87.   }
  88.   
  89. }

  90. public class Buffer extends PGraphics3D {
  91.   
  92.   protected int current_color = 0;
  93.   
  94.   public Buffer() {}
  95.   
  96.   public boolean displayable() { return true; }
  97.   
  98.   public  void callCheckSettings() { super.checkSettings(); }
  99.   
  100.   public void background(int arg) { super.background(0); }
  101.   public void background(float arg) { super.background(0); }
  102.   public void background(float arg, float arg_1) { super.background(0); }
  103.   public void background(int arg, float arg_1) { super.background(0); }
  104.   public void background(float arg, float arg_1, float arg_2) { super.background(0); }
  105.   public void background(float arg, float arg_1, float arg_2, float arg_3) { super.background(0); }
  106.   public void background(PImage arg) { super.background(0); }
  107.   
  108.   public void lights() {}
  109.   public void smooth() {}
  110.   public void fill(int arg) {}
  111.   public void fill(float arg) {}
  112.   public void fill(float arg, float arg_1) {}
  113.   public void fill(int arg, float arg_1) {}
  114.   public void fill(float arg, float arg_1, float arg_2) {}
  115.   public void fill(float arg, float arg_1, float arg_2, float arg_3) {}
  116.   
  117.   public void stroke(int arg) {}
  118.   public void stroke(float arg) {}
  119.   public void stroke(float arg, float arg_1) {}
  120.   public void stroke(int arg, float arg_1) {}
  121.   public void stroke(float arg, float arg_1, float arg_2) {}
  122.   public void stroke(float arg, float arg_1, float arg_2, float arg_3) {}
  123.   
  124.   public void textureMode(int arg) {}
  125.   public void texture(PImage arg) {}
  126.   public void vertex(float x, float y, float z, float u, float v) { super.vertex(x, y, z); }
  127.   
  128.   public void image(PImage arg, float arg_1, float arg_2) {}
  129.   public void image(PImage arg, float arg_1, float arg_2, float arg_3, float arg_4) {}
  130.   public void image(PImage arg, float arg_1, float arg_2, float arg_3, float arg_4, int arg_5, int arg_6, int arg_7, int arg_8) {}
  131.   
  132.   protected void imageImpl(PImage image,
  133.             float x1, float y1, float x2, float y2,
  134.             int u1, int v1, int u2, int v2) {}
  135.   
  136.   public void setCurrentId(int i) {
  137.     // ID 0 to 16777214  => COLOR -16777215 to -1 (white)
  138.     // -16777216 is black
  139.     current_color = i - 16777215;
  140.     super.fill(current_color);
  141.   }
  142.   
  143.   public int getId(int x, int y) {
  144.     super.loadPixels();
  145.     // COLOR -16777216 (black) to -1 => ID -1 (no object) to 16777214 
  146.     int id = pixels[y*width+x] + 16777215;
  147.     return id;
  148.   }
  149. }
I never figured out how to implement the Picker in 2.0 (I'm staying in 1.5 for the time being), but I did figure out how to implement it with GLGraphics and use it for picking faces on a mesh.  Hope this is useful to someone. Hopefully will have time to make a stand alone example soon.

Copy code
  1. // CODE needs to be spliced into something else...

  2. import codeanticode.glgraphics.*;
  3. import toxi.geom.*;
  4. import toxi.geom.mesh.*;
  5. import toxi.processing.*;

  6. GLGraphicsOffScreen  pickerB = new GLGraphicsOffScreen(this, height, width, false, 4);
  7. PImage pickerI;
  8. GLTexture tex;

  9. public void initGLPicker() {

  10.   // CONVERT TO GL MODEL START
  11.   currentMesh.computeVertexNormals(); // <-- Insert your mesh here from TOXILIBS (or other GLModel Shape)

  12.   float[] verts=currentMesh.getMeshAsVertexArray();
  13.   // in the array each vertex has 4 entries (XYZ + 1 spacing)
  14.   int numV=verts.length/4;  
  15.   float[] norms=currentMesh.getVertexNormalsAsArray();

  16.   bSurf = new GLModel(me, numV, TRIANGLES, GLModel.STREAM);
  17.   bSurf.beginUpdateVertices();
  18.   for (int i = 0; i < numV; i++) bSurf.updateVertex(i, verts[4 * i], verts[4 * i + 1], verts[4 * i + 2]);
  19.   bSurf.endUpdateVertices(); 

  20.   bSurf.initNormals();
  21.   bSurf.beginUpdateNormals();
  22.   for (int i = 0; i < numV; i++) bSurf.updateNormal(i, norms[4 * i], norms[4 * i + 1], norms[4 * i + 2]);
  23.   bSurf.endUpdateNormals();  

  24.   bSurf.initColors();
  25.   bSurf.beginUpdateColors();

  26.   for (int fNum=0; fNum<currentMesh.faces.size(); fNum++) {
  27.     int currentColor = fNum - 16777215;
  28.     int vNum = fNum*3;
  29.     //    println("writing face # " + fNum + " vertice # " + vNum + " " + (vNum+1) + " " + (vNum+2) + " color # = " + currentColor);
  30.     if (vNum < bSurf.getSize()) {
  31.       bSurf.updateColor(vNum, currentColor, 255); 
  32.       bSurf.updateColor(vNum+1, currentColor, 255); 
  33.       bSurf.updateColor(vNum+2, currentColor, 255);
  34.     }
  35.     else
  36.       println("out of bounds with color vertices!");
  37.   }

  38.   bSurf.endUpdateColors(); 

  39.   println("Finished loading GLMODEL BUFFER");

  40.   // CONVERT TO GL MODEL END
  41. }

  42. public void  updateGLPickerBuffer() {
  43.   // GL START
  44.   pickerB.beginDraw();
  45.   pickerB.beginGL();
  46.   pickerB.background(0);
  47.   pickerB.model(bSurf);
  48.   pickerB.endGL();
  49.   pickerB.endDraw();

  50.   // UPDATE Picker Texture TODO: THIS IS SLOWEST PART...
  51.   tex = pickerB.getTexture();
  52.   tex.updateTexture();
  53.   //tex.save("smooth.tif");
  54.   //tex.getImage(pickerI);
  55. }

  56. public int getId(int x, int y) {
  57.   int arrayMax = int(width*PickerRez)*int(height*PickerRez);
  58.   int pixelNumber = min(arrayMax, int(y*PickerRez*tex.width+x*PickerRez));
  59.   // COLOR -16777216 (black) to -1 => ID -1 (no object) to 16777214 
  60.   int id = tex.pixels[pixelNumber] + 16777215; // 16777215
  61.   //int id = 10;
  62.   return id;
  63. }






Hi, I just tested the object picking code from the wiki using 2.0a6, and it works. Are you using an older alpha release?
Hi Andres,

I'm not sure exactly what release I was using, but I was having trouble with the Picker library, not the wiki. My sketch needs max performance from the picker to work, so I implemented the GL Graphics version.  I don't totally grasp how I will port all of these awesome GL Graphics library things to 2.0, so I'm holding off for now.

Now if only there was a way to grab one pixel from the GPU texture without having to use "loadtexture" command.  I guess that's just inherent to the process.

Copy code
  1.   tex = pickerB.getTexture();
  2.   tex.updateTexture();




If you are using a PGraphics object created with a P2D or P3D renderer in Processing 2.0, then you should be able to retrieve the pixels array just by calling pg.loadPixels().
My issues is that loadPixels takes some time as does updateTexture.  I'm going to see whether I can multithread some of these calls and avoid the lag in my main script. The stuff I'm doing requires me to do a loadPixels every frame to access it with the picker.  While it's definitely faster to run this with a glgraphics offscreen buffer the lag comes when I offload this buffer from my GPU to run a picker function on the array of pixels.  I've reduced the size of the buffer, but his creates other issues.

I'm not sure if there is a way to avoid this offloading and just access it pixel by pixel directly (to check the color) directly on the GPU? I suppose that is the same problem... 
If you only need to check the color value at a specific pixel location, you could do:
Copy code
  1. import java.nio.*;

  2. void setup() {
  3.   size(100, 100, P2D);
  4.   noSmooth();
  5. }

  6. void draw() {
  7.   background(0);
  8.   stroke(255, 0, 0);
  9.   strokeWeight(10);
  10.   strokeCap(RECT);
  11.   point(50, 50);

  12.   PGraphicsOpenGL pg = (PGraphicsOpenGL)g;

  13.   PGL pgl = pg.beginPGL();
  14.   int[] pixel = new int[1];
  15.   IntBuffer pixelBuffer = IntBuffer.wrap(pixel);  
  16.   pgl.glReadPixels(mouseX, mouseY - 1, 1, 1, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer);
  17.   int col = PGL.nativeToJavaARGB(pixel[0]);
  18.   println(red(col) + " " + green(col) + " " + blue(col));
  19.   pg.endPGL();
  20. }
Copying all the pixels in the screen with a separate glReadPixels() call for each is going to be much slower than using loadPixels(), but if you need to check the color of only a few pixels per frame, then this should be faster.
Hi Andres,

I tried to create a color picking function for 2D sprites (PNGs converted into white masks and then tinted with the color ID) using 2.0a8 and strange things come up:

1) if I use P3D or P2D and call loadPixels() or get() the sketch slow down terribly

2) If I implement offscreen surface using JAVA2D I get wrong color results

My friend Erika opened 2 issues about those bugs:

Issue with tint and JAVA2D
Issue with loadPixels

In the mean while I tried your sketch in this thread but something is missing:

Copy code
  1.       PGL pgl = pg.beginPGL();
This method doesn't exist anymore.

Do you think is better to wait for 2.0 or do you have other suggestions about this problem?

Thank you in advance,
Massimo
Hello Massimo,

Thanks for reporting the issues, I will look into them soon.

As for the  beginPGL() function, it got renamed back to beginGL() in the latest alpha releases. However, the PGL class is still undergoing changes, and it is very likely that it will become beginPGL() again (and definitely) for the beta.
Thank you andres for your constant work on Processing!

Also your suggestion seems to solve my color picking problem!
I was wrong: your suggestion works fine if you draw on main PGraphics (g) but I tried to implement an offscreen buffer and, instead of reading the offscreen pixel, it get it from displayed pixels :-(

Copy code
  1. import java.nio.*;
  2. PGraphics offscreen;
  3. void setup() {
  4.   size(100, 100, P2D);
  5.   offscreen = createGraphics(100, 100, P2D);
  6.   offscreen.noSmooth();
  7.   //offscreen.hint(ENABLE_ACCURATE_2D); //is it better to include this?
  8. }
  9. void draw() {
  10.  
  11.   offscreen.beginDraw();
  12.   offscreen.background(0);
  13.   offscreen.stroke(255, 0, 0);
  14.   offscreen.strokeWeight(10);
  15.   offscreen.strokeCap(RECT);
  16.   offscreen.point(50, 50);
  17.   offscreen.endDraw();
  18.   PGraphicsOpenGL pg = (PGraphicsOpenGL) offscreen;
  19.   PGL pgl = pg.beginGL();
  20.   int[] pixel = new int[1];
  21.   IntBuffer pixelBuffer = IntBuffer.wrap(pixel); 
  22.   pgl.glReadPixels(mouseX, mouseY - 1, 1, 1, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer);
  23.   int col = PGL.nativeToJavaARGB(pixel[0]);
  24.   println(red(col) + " " + green(col) + " " + blue(col));
  25.   pg.endGL();
  26. }
This offscreen version of your sketch should work but it does not. Am I missing something?

I'm not so confident with GL related stuff and I hadn't the time to study your latest committed code deeply but after a small travel inside opengl PGraphics implementation I found something that confused me a bit:

Copy code
  1.     if (primarySurface) {
  2.       pgl.updatePrimary();
  3.       if (pgl.primaryIsDoubleBuffered()) {
  4.         pgl.drawBuffer(PGL.BACK);
  5.       }
  6.     } else {
  7.       if (!pgl.initialized) {
  8.         initOffscreen();
  9.       } else {
  10.         boolean outdated = offscreenFramebuffer != null && offscreenFramebuffer.contextIsOutdated();
  11.         boolean outdatedMulti = offscreenFramebufferMultisample != null && offscreenFramebufferMultisample.contextIsOutdated();
  12.         if (outdated || outdatedMulti) {
  13.           pgl.initialized = false;
  14.           initOffscreen();
  15.         }
  16.       }
  17.       pushFramebuffer();
  18.       if (offscreenMultisample) {
  19.         setFramebuffer(offscreenFramebufferMultisample);
  20.       } else {
  21.         setFramebuffer(offscreenFramebuffer);
  22.       }
  23.       pgl.updateOffscreen(pgPrimary.pgl);
  24.       pgl.drawBuffer(PGL.COLOR_ATTACHMENT0);
  25.     }
  26.     // We are ready to go!
This snippet is from beginDraw method inside PGraphicsOpenGL.java... my question is should I declare somehow that the offscreen PGraphics object is the FrameBuffer?

Thank you in advance,
Massimo

Hello, even if you only want to do low-level operations on the offscreen surface, you still need to enclose them between beginDraw/endDraw:
Copy code
  1.   PGraphicsOpenGL pg = (PGraphicsOpenGL) offscreen;
  2.   offscreen.beginDraw();
  3.   PGL pgl = pg.beginGL();
  4.   int[] pixel = new int[1];
  5.   IntBuffer pixelBuffer = IntBuffer.wrap(pixel);  
  6.   pgl.glReadPixels(mouseX, mouseY - 1, 1, 1, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer);
  7.   int col = PGL.nativeToJavaARGB(pixel[0]);
  8.   println(red(col) + " " + green(col) + " " + blue(col));
  9.   pg.endGL();
  10.   offscreen.endDraw();
Hi Andres,

I'm trying to recreate this snippet with new Processing 2.0b7 version but with no luck.

If I use main buffer it works as color picking method but if I use it with offscreen it will return always 0
Copy code
  1. import java.nio.*;

  2. PGraphics offscreenb;
  3. int currentColor = 0;


  4. void setup() {
  5.   size(640, 480, P3D);
  6.   offscreenb = createGraphics(width, height, P3D);
  7. }

  8. void draw() {
  9.   
  10.   //draw a green box in the center
  11.   translate(width / 2, height / 2);
  12.   fill(0, 128, 0);
  13.   stroke(0, 200, 0);
  14.   box(80);
  15.   
  16.   drawOffscreen();
  17.   currentColor = getPixel();
  18. }

  19. void mousePressed() {
  20.   println(red(currentColor) + "," + green(currentColor) + "," + blue(currentColor) + ",");
  21. }

  22. void drawOffscreen() {
  23.  
  24.   //draw a red box in the center of offscreen
  25.   offscreenb.beginDraw();
  26.   offscreenb.translate(width / 2, height / 2);
  27.   offscreenb.fill(255, 0, 0);
  28.   offscreenb.noStroke();
  29.   offscreenb.box(80);
  30.   offscreenb.endDraw(); 
  31. }

  32. int getPixel() {
  33.   PGraphicsOpenGL pg = (PGraphicsOpenGL) offscreenb; //change this with g and it works... :-(
  34.   
  35.   offscreenb.beginDraw();
  36.   PGL pgl = pg.beginPGL();
  37.   IntBuffer pixelBuffer = IntBuffer.allocate(1);
  38.   pgl.readPixels(mouseX, mouseY -1, 1, 1, PGL.RGBA, PGL.UNSIGNED_BYTE, pixelBuffer);
  39.   pg.endPGL();
  40.   offscreenb.endDraw();
  41.   return pixelBuffer.get();
  42. }



How are you folks getting color of pixels when using offscreen buffer and opengl?

Why  getColorValue() is protected? :-(

Thank you in advance,
Massimo
Hello

I've modified the library picking (Nicolas Clavaud) to work with processing version 2.0.b7.

You can also define class Buffer and Picker, directly on your processing editor

Buffer Class


Copy code
  1. public class Buffer extends PGraphics3D
  2. {
  3.   protected int current_color = 0;
  4.     
  5.   public Buffer(PApplet parent)
  6.   {
  7.     setParent(parent);
  8.     setSize(parent.width, parent.height);    
  9.   }

  10.   @Override
  11.   public boolean displayable() { return true; }
  12.   
  13.   public void callCheckSettings() { super.checkSettings(); }
  14.   
  15.   @Override
  16.   public void lights() {}
  17.   
  18.   @Override
  19.   public void smooth() {}
  20.   
  21.   @Override
  22.   public void fill(int arg) {}
  23.   
  24.   @Override
  25.   public void fill(float arg) {}
  26.   
  27.   @Override
  28.   public void fill(float arg, float arg_1) {}
  29.   
  30.   @Override
  31.   public void fill(int arg, float arg_1) {}
  32.   
  33.   @Override
  34.   public void fill(float arg, float arg_1, float arg_2) {}
  35.   
  36.   @Override
  37.   public void fill(float arg, float arg_1, float arg_2, float arg_3) {}
  38.   
  39.   @Override
  40.   public void stroke(int arg) {}
  41.   
  42.   @Override
  43.   public void stroke(float arg) {}
  44.   
  45.   @Override
  46.   public void stroke(float arg, float arg_1) {}
  47.   
  48.   @Override
  49.   public void stroke(int arg, float arg_1) {}
  50.   
  51.   @Override
  52.   public void stroke(float arg, float arg_1, float arg_2) {}
  53.   
  54.   @Override
  55.   public void stroke(float arg, float arg_1, float arg_2, float arg_3) {}
  56.   
  57.   @Override
  58.   public void textureMode(int arg) {}
  59.   
  60.   @Override
  61.   public void texture(PImage arg) {}
  62.   
  63.   @Override
  64.   public void vertex(float x, float y, float z, float u, float v) { super.vertex(x, y, z); }
  65.   
  66.   @Override
  67.   public void image(PImage arg, float arg_1, float arg_2) {}
  68.   
  69.   @Override
  70.   public void image(PImage arg, float arg_1, float arg_2, float arg_3, float arg_4) {}
  71.   
  72.   @Override
  73.   public void image(PImage arg, float arg_1, float arg_2, float arg_3, float arg_4, int arg_5, int arg_6, int arg_7, int arg_8) {}
  74.   
  75.   @Override
  76.   protected void imageImpl(PImage image, float x1, float y1, float x2, float y2, int u1, int v1, int u2, int v2) {}
  77.   
  78.   public void setCurrentId(int i) 
  79.   {
  80.       // ID 0 to 16777214  => COLOR -16777215 to -1 (white)
  81.       // -16777216 is black
  82.       current_color = i - 16777215;
  83.       super.fill(current_color);      
  84.   }
  85.   
  86.   public int getId(int x, int y)
  87.   {
  88.       super.loadPixels();
  89.       // COLOR -16777216 (black) to -1 => ID -1 (no object) to 16777214 
  90.       int id = pixels[y*width+x] + 16777215;
  91.       return id;
  92.   }
  93. }

Picker Class

Copy code
  1. public class Picker 
  2. {
  3.   protected PApplet parent;
  4.   public Buffer buffer;
  5.   
  6.   public Picker(PApplet parent) 
  7.   {
  8.     this.parent = parent;
  9.     buffer = new Buffer(parent);     
  10.     //parent.registerMethod("pre",this);
  11.     //parent.registerMethod("draw",this);
  12.   }      
  13.   
  14.   public void begin() 
  15.   {
  16.     if(parent.recorder == null)
  17.     {
  18.       parent.recorder = buffer; 
  19.       buffer.beginDraw();           
  20.     }
  21.   }
  22.   
  23.   public void end() 
  24.   {
  25.     buffer.endDraw();  
  26.     parent.recorder = null;
  27.   }

  28.   public void start(int i)
  29.   {
  30.     if (i < 0 || i > 16777214)
  31.     {
  32.       PApplet.println("[Picking error] start(): ID out of range");
  33.       return;
  34.     }
  35.     buffer.setCurrentId(i);            
  36.   }
  37.   
  38.   public void stop() 
  39.         {
  40.     parent.recorder = null;
  41.   }
  42.   
  43.   public void resume() 
  44.         {
  45.     parent.recorder = buffer;
  46.   }
  47.   
  48.   public int get(int x, int y)
  49.   {
  50.     return buffer.getId(x, y);
  51.   }
  52.   
  53.   public PGraphics getBuffer()
  54.   {
  55.     return buffer;
  56.   }    
  57. }

Example


Copy code
  1. Picker picker;
  2. float a = 0.0;

  3. void setup() 
  4. {  
  5.   size(200,200, P3D);  
  6.   picker = new Picker(this);
  7. }

  8. void draw() 
  9. {    
  10.   background(0,128,0);
  11.   a += 0.01;

  12.   picker.begin();
  13.   
  14.   picker.start(0);
  15.   pushMatrix();
  16.   translate(80, 75);
  17.   rotateX(a);
  18.   rotateY(a);
  19.   fill(200,40,60);
  20.   box(50);
  21.   popMatrix();
  22.   
  23.   picker.start(1);
  24.   pushMatrix();
  25.   translate(140, 75);
  26.   rotateX(a);
  27.   rotateY(a);
  28.   fill(60,40,200);
  29.   box(20);
  30.   popMatrix();
  31.   
  32.   picker.end();
  33.   
  34. }

  35. void mousePressed()
  36. {
  37.   println(picker.get(mouseX, mouseY));
  38. }

I hope that helps somewhat
Important Note: 

I don't know exactly why, but for some reason background can't be correctly overloaded, so is very important to call picker.begin() after the background() instruction
Hi all

I`ve found a important error in my solution.
the background is not managed properly in the recorder object

I'll try to find a solution
Sorry