Jump to content
  • Advertisement
Sign in to follow this  
KarenRei

OpenGL OpenGL Picking Conundrum

This topic is 4712 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This is my first project to use each of A) gtkglextmm, and B) OpenGl object selection. Despite many different attempts and approaches, I can't get it to work, and I don't know which one to blame. Suspecting OpenGL (and my code, in some bizarre way or another), I'm going to try here first. First, here's the relevant section of my code, boiled down to a simple example:
bool Scene::on_expose_event(GdkEventExpose* event)
{
    Glib::RefPtr<Gdk::GL::Window> window = get_gl_window();
    if (!window->gl_begin(get_gl_context()))
        return false;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, 1.0, 1.0, 1000000.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0, 1000, -3000,
              0, 0, 0,
              0, 1, 0);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glRenderMode(GL_RENDER);

    glColor3f(WIRE_DISPLAY_COLOR[0], WIRE_DISPLAY_COLOR[1], WIRE_DISPLAY_COLOR[2]);
    glBegin(GL_TRIANGLES);
    {
        glVertex3d(-600, -600, 0);
        glVertex3d(-400, -600, 0);
        glVertex3d(-600, -400, 0);
    }
    glEnd();
    glBegin(GL_TRIANGLES);
    {
        glVertex3d(600, -600, 0);
        glVertex3d(400, -600, 0);
        glVertex3d(600, -400, 0);
    }
    glEnd();
    glBegin(GL_TRIANGLES);
    {
        glVertex3d(600, 600, 0);
        glVertex3d(400, 600, 0);
        glVertex3d(600, 400, 0);
    }
    glEnd();
    glBegin(GL_TRIANGLES);
    {
        glVertex3d(-600, 600, 0);
        glVertex3d(-400, 600, 0);
        glVertex3d(-600, 400, 0);
    }
    glEnd();

    window->swap_buffers();

    if (need_pick)
        do_pick();

    window->gl_end();

    return true;
}

void Scene::do_pick()
{
    need_pick=false;

    GLuint selection_buffer[MAX_SELECTION*4];
    GLint viewport_buffer[4];
    glSelectBuffer(MAX_SELECTION*4, selection_buffer);
    glRenderMode(GL_SELECT);
    glInitNames();
    glPushName(0);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glGetIntegerv(GL_VIEWPORT, viewport_buffer);
    gluPickMatrix(pick_x,pick_y,pick_width,pick_height,viewport_buffer);
    gluPerspective(45.0, 1.0, 1.0, 1000000.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0, 1000, -3000,
              0, 0, 0,
              0, 1, 0);

    glLoadName(1);
    glBegin(GL_TRIANGLES);
    {
        glVertex3d(-600, -600, 0);
        glVertex3d(-400, -600, 0);
        glVertex3d(-600, -400, 0);
    }
    glEnd();
    glLoadName(2);
    glBegin(GL_TRIANGLES);
    {
        glVertex3d(600, -600, 0);
        glVertex3d(400, -600, 0);
        glVertex3d(600, -400, 0);
    }
    glEnd();
    glLoadName(3);
    glBegin(GL_TRIANGLES);
    {
        glVertex3d(600, 600, 0);
        glVertex3d(400, 600, 0);
        glVertex3d(600, 400, 0);
    }
    glEnd();
    glLoadName(4);
    glBegin(GL_TRIANGLES);
    {
        glVertex3d(-600, 600, 0);
        glVertex3d(-400, 600, 0);
        glVertex3d(-600, 400, 0);
    }
    glEnd();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    const int hits=glRenderMode(GL_RENDER);

    cout << "Picking.  Hits=" << hits << endl;
}
On expose, it draws four triangles, then, if the variable need_pick has been set by some other thread due a mouse event (along with the x, y, width, and height associated with the picking operation), it runs the exact same drawing code in selection mode. The opengl context should be current, as it was just used to render, and just in case somehow the modelview matrix is getting messed up, I set it up from a fresh glLoadIdentity. In the past, I have also printed out the modelview matrix (gotten with a glGetDoublev) to verify that it's the same in both places; it is. I've also printed out the mouse coordinates being stored in pick_x, pick_y, etc to make sure that they're in the proper locations with respect to the viewport; they are. The problem is, this code just doesn't work. The objects can't get picked. However, bizarrely, if I change the gluLookAt's y coordinate to "0" instead of "1000", the code *does* work. Does anyone have a clue what on earth could be going on here? I'm completely baffled. :(

Share this post


Link to post
Share on other sites
Advertisement
Does your pick_y take into account that the viewport origin is different than the window origin? Emphasis is mine.

Quote:

void gluPickMatrix(GLdouble x, GLdouble y, GLdouble witdth, GLdouble height, GLint viewport[4]);

Parameters:

x,y : These two values represent the cursor location. They define the centre of the picking area. This value is specified in window coordinates. However note that window coordinates in OpenGL have the origin at the bottom left corner of the viewport, whereas for the Operating system is the upper left corner.
width, height : The size of the picking region, too small and you may be hard pressed to pick small objects, too large and you may end up with too many hits.
viewport : The current viewport


I suppose I should add this. Its been a while since I have done picking in openGL but here is the line of code I have in my projects

gluPickMatrix(x, viewport[3]-y, 6.0, 6.0, viewport);

the viewport[3]-y accounts for the difference between the viewport origin and the window origin.

Share this post


Link to post
Share on other sites
Aaargh, you're 100% spot on, and I'm just plain silly to have missed that after reading about half a dozen code examples :P Thank you!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!