Open GL Super Bible:Interactive Graphics
To access the contents, click the chapter and section titles.
Open GL Super Bible
(Publisher: Macmillan Computer Publishing)
Author(s): Waite group Press
ISBN: 1571690735
Publication Date: 08/01/96
Previous
Table of Contents
Next
Working with Selection Mode
As mentioned, OpenGL can operate in three different rendering modes. The default mode is GL_RENDER, in which all the drawing actually occurs on screen. To use selection, we must change the rendering mode to selection by calling the OpenGL function:
glRenderMode(GL_SELECTION);
When we actually want to draw again, we call
glRenderMode(GL_RENDER);
to place OpenGL back in rendering mode. The third rendering mode is GL_FEEDBACK, discussed later in this chapter.
The naming code in Listing 19-1 has no effect unless we first switch the rendering mode to selection mode. Most often, you will use the same function to render the scene in both GL_RENDER mode and GL_SELECTION modes, as we have done here.
Listing 19-2 is the code that is triggered by the clicking of the left mouse button. This code gets the mouse coordinates from lParam and passes them to ProcessSelection, which will process the mouse click for this example.
Listing 19-2 Code that responds to the left mouse button click
case WM_LBUTTONDOWN:
{
int xPos = LOWORD(lParam); // horizontal position of cursor
int yPos = HIWORD(lParam); // vertical position of cursor
// Render in selection mode and display results
ProcessSelection(xPos, yPos);
}
The Selection Buffer
The selection buffer is filled with hit records during the rendering process. A hit record is generated whenever a primitive or collection of primitives is rendered that would have been contained in the viewing volume. Under normal conditions, this is simply anything that would have appeared on screen.
The selection buffer is an array of unsigned integers, and each hit record occupies at least four elements of the array. The first array index contains the number of names that are on the names stack when the hit occurs. For the PLANETS example (Listing 19-1), this will always be 1. The next two entries contain the minimum and maximum window z coordinates of all the vertices contained by the viewing volume since the last hit record. This value, which ranges from [0,1], is scaled to the size of an unsigned integer (2^32
1) for storage in the selection buffer. This pattern, illustrated in Figure 19-1, is then repeated for all the hit records contained in the selection buffer.
Figure 19-1 Hit record format of the selection buffer
The format of the selection buffer gives you no way of knowing how many hit records you will need to parse. This is because the selection buffer is not actually filled until you switch the rendering mode back to GL_RENDER. When you do this with the glRenderMode function, the return value of glRenderMode returns the number of hit records copied.
Listing 19-3 shows the processing function called when a mouse click occurs for the PLANETS example program. It shows the selection buffer being allocated and specified with glSelectBuffer. This function takes two arguments: the length of the buffer and a pointer to the buffer itself.
Listing 19-3 Function to process the mouse click
// Process the selection, which is triggered by a right mouse
// click at (xPos, yPos).
#define BUFFER_LENGTH 64
void ProcessSelection(int xPos, int yPos)
{
// Space for selection buffer
GLuint selectBuff[BUFFER_LENGTH];
// Hit counter and viewport storage
GLint hits, viewport[4];
// Set up selection buffer
glSelectBuffer(BUFFER_LENGTH, selectBuff);
// Get the viewport
glGetIntegerv(GL_VIEWPORT, viewport);
// Switch to projection and save the matrix
glMatrixMode(GL_PROJECTION);
glPushMatrix();
// Change render mode
glRenderMode(GL_SELECT);
// Establish new clipping volume to be unit cube around
// mouse cursor point (xPos, yPos) and extending two pixels
// in the vertical and horizontal direction
glLoadIdentity();
gluPickMatrix(xPos, yPos, 2,2, viewport);
// Apply perspective matrix
gluPerspective(45.0f, fAspect, 1.0, 425.0);
// Draw the scene
RenderScene();
// Collect the hits
hits = glRenderMode(GL_RENDER);
// If a single hit occurred, display the info.
if(hits == 1)
ProcessPlanet(selectBuff[3]);
// Restore the projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
// Go back to modelview for normal rendering
glMatrixMode(GL_MODELVIEW);
}
Previous
Table of Contents
Next
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.
Wyszukiwarka
Podobne podstrony:
YAMAHA AX 596596 (2)596 599594 (2)YAMAHA CDX 59620080311 NMR2id&596591 594594,6,artykul596 04Mechanik nr 8 9 2010 s 590 594596 18więcej podobnych podstron