Feedback (Selection and Feedback) (OpenGL Programming)

Feedback is similar to selection in that once you’re in either mode, no pixels are produced and the screen is frozen. Drawing does not occur; instead, information about primitives that would have been rendered is sent back to the application. The key difference between selection and feedback modes is the information that is sent back. In selection mode, assigned names are returned to an array of integer values. In feedback mode, information about transformed primitives is sent back to an array of floating-point values. The values sent back to the feedback array consist of tokens that specify what type of primitive (point, line, polygon, image, or bitmap) has been processed and transformed, followed by vertex, color, or other data for that primitive. The values returned are fully transformed by lighting and viewing operations. Feedback mode is initiated by calling glRenderMode() with GL_FEEDBACK as the argument.

Here’s how you enter and exit feedback mode:

1. Call glFeedbackBuffer() to specify the array to hold the feedback information. The arguments for this command describe what type of data and how much of it is written into the array.

2. Call glRenderMode() with GL_FEEDBACK as the argument to enter feedback mode. (For this step, you can ignore the value returned by glRenderMode().) After this point, primitives aren’t rasterized to produce pixels until you exit feedback mode, and the contents of the framebuffer don’t change.


3. Draw your primitives. While issuing drawing commands, you can make several calls to glPassThrough() to insert markers into the returned feedback data and thus facilitate parsing.

4. Exit feedback mode by calling glRenderMode() with GL_RENDER as the argument if you want to return to normal drawing mode. The integer value returned by glRenderMode() is the number of values stored in the feedback array.

5. Parse the data in the feedback array.

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

Establishes a buffer for the feedback data buffer is a pointer to an array where the data is stored. The size argument indicates tne maximum number of values that can be stored in the array. The tvpe argument describes the information fed back for each vertex in the feedback array; its possible values and their meanings are shown in Table 13-1. glFeedbackBuffer() must be called before feedback mode is entered. In the table, k is 1 in color-index mode and 4 in RGBA mode.

type Argument

Coordinates

Color

Texture

Total Values

GL_2D

*>y

-

-

2

GL_3D

x, y, z

-

-

3

GL_3D_COLOR

χ,γ,ζ

k

-

3 + k

GL_3D_COLOR_TEXTURE

χ,γ,ζ

k

4

7 + k

GL_4D_COLOR_TEXTURE

x, y, z, w

k

4

8 + k

Table 13-1 glFeedbackBufferQ type Values

Note: When multitexturing is supported, feedback returns only the texture coordinates of texture unit 0.

The Feedback Array

In feedback mode, each primitive that would be rasterized (or each call to glBitmapO, glDrawPixels(), or glCopyPixels(), if the raster position is valid) generates a block of values that’s copied into the feedback array. The number of values is determined by the type argument of glFeedbackBuffer(), as listed in Table 13-1. Use the appropriate value for the type of primitives you’re drawing: GL_2D or GL_3D for unlit two- or three-dimensional primitives; GL_3D_COLOR for lit, three-dimensional primitives; and GL_3D_ COLOR_TEXTURE or GL_4D_COLOR_TEXTURE for lit, textured, three- or four-dimensional primitives.

Each block of feedback values begins with a code indicating the primitive type, followed by values that describe the primitive’s vertices and associated data. Entries are also written for pixel rectangles. In addition, pass-through markers that you’ve explicitly created can be returned in the array; the next subsection explains these markers in more detail. Table 13-2 shows the syntax for the feedback array; remember that the data associated with each returned vertex is as described in Table 13-1. Note that a polygon can have n vertices returned. Also, the x-, y-, and z-coordinates returned by feedback are window coordinates; if w is returned, it’s in clip coordinates. For bitmaps and pixel rectangles, the coordinates returned are those of the current raster position. In Table 13-2, note that GL_LINE_RESET_TOKEN is returned only when the line stipple is reset for that line segment.

Primitive Type

Code

Associated Data

Point

GL_POINT_T OKEN

vertex

Line

GL_LINE_TOKEN or GL_LINE_ RESET_TOKEN

vertex vertex

Polygon

GL_POLYGON_TOKEN

h vertex vertex … vertex

Bitmap

GL_BITMAP_TOKEN

vertex

Pixel Rectangle

GL_DRAW_PIXEL_TOKEN or GL_COPY_PIXEL_TOKEN

vertex

Pass-through

GL_PASS_THROUGH_TOKEN

a floating-point number

Table 13-2 Feedback Array Syntax

Using Markers in Feedback Mode

Feedback occurs after transformations, lighting, polygon culling, and interpretation of polygons by glPolygonMode(). It might also occur after polygons with more than three edges are broken up into triangles (if your particular OpenGL implementation renders polygons by performing this decomposition). Thus, it might be hard for you to recognize the primitives you drew in the feedback data you receive. To help parse the feedback data, call glPassThroughQ as needed in your sequence of drawing commands to insert a marker. You might use the markers to separate the feedback values returned from different primitives, for example. This command causes GL_ PASS_THROUGH_TOKEN to be written into the feedback array, followed by the floating-point value you pass in as an argument.

A Feedback Example

Example 13-7 demonstrates the use of feedback mode. This program draws a lit, three-dimensional scene in normal rendering mode. Then, feedback mode is entered, and the scene is redrawn. Since the program draws lit, untextured, three-dimensional objects, the type of feedback data is GL_3D_ COLOR. Since RGBA mode is used, each unclipped vertex generates seven values for the feedback buffer: x, y, z, r, g, b, and a.

In feedback mode, the program draws two lines as part of a line strip and then inserts a pass-through marker. Next, a point is drawn at (-100.0, -100.0, -100.0), which falls outside the orthographic viewing volume and thus doesn’t put any values into the feedback array. Finally, another passthrough marker is inserted, and another point is drawn.

Example 13-7 Feedback Mode: feedback.c

Feedback Mode: feedback.c

 

 

 

Feedback Mode: feedback.c

 

 

 

Feedback Mode: feedback.c

Running this program generates the following output:

tmp73ec-45_thumb

Thus, the line strip drawn with these commands results in two primitives:

tmp73ec-46_thumb

The first primitive begins with GL_LINE_RESET_TOKEN, which indicates that the primitive is a line segment and that the line stipple is reset. The second primitive begins with GL_LINE_TOKEN, so it’s also a line segment, but the line stipple isn’t reset and hence continues from where the previous line segment left off. Each of the two vertices for these lines generates seven values for the feedback array. Note that the RGBA values for all four vertices in these two lines are (0.84, 0.84, 0.84, 1.0), which is a very light gray color with the maximum alpha value. These color values are a result of the interaction of the surface normal and lighting parameters.

Since no feedback data is generated between the first and second passthrough markers, you can deduce that any primitives drawn between the first two calls to glPassThrough() were clipped out of the viewing volume. Finally, the point at (50.0, 50.0, 0.0) is drawn, and its associated data is copied into the feedback array.

Note: In both feedback and selection modes, information about objects is returned prior to any fragment tests. Thus, objects that would not be drawn due to failure of the scissor, alpha, depth, or stencil test may still have their data processed and returned in both feedback and selection modes.

Try This

Make changes in Example 13-7 to see how they affect the feedback values that are returned. For example, change the coordinate values of glOrtho(). Change the lighting variables, or eliminate lighting altogether and change the feedback type to GL_3D. Or, add more primitives to see what other geometric objects (such as filled polygons) contribute to the feedback array.

Next post:

Previous post: