Object/Polygon/Face selection aka picking

Tutorials concerning the OpenGL® ES cross-platform API for full-function 2D and 3D graphics on the Google-Android platform.

Object/Polygon/Face selection aka picking

Postby mb_zi » Sat Feb 27, 2010 2:51 am

Hi,

Short intro -> Im a CS student, knowledge of basic OpenGL and java... and in need of some lovely help...im a novice with android so sorry if im making stupid mistakes..

im currently making a free game for one of my projects. For test purposes im outputting aload of 3d triangles. i need to select certain objects and move them in a certain direction. After researching i found it can be quite tricky on android devices to implement a picking technique which selects objects based on where you touch the screen and read the framebuffer.

All i need to know is to know which object(square/triangle etc) im touching. To do this i render all the objects, when a touch event occurs it clears all past rendering and re renders the scene with each objects own special 'picking' method which draws the objects with a unique colour. i use glReadPixels() to find out where im touching and it reads the colour been displayed at that point. To make sure im not reading incorrect colours i have disabled all effects such as textures/fog etc.

The problem im encountering is that glReadPixels always reads 0 0 0 0 which is black???... even when selecting something rendered... im not entirely sure on how to fix this problem and would like some help if possible or perhaps a hint in the right direction thanks :)

The following code examples are a cut down version of what im currently using and some DDM output:


Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         public boolean onTouchEvent(MotionEvent event)
  2.  
  3.         {
  4.  
  5.                 float x = event.getX();
  6.  
  7.                 float y = event.getY();
  8.  
  9.  
  10.  
  11.                 if(event.getAction() == MotionEvent.ACTION_MOVE)
  12.  
  13.                 {
  14.  
  15.                         float dx = x - oldX;
  16.  
  17.                         float dy = y - oldY;
  18.  
  19.  
  20.  
  21.                         //Define camera change areas (8% up down left right)
  22.  
  23.                         //Leaves a middle area which can be used to select components
  24.  
  25.                         int upperArea = this.getHeight() / 8;
  26.  
  27.                         int lowerArea = this.getHeight() - upperArea;
  28.  
  29.                         int leftArea = this.getWidth() / 8;
  30.  
  31.                         int rightArea = this.getWidth() - leftArea;
  32.  
  33.  
  34.  
  35.                         /***************************/
  36.  
  37.                         /** CAMERA CHANGING AREA **/
  38.  
  39.                         /***************************/
  40.  
  41.                         if(x < leftArea || x > rightArea)
  42.  
  43.                         {              
  44.  
  45.                                 xrot += dy * TOUCH_SCALE;//changes camera view up or down
  46.  
  47.                         }    
  48.  
  49.                         if(y > lowerArea || y < upperArea)
  50.  
  51.                         {
  52.  
  53.                                 yrot += dx * TOUCH_SCALE;//changes camera view left or right
  54.  
  55.                         }
  56.  
  57.                         /**
  58.  
  59.                          * Where the magic is meant to happen, touch screen, read colour, check
  60.  
  61.                          */
  62.  
  63.                                 CurrentGL.glClearColor(0.0f,0.0f,0.0f,0.0f);
  64.  
  65.                                 CurrentGL.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
  66.  
  67.                                 CurrentGL.glLoadIdentity();
  68.  
  69.                                
  70.  
  71.                                 //This and lighting disabled to only allow rendering of solid colours
  72.  
  73.                                 CurrentGL.glDisable(GL10.GL_DITHER);                   
  74.  
  75.                                 CurrentGL.glDisable(GL10.GL_LIGHTING);                         
  76.  
  77.                                 CurrentGL.glDisable(GL10.GL_TEXTURE_2D);               
  78.  
  79.                                 CurrentGL.glDisable(GL10.GL_FOG);
  80.  
  81.                                 CurrentGL.glEnable(GL10.GL_COLOR_MATERIAL);
  82.  
  83.                                 CurrentGL.glShadeModel(GL10.GL_FLAT);
  84.  
  85.  
  86.  
  87.                                 try
  88.  
  89.                                 {
  90.  
  91.                                         for(int i = 0; i < TriangleObjects.size();i++)
  92.  
  93.                                         {
  94.  
  95.                                                 TriangleObjects.get(i).picking(CurrentGL);//renders the triangles with their unique colours
  96.  
  97.                                         }
  98.  
  99.                                 }
  100.  
  101.                                 catch(Exception e)
  102.  
  103.                                 {
  104.  
  105.                                         System.out.println("End of list or no Triangle objects in list");
  106.  
  107.                                 }
  108.  
  109.                                 ByteBuffer PixelBuffer = ByteBuffer.allocateDirect(4);
  110.  
  111.                                 PixelBuffer.order(ByteOrder.nativeOrder());
  112.  
  113.                                
  114.  
  115.                                 CurrentGL.glReadPixels((int)x, (int) y, 1, 1, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, PixelBuffer);
  116.  
  117.                                 System.out.println(PixelBuffer.get(0) + " "+ PixelBuffer.get(1)+ " " + PixelBuffer.get(2) + " " + PixelBuffer.get(3));//prints out the RGBA values for testing so far only 0 0 0 0     
  118.  
  119.                         }
  120.  
  121.                 }
  122.  
  123.                 oldX = x;
  124.  
  125.                 oldY = y;
  126.  
  127.                 return true;
  128.  
  129.         }
Parsed in 0.038 seconds, using GeSHi 1.0.8.4
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         public void onDrawFrame(GL10 gl)
  2.  
  3.         {
  4.  
  5.                 CurrentGL = gl;//updates global im not sure if you're meant to do this...but allows rendering in touch method
  6.  
  7.        
  8.  
  9.                 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);       
  10.  
  11.                 gl.glLoadIdentity();           
  12.  
  13.                 gl.glShadeModel(GL10.GL_SMOOTH);               
  14.  
  15.                 gl.glTranslatef(0.0f, 0.0f, z);
  16.  
  17.                
  18.  
  19.                 gl.glPushMatrix();
  20.  
  21.                         gl.glTranslatef(0.0f, 0.0f, 0.0f);     
  22.  
  23.                         gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);
  24.  
  25.                         gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);
  26.  
  27.        
  28.  
  29.                         try
  30.  
  31.                         {
  32.  
  33.                                 for(int i = 0; i < TriangleObjects.size();i++)
  34.  
  35.                                 {
  36.  
  37.                                         TriangleObjects.get(i).draw(gl);
  38.  
  39.                                 }
  40.  
  41.                         }
  42.  
  43.                         catch(Exception e)
  44.  
  45.                         {
  46.  
  47.                                 System.out.println("End of list or no Triangle objects in list");
  48.  
  49.                         }
  50.  
  51.                 gl.glPopMatrix();
  52.  
  53.         }      
Parsed in 0.034 seconds, using GeSHi 1.0.8.4


Inside the Triangle object class:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         public void picking(GL10 gl)
  2.  
  3.         {
  4.  
  5.                 gl.glFrontFace(GL10.GL_CW);
  6.  
  7.                 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
  8.  
  9.                 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  10.  
  11.                 gl.glColor4f(uniqueColour[0], uniqueColour[1], uniqueColour[2], uniqueColour[3]);//unique colouring
  12.  
  13.                 gl.glDrawArrays(GL10.GL_TRIANGLES, 0, vertices.length / 3);
  14.  
  15.                 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
  16.  
  17.         }
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. 02-27 01:41:48.959: INFO/System.out(1215): 0 0 0 0
  2.  
  3. 02-27 01:41:48.989: INFO/System.out(1215): 0 0 0 0
  4.  
  5. 02-27 01:41:49.029: INFO/System.out(1215): 0 0 0 0
  6.  
  7. 02-27 01:41:49.059: INFO/System.out(1215): 0 0 0 0
  8.  
  9. 02-27 01:41:49.099: INFO/System.out(1215): 0 0 0 0
  10.  
  11. 02-27 01:41:49.119: INFO/System.out(1215): 0 0 0 0
  12.  
  13.  
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


any help would be greatly appreciated! sorry of the code looks choppy..
Last edited by mb_zi on Sat Feb 27, 2010 5:50 pm, edited 3 times in total.
mb_zi
Junior Developer
Junior Developer
 
Posts: 17
Joined: Sat Feb 27, 2010 2:16 am

Top

Postby mb_zi » Sat Feb 27, 2010 5:40 pm

After looking for a solution this morning i believe glReadPixels is working... what lies the problem is that i need permission to access the framebuffer to gain the information?? the way to do this changed when android went from 1.0 to 1.5.. i believe... hence until i do this ill get 0 0 0 0 results? im still searching for a solution and hopefully ill get one soon. as soon as i get this working ill probably write a tutorial as this is driving me crazy so no idea what its doing to other novices...


so far ive added the following permissions to the manifiest files:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.                 <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
  3.  
  4.                 <uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


and this managed to help me so far point in the right direction:

http://osdir.com/ml/android-ndk/2009-12/msg00171.html
mb_zi
Junior Developer
Junior Developer
 
Posts: 17
Joined: Sat Feb 27, 2010 2:16 am

Postby agr_ank » Thu Mar 25, 2010 9:09 am

The post was very useful...


I am getting 0,0,0,0 when using glReadPixels. I think its the permission issue.

When I try to get the permissions it fails telling that the protection level for this is 2.

As I understand these permissions are not for the 3rd Party developers. I am trying it only for learning purposes and not releasing this.

Any workaround will be useful. If possible plz tell me in detailed steps.

Thanks.
agr_ank
Once Poster
Once Poster
 
Posts: 1
Joined: Thu Mar 25, 2010 9:04 am

Postby mb_zi » Tue Mar 30, 2010 3:27 am

Hi,

Sorry to see your having the same problem... eventually I gave up and implemented boarders around displayed objects. It’s a very tedious and no way near as accurate but works for what I wanted to achieve. For a simple puzzle game it works ok as I always know what position my camera and not too bad. However for a more complex 3d game or app I wouldn’t recommend this approach.

For another solution you can try ray tracing. Based on the camera position and where the user touches you can create a "ray" to x distance. You then can increase this ray x amount and if it touches an object within x-max then you have a collision (aka every time you increase the ray check for any collisions). If so win otherwise ignore.

p.s. very late im tired few errors above aha
mb_zi
Junior Developer
Junior Developer
 
Posts: 17
Joined: Sat Feb 27, 2010 2:16 am

Re: Object/Polygon/Face selection aka picking

Postby atla » Tue May 18, 2010 10:12 pm

Hi folks,

i am currently struggling with the same problems. I need a way of picking objects on my screen and looked into glReadPixel with coloring.. no success until now.

I will definetly let you know if and how it worked for me. But until then i appreciate any help from someone else that got it working already!

Greets,

atla
atla
Freshman
Freshman
 
Posts: 7
Joined: Fri Feb 26, 2010 3:01 pm
Location: Nußloch

Re: Object/Polygon/Face selection aka picking

Postby atla » Tue May 18, 2010 11:04 pm

I nailed it down more or less, i get different colors from my 3x3 quads with different red tones... but due to the conversion to Float and back to int i don't get the correct values.

My Example:

to test i took bigger distances between the colorcodes for my first try.

bla.pickId = i * 20 (e.g. 60 for third tile)

i render using this:

gl.glColor4f(pickId/255.0f, 0.0f, 0.0f, 1.0f);

this.renderer.draw(gl);

i guess i already loose precision on that conversion as the OpenGL ES GL0 implementation does not offer the glColor4ub function i would use on standard GL... therefore i need to use the color4f function here.

when i read my Pixels i read it like the example above looking for bytes

byte[] c = new byte[4];
ByteBuffer pixels = ByteBuffer.wrap(c);

gl.glReadPixels(pickX, height-pickY, 1, 1, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixels);

int r = c[0];
int g = c[1];
int b = c[2];
//int a = c[3];

if (r < 0)
r += 256;
if (g < 0)
g += 256;
if (b < 0)
b += 256;

Log.v("TEST", "bla r " + r + " g " + g + " b " + b );

My problem is i do not get the correct values as put in pickId but get values like 99, 123, 82 instead of 100, 120, 80 ...
i could work around this and just round up to the nearest power of 20 but i would rather like to be able to pick way more objects

maybe someone has an idea for that?
atla
Freshman
Freshman
 
Posts: 7
Joined: Fri Feb 26, 2010 3:01 pm
Location: Nußloch

Top

Re: Object/Polygon/Face selection aka picking

Postby Vince » Fri Oct 08, 2010 11:30 am

Atla, have you found a solution to that problem?

By the way, to (possibly) avoid rounding errors I'm using glColor4x like this:
glColor4x(red*257, green*257, blue*257, alpha*257);
Where red/green/blue/alpha = [0..255]
Vince
Freshman
Freshman
 
Posts: 4
Joined: Tue Apr 27, 2010 3:59 pm

Re: Object/Polygon/Face selection aka picking

Postby Harry » Fri Mar 25, 2011 3:46 pm

Hi,
i am using the color picking method in my app and picking works fine!

I have no rounding errors with:

drawing:
Code: Select all
int redDraw = value; // < 256
gl.glColor4f(redDraw, 0, 0, 1);


searching object after picking:
Code: Select all
// i get a byteBuffer with RGBA
ByteBuffer buffer = ...
int red = buffer.get(0);
if(red < 0)
{
   red += 256;
}


BUT i have the problem, that all my coloured objects are coloured on the screen.
I think the back buffer is not cleared before redrawing all objects with textures.

What is the right way to clear the back buffer in OpenGL ES 1.0?

Hier is my Code:

In onTouchEvent-method (getting the index of the right object)
Code: Select all
      int iIndex = -1;
      int iRed;
      
      m_PickingPixelBuffer = ByteBuffer.allocateDirect(4);
      m_PickingPixelBuffer.order(ByteOrder.nativeOrder());

      // setting globals for Renderer
      m_bPickingEnabled = true;
      m_iPickingX = _iX;
      m_iPickingY = _iY;
      requestRender();

      // wait for picking process (renderer)
      while(m_bPickingEnabled);

      iRed = m_PickingPixelBuffer.get(0);
      if(iRed < 0)
      {
         iRed += 256;
      }
      
      for (int i = 0; i < numOfObjects; i++)
      {
         if (m_Modell.getCover(i).getColorRed() == iRed)
         {
            iIndex = i;
            break;
         }
      }


Drawing
Code: Select all
public void onDrawFrame(GL10 gl)
   {
      // clear Buffer
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

      if (isPickingEnabled())
      {
         // draw colored objects  and picking pixel color
         pickingDraw(gl);

         // Clear BACK BUFFER
         gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
      }
      // draw objects with textures
      draw(gl);
   }
Harry
Freshman
Freshman
 
Posts: 4
Joined: Fri Mar 25, 2011 3:15 pm

Re: Object/Polygon/Face selection aka picking

Postby Harry » Fri Mar 25, 2011 4:58 pm

The solution is:

gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);

Textures replace color settings with GL10.GL_REPLACE.
Default is GL_MODULATE.
Harry
Freshman
Freshman
 
Posts: 4
Joined: Fri Mar 25, 2011 3:15 pm

Re: Object/Polygon/Face selection aka picking

Postby pedriyoo » Wed Sep 21, 2011 9:58 am

Hi!

I'm also doing the color picking method but I get the same color for the three objects I draw. My program so far is very simple, it draws 2 squares and one triangle and draws each one with a different red-index when the user is touching the screen.

The thing is that I'm getting the same red-index for the three objects, and plus, the objects are drawn coloured (so the buffer doesn't get cleared...).

I have tried to do the things others explain above but I don't understand how to use
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);

Here is my code:

The onDrawFrame method (within my Renderer). Here is where I render the polygons with an unique color when the user is touching the screen.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public void onDrawFrame(GL10 gl) {
  2.  
  3.     // clear Screen and Depth Buffer
  4.     gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
  5.  
  6.     // Reset the Modelview Matrix
  7.     gl.glLoadIdentity();
  8.  
  9.     if (mGLView.isPickingEnabled()) {
  10.          gl.glDisable(GL10.GL_TEXTURE_2D);
  11.          gl.glDisable(GL10.GL_LIGHTING);
  12.          gl.glDisable(GL10.GL_FOG);
  13.  
  14.          // draw colored objects  and picking pixel color
  15.          pickingDraw(gl);
  16.  
  17.          // Translate screen coordinate Y to openGL-screen coordinates
  18.          mGLView.mPickingY = (int)(mHeight - mGLView.mPickingY);
  19.  
  20.          gl.glReadPixels((int) mGLView.mPickingX,
  21.                  (int) mGLView.mPickingY, 1, 1,
  22.                  GL10.GL_RGBA,
  23.                  GL10.GL_UNSIGNED_BYTE,
  24.                  mGLView.m_PickingPixelBuffer);
  25.  
  26.          Log.i("RA", "RGBA COLORS: " +
  27.                  (int) mGLView.m_PickingPixelBuffer.get(0) + " , " +
  28.                  (int) mGLView.m_PickingPixelBuffer.get(1) + " , " +
  29.                  (int) mGLView.m_PickingPixelBuffer.get(2) + " , " +
  30.                  (int) mGLView.m_PickingPixelBuffer.get(3) );
  31.  
  32.          mGLView.disablePicking();
  33.  
  34.          // Clear BACK BUFFER
  35.          gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
  36.     }
  37.  
  38.     gl.glLoadIdentity();
  39.  
  40.     // Drawing
  41.     gl.glTranslatef(0.0f, 0.0f, -25.0f);    // move 5 units INTO the screen
  42.     square.draw(gl);
  43.  
  44.     gl.glTranslatef(0.0f, -5.0f, 0.0f);
  45.     square.draw(gl);
  46.  
  47.     gl.glTranslatef(4.0f, 10.0f, 0.0f);
  48.     triangle.draw(gl);
  49. }
Parsed in 0.042 seconds, using GeSHi 1.0.8.4


The pickingDraw method is the following (within my Renderer too):

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. private void pickingDraw(GL10 gl) {
  2.     // Drawing
  3.     gl.glTranslatef(0.0f, 0.0f, -25.0f);    // move 5 units INTO the screen
  4.     gl.glColor4f(128, 0, 0, 1);
  5.     square.draw(gl);                        // Draw each polygon with a different color
  6.  
  7.     gl.glTranslatef(0.0f, -5.0f, 0.0f);
  8.     gl.glColor4f(129, 0, 0, 1);
  9.     square.draw(gl);
  10.  
  11.     gl.glTranslatef(4.0f, 10.0f, 0.0f);
  12.     gl.glColor4f(130, 0, 0, 1);
  13.     triangle.draw(gl);
  14. }
Parsed in 0.038 seconds, using GeSHi 1.0.8.4


On the other hand, I inherited GLSurfaceView so I can handle user touches. Within this class, I use this method:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public boolean onTouchEvent(MotionEvent e) {
  2.  
  3.     float _iX = e.getX();
  4.     float _iY = e.getY();
  5.  
  6.     int iRed;
  7.  
  8.     m_PickingPixelBuffer = ByteBuffer.allocateDirect(4);
  9.     m_PickingPixelBuffer.order(ByteOrder.nativeOrder());
  10.  
  11.     // setting globals for Renderer
  12.     mPickingX = _iX;
  13.     mPickingY = _iY;
  14.  
  15.     mPickingEnabled = true;
  16.     requestRender();
  17.  
  18.     // wait for picking process (renderer)
  19.     while(mPickingEnabled);
  20.  
  21.     iRed = m_PickingPixelBuffer.get(0);
  22.     if(iRed < 0)
  23.     {
  24.        iRed += 256;
  25.     }
  26.  
  27.     Log.i("RA", "Coordinates: (" + mPickingX + ", " + mPickingY + ")");
  28.     Log.i("RA", "Red Color " + iRed);
  29.  
  30.     return true;
  31. }
Parsed in 0.039 seconds, using GeSHi 1.0.8.4


It seems that it detects the polygons when I touch them, but I get the same color index for the three of them. Plus, the three objects have the same exact color (I even drew each one with a value of red, green and blue respectively, but they ended up being drawn with the color of the last one that was drawn. For example, if the triangle is the last being drawn, and its color is blue, the three objects get drawn in blue).

Finally, this is the output I get when I touch an square, then an empty space, and another square:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. 01-19 01:34:23.345: INFO/RA(11566): RGBA COLORS: -1 , 0 , 0 , -1
  2. 01-19 01:34:23.355: INFO/RA(11566): Coordinates: (247.81186, 391.0)
  3. 01-19 01:34:23.355: INFO/RA(11566): Red Color 255
  4. 01-19 01:34:23.385: INFO/RA(11566): RGBA COLORS: -1 , 0 , 0 , -1
  5. 01-19 01:34:23.385: INFO/RA(11566): Coordinates: (248.52428, 390.0)
  6. 01-19 01:34:23.385: INFO/RA(11566): Red Color 255
  7. 01-19 01:34:23.405: INFO/RA(11566): RGBA COLORS: -1 , 0 , 0 , -1
  8. 01-19 01:34:23.405: INFO/RA(11566): Coordinates: (248.52428, 390.0)
  9. 01-19 01:34:23.405: INFO/RA(11566): Red Color 255
  10. 01-19 01:34:24.305: INFO/RA(11566): RGBA COLORS: 0 , 0 , 0 , -1
  11. 01-19 01:34:24.315: INFO/RA(11566): Coordinates: (119.571884, 577.0)
  12. 01-19 01:34:24.315: INFO/RA(11566): Red Color 0
  13. 01-19 01:34:24.335: INFO/RA(11566): RGBA COLORS: 0 , 0 , 0 , -1
  14. 01-19 01:34:24.335: INFO/RA(11566): Coordinates: (119.33441, 573.0)
  15. 01-19 01:34:24.335: INFO/RA(11566): Red Color 0
  16. 01-19 01:34:24.355: INFO/RA(11566): RGBA COLORS: 0 , 0 , 0 , -1
  17. 01-19 01:34:24.355: INFO/RA(11566): Coordinates: (119.33441, 573.0)
  18. 01-19 01:34:24.355: INFO/RA(11566): Red Color 0
  19. 01-19 01:34:25.195: INFO/RA(11566): RGBA COLORS: -1 , 0 , 0 , -1
  20. 01-19 01:34:25.195: INFO/RA(11566): Coordinates: (259.80466, 395.0)
  21. 01-19 01:34:25.195: INFO/RA(11566): Red Color 255
  22. 01-19 01:34:25.215: INFO/RA(11566): RGBA COLORS: -1 , 0 , 0 , -1
  23. 01-19 01:34:25.215: INFO/RA(11566): Coordinates: (259.44843, 398.0)
  24. 01-19 01:34:25.215: INFO/RA(11566): Red Color 255
Parsed in 0.043 seconds, using GeSHi 1.0.8.4


I also have included the permissions mb_zi mentioned.

I don't know why the red values are the same for each object.

Any help would be appreciated.
Thanks.
pedriyoo
Freshman
Freshman
 
Posts: 2
Joined: Mon Jan 31, 2011 4:34 pm

Re: Object/Polygon/Face selection aka picking

Postby harrry » Fri Nov 11, 2011 9:50 am

Hi Pedriyoo,

Some points:
- color picking needs no permission
- Is not needed
// Translate screen coordinate Y to openGL-screen coordinates
mGLView.mPickingY = (int)(mHeight - mGLView.mPickingY);

- your pickingDraw must be the same as if you draw your object normaly, but
Code: Select all
gl.glDisable(GL10.GL_TEXTURE_2D);
gl.glDisable(GL10.GL_FOG);
gl.glDisable(GL10.GL_BLEND);
...
disabled.

This is only a solution, if you use textures:
Code: Select all
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);
Use it in
Code: Select all
onSurfaceCreated(GL10 gl, EGLConfig config)


Regards Harry
harrry
Freshman
Freshman
 
Posts: 4
Joined: Mon Jul 25, 2011 5:22 pm

Re: Object/Polygon/Face selection aka picking

Postby harrry » Fri Nov 11, 2011 10:34 am

Color picking in 4 steps:

- clear buffers
- draw objects in unique colors (pickingDraw(GL10 gl))
- clear buffers (removes all picking objects)
- draw objects normal (draw(GL10 gl))

!!! Do in pickingDraw() the same as in draw(), but disable blending, fog, textures... !!!

Code: Select all
public void onDrawFrame(GL10 gl)
{
   // clear Buffers
   gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
         
   if (m_Control.isPickingEnabled())
   {
      pickingDraw(gl);
               
      //clear Buffers
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
   }
            
       // draw normal
   draw(gl);
}


pickingDraw(GL10 gl):
Code: Select all
private void pickingDraw(GL10 gl)
{
   ...

   // disable options
   gl.glDisable(GL10.GL_TEXTURE_2D);
   gl.glDisable(GL10.GL_FOG);
   gl.glDisable(GL10.GL_BLEND);

   // draw objects in unique colors
   for (int i = 0; i <  m_alCoverPoints.size() && i < m_alCovers.size(); i++)
   {

      Cover cover = m_alCovers.get(i);
      gl.glPushMatrix();
                  
      // set color
      gl.glColor4f(cover.getColorRed() / 255f, 0, 0, 1);
      // set object points
      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, m_alCoverPoints.get(i));
      // draw elements
      gl.glDrawElements(GL10.GL_TRIANGLES, 2 * 3, GL10.GL_UNSIGNED_SHORT, m_sbIndices);
            
      gl.glPopMatrix();
   }
      
   // color picking
   gl.glReadPixels(m_Control.getPickingX(), m_Control.getPickingY(), 1, 1, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, m_Control.getPickingPixelBuffer());

   // tell other theads picking is ready
   m_Control.deactivatePicking();
      
   // enable options
   gl.glEnable(GL10.GL_TEXTURE_2D);
   gl.glEnable(GL10.GL_FOG);
   gl.glEnable(GL10.GL_BLEND);
}
harrry
Freshman
Freshman
 
Posts: 4
Joined: Mon Jul 25, 2011 5:22 pm

Top

Return to Android 2D/3D Graphics - OpenGL Tutorials

Who is online

Users browsing this forum: No registered users and 5 guests