Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: Problem with selection

  1. #1
    Junior Member Newbie
    Join Date
    Dec 2003
    Location
    Cleveland
    Posts
    22

    Problem with selection

    Having a problem with selection of objects.

    Ultimately, I want to be able to right-click on an object, which results in pop up messagewindow with a list of moves the object can make (checkers prog)

    I thought I had a pretty good understanding of how selection works (via select_mode). However, I'm not getting any results.

    Code :
     int RetrieveObjectID(int x, int y)
    {
    	int objectsFound = 0;								// This will hold the amount of objects clicked
    	int	viewportCoords[4] = {0};						// We need an array to hold our view port coordinates
     
    	// This will hold the ID's of the objects we click on.
    	unsigned int selectBuffer[32] = {0};				
     
    	// glSelectBuffer is what we register our selection buffer with.  The first parameter
    	// is the size of our array.  The next parameter is the buffer to store the information found.
    	// More information on the information that will be stored in selectBuffer is further below.
    	glSelectBuffer(32, selectBuffer);					// Setup our selection buffer to accept object ID's
     
    	// This function returns information about many things in OpenGL.  We pass in GL_VIEWPORT
    	// to get the view port coordinates.  It saves it like a RECT with {top, left, bottom, right}
     
    	glGetIntegerv(GL_VIEWPORT, viewportCoords);			// Get the current view port coordinates
     
    	// Now we want to get out of our GL_MODELVIEW matrix and start effecting our
    	// GL_PROJECTION matrix.  This allows us to check our X and Y coords against 3D space.
     
    	glMatrixMode(GL_PROJECTION);						// We want to now effect our projection matrix
     
    	glPushMatrix();										// We push on a new matrix so we don't effect our 3D projection
     
    		glRenderMode(GL_SELECT);						// Allows us to render the objects, but not change the frame buffer
     
    		glLoadIdentity();								// Reset our projection matrix
     
    		gluPickMatrix(x, viewportCoords[3] - y, 2, 2, viewportCoords);
    		cout<< x << " x value, " << viewportCoords[3] - y << " y value, "<< 2 << " " << 2 <<endl;
     
    		// 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. 
     
    		gluPerspective(45.0f,(float)g_rRect.right/(float)g_rRect.bottom,1.0f,300.0f);
     
    		glMatrixMode(GL_MODELVIEW);						// Go back into our model view matrix
     
    		glutDisplay();									// Now we render into our selective mode to pinpoint clicked objects
     
    		objectsFound = glRenderMode(GL_RENDER);			// Return to render mode and get the number of objects found
     
    		glMatrixMode(GL_PROJECTION);					// Put our projection matrix back to normal.
     
    		glPopMatrix();										// Stop effecting our projection matrix
     
    		glMatrixMode(GL_MODELVIEW);							// Go back to our normal model view matrix
     
    		if (objectsFound > 0)
    		{		
    			// 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.
    		unsigned 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];
    			}
    		}
     
    		// Return the selected object
    		return selectedObject;
    	}
     
    	// We didn't click on any objects so return 0
    	return 0;											
    }
    This was from an example on the internet.
    Its called from the GlutMouse function.
    Also here's the display function i use

    Code :
     void glutDisplay(void)
    {
        glDisable(GL_LIGHTING);
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	glClearColor(1.0,1.0,1.0,1.0);
     
     
        if (wireframe)
            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        else
            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     
     
        glPushMatrix();
     
        /* translate camera to the coordinates provided by eye array */
        glTranslatef (-eye[0], -eye[1], -eye[2]);
     
        /* rotates the screen by the angles provided by rot array */
        glRotatef(rot[0], 1.0f, 0.0f, 0.0f);
        glRotatef(rot[1], 0.0f, 1.0f, 0.0f);
        glRotatef(rot[2], 0.0f, 0.0f, 1.0f);
     
        glBindTexture(GL_TEXTURE_2D, g_TexturesArray[0]);
     
    	//**** Call display list for checker board
    	glCallList(displayLists);
     
        glPopMatrix();
     
     
    	for(int i = 0; i < 12; i++)
    	{
     
     
    		if(Piece_Alive[1][i] == true)
    		{
    			double dimX, dimY;
     
    			glPushName(i + 100);
    			glPushMatrix();
     
    				/* translate camera to the coordinates provided by eye array */
    				glTranslatef (-eye[0], -eye[1], -eye[2]);
     
    				/* rotates the screen by the angles provided by rot array */
    				glRotatef(rot[0], 1.0f, 0.0f, 0.0f);
    				glRotatef(rot[1], 0.0f, 1.0f, 0.0f);
    				glRotatef(rot[2], 0.0f, 0.0f, 1.0f);
    				// We translate the cylinder over by half of it's length so it's centered on the screen
    				glColor3f(0.1f,0.1f,0.1f);
    				getCoordinateValues(dimX, dimY, Piece_CoordinateX[i], Piece_CoordinateY[i]);
    			//	cout << dimX << " x value "<< dimY <<" y value "<<endl;
    				glTranslatef(dimX - 1, 1.11, dimY +.25);				// Move the cylinder over so it's centered around (0, 0, 0)
    				glRotatef(90, 1.0f, 0.0f, 0.0f);
    				glCallList(displayLists + 1);
     
    			glPopMatrix();
    			glPopName();
    		}
    	}
     
    	for(int j = 12; j < 24; j++)
    	{
     
     
    		if(Piece_Alive[0][j] == true)
    		{
    			double dimX, dimY;
    			glPushName(j + 100);
    			glPushMatrix();
     
    				/* translate camera to the coordinates provided by eye array */
    				glTranslatef (-eye[0], -eye[1], -eye[2]);
     
    				/* rotates the screen by the angles provided by rot array */
    				glRotatef(rot[0], 1.0f, 0.0f, 0.0f);
    				glRotatef(rot[1], 0.0f, 1.0f, 0.0f);
    				glRotatef(rot[2], 0.0f, 0.0f, 1.0f);
    				// We translate the cylinder over by half of it's length so it's centered on the screen
    				glColor3f(1.0f,0.0f,0.0f);
    				getCoordinateValues(dimX, dimY, Piece_CoordinateX[j], Piece_CoordinateY[j]);
    			//	cout << dimX << " x value "<< dimY <<" y value "<<endl;
    				glTranslatef(dimX - 1, 1.11, dimY - 2.25);				// Move the cylinder over so it's centered around (0, 0, 0)
    				glRotatef(90, 1.0f, 0.0f, 0.0f);
    				glCallList(displayLists + 1);
     
    			glPopMatrix();
    			glPopName();
    		}
    	}
     
        CalculateFrameRate();
     
        glFlush();
        glutSwapBuffers();
     
    }
    My only guesses of whats wrong is maybe my selection buffer is too small, I read somewhere that it holds all kinds of info on objects and I have 24 pieces which are to be selected. Also would the transformations I do before created the object have anything do with it?

  2. #2
    Advanced Member Frequent Contributor plasmonster's Avatar
    Join Date
    Mar 2004
    Posts
    750

    Re: Problem with selection

    Make sure that somewhere in your program you have
    some code to initialize selection:

    Code :
     
    const int bufferSize = 1024;
    uint buffer[bufferSize];
     
    glSelectBuffer( bufferSize , buffer );
    glRenderMode( GL_SELECT );
    glInitNames();
    You need this before picking can begin; when you clear the screen, for example.

    Another area that can be problematic is the selection rectangle itself. Your code looks ok, but for santity, I draw the selection rect on
    the screen so I can verify that it is where I think it is.
    You posted alot of code, perhaps I missed sometihng else...

  3. #3
    Junior Member Newbie
    Join Date
    Dec 2003
    Location
    Cleveland
    Posts
    22

    Re: Problem with selection

    Actually, I don't think I quite fully understand this part of the code.

    Code :
      glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glRenderMode(GL_SELECT);
    glLoadIdentity();
    gluPickMatrix(x, viewportCoords[3] - y, 2, 2, viewportCoords);
    gluPerspective(45.0f,(float)g_rRect.right/(float)g_rRect.bottom,1.0f,300.0f);
    I understand it's switching to the Projection Matrix, which as I understand projects the 3-d dimensional into a 2D space. Then pushing the current matrix in place. Loading an identity matrix, but I don't quite get the gluPickMatrix() part which i assume creates the new matrix. Does it multiply the Identity or whatever matrix is in use? Understanding this would help me make the bounding square (btw good idea). Any explanations?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •