Silicon Graphics

[Prev] [TOC] [Next]



(-) OpenGL Programming Guide
(-) Chapter 12Selection and Feedback
(-) Feedback

A Feedback Example

Example 12-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 pass-through marker is inserted, and another point is drawn.

Example 12-7 : Using Feedback Mode: feedback.c


#include <GL/gl.h>
#include <GL/glu.h>
#include "aux.h"

void myinit(void)
{
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
}

void drawGeometry (GLenum mode)
{
    glBegin (GL_LINE_STRIP);
        glNormal3f (0.0, 0.0, 1.0);
        glVertex3f (30.0, 30.0, 0.0);
        glVertex3f (50.0, 60.0, 0.0);
        glVertex3f (70.0, 40.0, 0.0);
    glEnd ();
    if (mode == GL_FEEDBACK)
        glPassThrough (1.0);

    glBegin (GL_POINTS);
        glVertex3f (-100.0, -100.0, -100.0); 
    glEnd ();
    if (mode == GL_FEEDBACK)
        glPassThrough (2.0);

    glBegin (GL_POINTS);
        glNormal3f (0.0, 0.0, 1.0);
        glVertex3f (50.0, 50.0, 0.0);
    glEnd ();
}

void print3DcolorVertex (GLint size, GLint *count, 
        GLfloat *buffer)
{
    int i;

    printf ("  ");
    for (i = 0; i < 7; i++) {
        printf ("%4.2f ", buffer[size-(*count)]);
        *count = *count - 1;
    }
    printf ("\n");
}

void printBuffer(GLint size, GLfloat *buffer)
{
    GLint count;
    GLfloat token;

    count = size;
    while (count) {
        token = buffer[size-count]; count--;
        if (token == GL_PASS_THROUGH_TOKEN) {
            printf ("GL_PASS_THROUGH_TOKEN\n");
            printf ("  %4.2f\n", buffer[size-count]);
            count--;
        }
        else if (token == GL_POINT_TOKEN) {
            printf ("GL_POINT_TOKEN\n");
            print3DcolorVertex (size, &count, buffer);
        }
        else if (token == GL_LINE_TOKEN) {
            printf ("GL_LINE_TOKEN\n");
            print3DcolorVertex (size, &count, buffer);
            print3DcolorVertex (size, &count, buffer);
        }
        else if (token == GL_LINE_RESET_TOKEN) {
            printf ("GL_LINE_RESET_TOKEN\n");
            print3DcolorVertex (size, &count, buffer);
            print3DcolorVertex (size, &count, buffer);
        }
    }
}

void display(void)
{
    GLfloat feedBuffer[1024];
    GLint size;

    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    glOrtho (0.0, 100.0, 0.0, 100.0, 0.0, 1.0);

    glClearColor (0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    drawGeometry (GL_RENDER);

    glFeedbackBuffer (1024, GL_3D_COLOR, feedBuffer);
    (void) glRenderMode (GL_FEEDBACK);
    drawGeometry (GL_FEEDBACK);

    size = glRenderMode (GL_RENDER);
    printBuffer (size, feedBuffer);
}


int main(int argc, char** argv)
{
    auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);
    auxInitPosition (0, 0, 100, 100);
    auxInitWindow (argv[0]);
    myinit ();
    auxMainLoop(display);
}

Running this program generates the following output:

GL_LINE_RESET_TOKEN
 30.00 30.00 0.00 0.84 0.84 0.84 1.00
 50.00 60.00 0.00 0.84 0.84 0.84 1.00
GL_LINE_TOKEN
 50.00 60.00 0.00 0.84 0.84 0.84 1.00
 70.00 40.00 0.00 0.84 0.84 0.84 1.00
GL_PASS_THROUGH_TOKEN
 1.00
GL_PASS_THROUGH_TOKEN
 2.00
GL_POINT_TOKEN
 50.00 50.00 0.00 0.84 0.84 0.84 1.00

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

glBegin(GL_LINE_STRIP);
    glNormal3f (0.0, 0.0, 1.0);
    glVertex3f (30.0, 30.0, 0.0);
    glVertex3f (50.0, 60.0, 0.0);
    glVertex3f (70.0, 40.0, 0.0);
glEnd();

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 pass-through 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.

Try This

Try This

Make changes to Example 12-7 and 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 geometry (such as filled polygons) contributes to the feedback array.


[Prev] [TOC] [Next]

OpenGL Programming Guide


Maintained by Maintainer: Send e-mail to .htm">name@address.