Open GL Super Bible

Previous Table of Contents Next


Now in our ProcessSelection function, we still call the ProcessPlanet function that we wrote, but this time we pass the entire selection buffer:

// If a single hit occurred, display the info.
if(hits == 1)
        ProcessPlanet(selectBuff);

Listing 19-5 shows the more substantial ProcessPlanet function for this example. In this instance, the bottom name on the names stack will always be the name of the planet because it was pushed on first. If a moon is clicked on, it will also be on the names stack. This function displays the name of the planet selected, and if it was a moon, that information is also displayed. A sample output is shown in Figure 19-4.


Figure 19-4  Sample output from the MOONS sample program

Listing 19-5 Code that parses the selection buffer for the MOONS sample program

// Parse the selection buffer to see which planet/moon was selected
void ProcessPlanet(GLuint *pSelectBuff)
        {
        int id,count;
        char cMessage[64];

// How many names on the name stack
count = pSelectBuff[0];

// Bottom of the name stack
id = pSelectBuff[3];

// Select on earth or mars, whichever was picked
switch(id)
        {
        case EARTH:
                strcpy(cMessage,"You clicked Earth.");

                // If there is another name on the name stack,
                // then it must be the moon that was selected
                // This is what was actually clicked on
                if(count == 2)
                        strcat(cMessage,"\nSpecifically the moon.");
                break;

        case MARS:
                strcpy(cMessage,"You clicked Mars.");

                // We know the name stack is only two deep. The precise
                // moon that was selected will be here.
                if(count == 2)
                        {
                        if(pSelectBuff[4] == MOON1)
                             strcat(cMessage,"\nSpecifically Moon #1.");
                        else
                             strcat(cMessage,"\nSpecifically Moon #2.");
                        }
                break;
                // If nothing was clicked we shouldn't be here!
                default:
                      strcpy(cMessage,"Error - Nothing was clicked on!");
                      break;
                }

        // Display the message about planet and moon selection
        MessageBox(NULL,cMessage,"Selection Message",MB_OK);
        }

Feedback

Feedback, like selection, is a rendering mode that does not produce output in the form of pixels on the screen. Instead, information is written to a feedback buffer about how the scene would have been rendered. This information includes transformed vertex data in window coordinates, color data resulting from lighting calculations, and texture data.

Feedback mode is entered just like selection mode, by calling glRenderMode with a GL_FEEDBACK argument. You must reset the rendering mode to GL_RENDER to fill the feedback buffer and return to normal rendering mode.

The Feedback Buffer

The feedback buffer is an array of floating point values specified with the glFeedback function:

void glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer);

This function takes the size of the feedback buffer, the type and amount of drawing information wanted, and finally a pointer to the buffer itself.

Valid values for type are shown in Table 19-1. The type of data specifies how much data is placed in the feedback buffer for each vertex. Color data (C) is represented by a single value in color index mode, or four values for RGBA color mode.

Table 19-1 Feedback Buffer Types

Type Vertex Coordinates Color Data Texture Data Total Values

GL_2D x, y N/A N/A 2
GL_3D x, y, z N/A N/A 3
GL_3D_COLOR x, y, z C N/A 3 + C
GL_3D_COLOR_TEXTURE x, y, z C 4 7 + C
GL_4D_COLOR_TEXTURE x, y, z, w C 4 8 + C

Feedback Data

The feedback buffer contains a list of tokens followed by vertex data and possibly color and texture data. You can parse for these tokens (see Table 19-2) to determine the types of primitives that would have been rendered.

Table 19-2 Feedback Buffer Tokens

Token Primitive

GL_POINT_TOKEN Points
GL_LINE_TOKEN Line
GL_LINE_RESET_TOKEN Line segment when line stipple is reset
GL_POLYGON_TOKEN Polygon
GL_BITMAP_TOKEN Bitmap
GL_DRAW_PIXEL_TOKEN Pixel rectangle drawn
GL_COPY_PIXEL_TOKEN Pixel rectangle copied
GL_PASS_THROUGH_TOKEN User-defined marker

The point, bitmap, and pixel tokens are followed by data for a single vertex, and possibly color and texture data. This depends on the data type from Table 19-1 specified in the call to glFeedbackBuffer. The line tokens return two sets of vertex data, and the polygon token is immediately followed by the number of vertices that follow. The user-defined marker (GL_PASS_THROUGH_TOKEN) is followed by a single floating point value that is user defined. Figure 19-5 shows an example of a feedback buffer’s memory layout if a GL_3D type were specified.


Figure 19-5  An example memory layout for a feedback buffer

PassThrough Markers

When your rendering code is executing, the feedback buffer is filled with tokens and vertex data as each primitive is specified. Just as you can in selection mode, you can flag certain primitives by naming them. In feedback mode you can set markers between your primitives, as well. This is done by calling glPassThrough:

void glPassThrough(GLfloat token );

This function places a GL_PASS_THROUGH_TOKEN in the feedback buffer, followed by the value you specify when calling the function. This is somewhat similar to naming primitives in selection mode. It’s the only way of labeling objects in the feedback buffer.


Previous Table of Contents Next