English 中文(简体)
OpenGL 3D Selection
原标题:

I am trying to create a 3D robot that should perform certain actions when certain body parts are clicked. I have successfully (sort of) implemented picking in that if you click on any x-plane part, it registers a hit, but not anywhere else. That is, it is not registering depth, and if you clicked on it s square head, you could only register a hit by clicking on the front of the head (facing you). Obviously, I don t fully understand picking and selection and am sloppily trying to transcribe what I know about 2D selection to 3D (my teacher is as helpful as a rock) but I have left something out or not changed something pertaining to depth. Can anyone help me out? Here are the related functions.

void processHits (GLint hits, GLuint buffer[])
{
    unsigned int i, j;
    GLint n, *ptr;

    printf ("hits = %d
", hits);
    ptr = (GLint *) buffer;

    //For each hit.
    for (i = 0; i < hits; i++)
    {
        n = *ptr;       //Number of names under current hit.
        ptr+=3;         //Bypass three integers: n, z1, z2.
        printf ("hit %d has %d name(s)
", i, n);

        //For each name.
        for (j = 0; j < n; j++)
        {
            if(*ptr==1) printf ("Body hit.
");
            else if(*ptr==2) printf ("Right shoulder hit.
");
            else if(*ptr==3) printf ("Left shoulder hit.
");
            else if(*ptr==4) printf ("Left arm hit.
");
            else if(*ptr==5) printf ("Right arm hit.
");
            else if(*ptr==6) printf ("Left leg hit.
");
            else if(*ptr==7) printf ("Right leg hit.
");
            else if(*ptr==8) printf ("Right foot hit.
");
            else if(*ptr==9) printf ("Left foot hit.
");
            else if(*ptr==10) printf ("Neck hit.
");
            else if(*ptr==11) printf ("Head hit.
");
            else printf ("Nothing hit.
");

            ptr++;
        }
        printf ("
");
    }
}

void selection(int mouse_x, int mouse_y)
{
    GLuint buffer[512];                     //Set up a selection buffer.
    GLint hits;                             //The number of objects we selected.
    GLint viewport[4];                      //Viewport size. [0] Is <x>, [1] Is <y>, [2] Is <length>, [3] Is <width>.

    glGetIntegerv(GL_VIEWPORT, viewport);   //Sets the array <viewport> to size and location of screen relative to window.
    glSelectBuffer(512, buffer);            //Tell OpenGL to use our array for selection.

    glRenderMode(GL_SELECT);                //Puts OpenGL in selection mode. Nothing will be drawn. Object IDs and extents stored in buffer.

    glInitNames();                          //Initializes name stack.
    glPushName(0);                          //Push an entry onto the stack.

    glMatrixMode(GL_PROJECTION);            //Selects the projection matrix.
    glPushMatrix();                         //Push the projection matrix.
    glLoadIdentity();                       //Resets matrix.

    //This creates a matrix that will zoom up to a small portion of the screen, where the mouse is.
    gluPickMatrix((GLdouble) mouse_x, (GLdouble) (viewport[3]-mouse_y), 0.01, 0.01, viewport);

    gluPerspective(45.0f, (GLfloat) (viewport[2]-viewport[0])/(GLfloat) (viewport[3]-viewport[1]), 0.1f, 100.0f);
    glMatrixMode(GL_MODELVIEW);                                 //Select the modelview matrix.
    drawObjects(GL_SELECT);                                     //Render the targets to the selection buffer.
    glMatrixMode(GL_PROJECTION);                                //Select the projection matrix.
    glPopMatrix();                                              //Pop the projection matrix.
    glMatrixMode(GL_MODELVIEW);                                 //Select the modelview matrix.
    hits = glRenderMode(GL_RENDER);
    processHits (hits, buffer);

    //printf("%d ", hits);

    //Post redisplay message.
    glutPostRedisplay();
}

void mouse(int button, int state, int x, int y)
{    
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {
        selection(x, y);
    }
} 
问题回答

It s not entirely clear what you re asking for. If you mean you re only getting a hit record for the object that s front-most, then that s kind of expected. Polygon(s) that are culled won t generate any hit record(s). If you want hit records for polygons that would normally be culled, you ll want to use glDisable(GL_CULL_FACE); while you do the drawing in selection mode. This prevents polygons from being culled, so they can produce hit records.

Read about Object Selection Using the Back Buffer here. I implemented it once and it worked great.





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签