Java-Gaming.org Java4K winners: [ by our judges | by the community ]         
Featured games (67)
games approved by the League of Dukes
Games in Showcase (∞)
games submitted by our members



News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  Print  
  Selection problems  (Read 744 times)
0 Members and 1 Guest are viewing this topic.
Offline SamiLakka

JGO n00b
*

Posts: 15


Java games rock!


« on: 2003-11-27 12:26:00 »

I populate my 3D-space with spheres that contain smaller spheres. When the spheres doesn't have anything inside of them, my selection routine works fine. But when my spheres contain smaller spheres I don't get any selections. I think that this has to do with glPushName and glPushMatrix but I don't know how.
See pseudocode for the drawing method below.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
for (int i = 0; i < counter; i++) {
// When I comment these lines inside loop everything works
 gl.glPushMatrix();    
     // draw smaller sphere
 gl.glPopMatrix();
}

glPushName(uniqueId)
gl.glPushMatrix()
  // Draw larger sphere
gl.glPopMatrix()
gl.glPopName();


Selection routines
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
private int[] setupSelection() {
      int objectsFound = 0;                              // This will hold the amount of objects clicked
           int viewportCoords[] = new int [4];            // We need an array to hold view port coordinates
           int selectBuffer[] = new int [32];
           
            gl.glSelectBuffer(32, selectBuffer);      // Setup selection buffer to accept object ID's
           gl.glGetIntegerv(GL.GL_VIEWPORT, viewportCoords); // Get the current view port coordinates
           gl.glMatrixMode(GL.GL_PROJECTION);            // We want to now effect projection matrix
           
            gl.glPushMatrix();                  // We push on a new matrix so we don't effect our 3D projection

            // This makes it so it doesn't change the frame buffer if we render into it, instead,
           // a record of the names of primitives that would have been drawn if the render mode was
           // GL_RENDER are now stored in the selection array (selectBuffer).

            gl.glRenderMode(GL.GL_SELECT);                        // Allows us to render the objects, but not change the frame buffer
           gl.glLoadIdentity();                                    // Reset our projection matrix

            // gluPickMatrix allows us to create a projection matrix that is around our
           // cursor.  This basically only allows rendering in the region that we specify.
           // If an object is rendered into that region, then it saves that objects ID for us            
           // The first 2 parameters are the X and Y position to start from, then the next 2
           // are the width and height of the region from the starting point.  The last parameter is
           // of course our view port coordinates.  You will notice we subtract "y" from the
           // BOTTOM view port coordinate.  We do this to flip the Y coordinates around.  The 0 y
           // coordinate starts from the bottom, which is opposite to window's coordinates.
           // We also give a 2 by 2 region to look for an object in. This can be changed to preference.

            glu.gluPickMatrix(selectedPoint.getX(), viewportCoords[3] - selectedPoint.getY(),
                  2, 2, viewportCoords);

            // Next, we just call our normal gluPerspective() function, exactly as we did on startup.
           // This is to multiply the perspective matrix by the pick matrix we created up above.

            glu.gluPerspective(45.0f,(float)HEIGTH/(float)WIDTH,0.1f,150.0f);            
            gl.glMatrixMode(GL.GL_MODELVIEW);                        // Go back into our model view matrix            

            return selectBuffer;

}

      private int getSelection(int[] selectBuffer) {
            int objectsFound;
            // If we return to our normal render mode from select mode, glRenderMode returns
           // the number of objects that were found in our specified region (specified in gluPickMatrix())
           
            //      Return to render mode and get the number of objects found
           objectsFound = gl.glRenderMode(GL.GL_RENDER);      
           
            gl.glMatrixMode(GL.GL_PROJECTION);                  // Put our projection matrix back to normal.            
           gl.glPopMatrix();                                          // Stop effecting our projection matrix
           
            gl.glMatrixMode(GL.GL_MODELVIEW);                  // Go back to our normal model view matrix
           
            // PHEW!  That was some stuff confusing stuff.  Now we are out of the clear and should have
           // an ID of the object we clicked on.  objectsFound should be at least 1 if we found an object.
           
            System.out.println("Objects found : "+objectsFound);
            if (objectsFound > 0) {            
                  // If we found more than one object, we need to check the depth values
                 // of all the objects found.  The object with the LEAST depth value is
                 // the closest object that we clicked on.  Depending on what you are doing,
                 // you might want ALL the objects that you clicked on (if some objects were
                 // behind the closest one), but for this tutorial we just care about the one
                 // in front.  So, how do we get the depth value?  Well, The selectionBuffer
                 // holds it.  For every object there is 4 values.  The first value is
                 // "the number of names in the name stack at the time of the event, followed
                 // by the minimum and maximum depth values of all vertices that hit since the
                 // previous event, then followed by the name stack contents, bottom name first." - MSDN
                 // The only ones we care about are the minimum depth value (the second value) and
                 // the object ID that was passed into glLoadName() (This is the fourth value).
                 // So, [0 - 3] is the first object's data, [4 - 7] is the second object's data, etc...
                 // Be carefull though, because if you are displaying 2D text in front, it will
                 // always find that as the lowest object.  So make sure you disable text when
                 // rendering the screen for the object test.  I use a flag for RenderScene().
                 // So, lets get the object with the lowest depth!            
           
                  // Set the lowest depth to the first object to start it off.
                 // 1 is the first object's minimum Z value.
                 // We use an unsigned int so we don't get a warning with selectBuffer below.
                 int lowestDepth = selectBuffer[1];
           
                  // Set the selected object to the first object to start it off.
                 // 3 is the first object's object ID we passed into glLoadName().
                 int selectedObject = selectBuffer[3];                  
           
                  // Go through all of the objects found, but start at the second one
                 for (int i = 1; i < objectsFound; i++) {
                        // Check if the current objects depth is lower than the current lowest
                       // Notice we times i by 4 (4 values for each object) and add 1 for the depth.
                       if (selectBuffer[(i * 4) + 1] < lowestDepth) {
                              // Set the current lowest depth
                             lowestDepth = selectBuffer[(i * 4) + 1];
           
                              // Set the current object ID
                             selectedObject = selectBuffer[(i * 4) + 3];
                        }
                  }
                  System.out.println("Selected object : "+selectedObject);
                 
                  return selectedObject;                  
            }
           
            return 0;      
      }


Best Regards,

Sami
Pages: [1]
  Print  
 
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.16 | SMF © 2011, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.493 seconds with 21 queries.