wolvorinePk
wolvorinePk

Reputation: 1790

C++ OpenGL Mouse picking on thin lines not working

I am first time using picking technique and I have followed the NEHE tutorial to use picking technique in opengl , i actually need to detect the thin lines on the square. But i am not sure why it is not detecting it correctly , even if i remove the square from its background still it select randomly other selections rather than the one i made it. Most of the time it never detect... so i made another test exe and i put 2 lines only and removed the square background but still it don't get selected..some times it get selected on other parts of the screen.. These lines are little far from the screen so i gave zooming freedom to see clearly how lines are existing so i checked it by zoom as well...but still no use. its very confusing.

below is my code how i am creating the lines

my initialization code

void COpenGLControl::oglInitialize(void)
{
    // Initial Setup:
    //
    static PIXELFORMATDESCRIPTOR pfd =
    {
        sizeof(PIXELFORMATDESCRIPTOR),
        1,
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA,
        32, // bit depth
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        16, // z-buffer depth
        0, 0, 0, 0, 0, 0, 0,
    };


    // Get device context only once.
    hdc = GetDC()->m_hDC;

    // Pixel format.
    m_nPixelFormat = ChoosePixelFormat(hdc, &pfd);
    SetPixelFormat(hdc, m_nPixelFormat, &pfd);

    // Create the OpenGL Rendering Context.
    hrc = wglCreateContext(hdc);
    wglMakeCurrent(hdc, hrc);

    // Basic Setup:
    //
    // Set color to use when clearing the background.
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClearDepth(1.0f);

    // Turn on backface culling
    glFrontFace(GL_CCW);
    glCullFace(GL_BACK);

    // Turn on depth testing

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    GLenum a = glGetError();
    CCTrace::Trace(L"COpenGLControl::oglInitialize return",a);

    OnDraw(NULL);
}

this is selection method which i am calling on mouse click

void CRightOGL::Selection(int mouse_x,int mouse_y)                                          // This Is Where Selection Is Done
{

    GLuint    buffer[512]={0};
    GLint   hits; // The Number Of Objects That We Selected

    // The Size Of The Viewport. [0] Is <x>, [1] Is <y>, [2] Is <length>, [3] Is <width>
    GLint   viewport[4];

    // This Sets The Array <viewport> To The Size And Location Of The Screen Relative To The Window
    glGetIntegerv(GL_VIEWPORT, viewport);
    glSelectBuffer(512, buffer);                                // Tell OpenGL To Use Our Array For Selection


    (void) glRenderMode(GL_SELECT);

    glInitNames();                                              
    glPushName(0);                                              

    glMatrixMode(GL_PROJECTION);                                
    glPushMatrix();                                             
    glLoadIdentity();                                           


    gluPickMatrix((GLdouble) mouse_x, (GLdouble) (viewport[3]-mouse_y), 30.0f, 30.0f, viewport);


    gluPerspective(35.0f, (GLfloat) (viewport[2]-viewport[0])/(GLfloat) (viewport[3]-viewport[1]), 0.01f, 2000.0f);
    glMatrixMode(GL_MODELVIEW);                             


    DrawTargetLines();                                          

    //DrawJawImage();   
    glMatrixMode(GL_PROJECTION);                                // Select The Projection Matrix
    glPopMatrix();                                              // Pop The Projection Matrix
    glMatrixMode(GL_MODELVIEW);                                 // Select The Modelview Matrix
    hits=glRenderMode(GL_RENDER);                               // Switch To Render Mode, Find Out How Many
                                                                // Objects Were Drawn Where The Mouse Was
    GLenum s = glGetError();
    if(s!=0) CCTrace::Trace(L"CRightOGL::oglDrawScene",s);

    if (hits > 0)                                               // If There Were More Than 0 Hits
    {
        int choose = buffer[3];                                 // Make Our Selection The First Object
        int depth = buffer[1];                                  // Store How Far Away It Is 
        //SetTeethSlice(choose);


        for (int loop = 1; loop < hits; loop++)                 // Loop Through All The Detected Hits
        {
            // If This Object Is Closer To Us Than The One We Have Selected
            if (buffer[loop*4+1] < GLuint(depth))
            {
                choose = buffer[loop*4+3];                      // Select The Closer Object
                depth = buffer[loop*4+1];                       // Store How Far Away It Is
            }       
        }
        ((CTeethBiometricApp*)::AfxGetApp())->setDialogSlider(choose);

    }
}

This is draw lines function to draw 52 different lines

void CRightOGL::DrawTargetLines()
{

    glDisable(GL_TEXTURE_2D);
        //original line when you need to adjust the line use this block
        //  glVertex3d(-0.5,-0.23f,1.0f);                  
        //  glVertex3d( -0.1,-0.35f,1.0f);
        //-------------------------------------------------------------------

    float y1 = 0.25f, y2 = 0.37f;
    for(float loop=1;loop<51;loop++)
    {
        y1+=0.004f;
        y2+=0.004f;

        glLoadName(loop);                                       // Assign Object A Name (ID)
        glPushMatrix();                                         // Push The Modelview Matrix
        glLineWidth(3.0f);
        glBegin(GL_LINES);                      // Start Drawing Our Player Using Lines
        if(this->m_CurrentSlice==loop)
            glColor3f(1.0f,1.0f,0.0f);
        else
            glColor3f(1.0f,0.0f,0.0f);

        glVertex3d(-0.5,y1,1.0f);                  // Top Left Of Player
        glVertex3d( -0.1,y2,1.0f);                  // Bottom Right Of Player
                                                // Pop The Modelview Matrix
        glEnd(); 
        glPopMatrix();
    }
}

this is my draw function

void CRightOGL::oglDrawScene(void)
{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glShadeModel(GL_SMOOTH);    

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    glLoadIdentity();
    //glTranslatef(0.0f, 0.0f, -m_fZoom);//this is for zoom using left mouse click but no placing
    glTranslatef(m_fPosX, m_fPosY,-m_fZoom); // this is for placing + zooming using middle scroll button mouse click

    glRotatef(m_fRotX, 1.0f, 0.0f, 0.0f);//these two for mouse movement
    glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
    glRotated(90,0.0f, 0.0f, -1.0f);

    GLenum s = glGetError();

    DrawJawImage(); 
    DrawTargetLines();
    SwapBuffers(hdc);

    glFlush();

}

my test exes are on this dropbox

http://dl.dropbox.com/u/104183650/Release.zip

please use zooming using mouse right button and to rotate left mouse button

Upvotes: 0

Views: 1170

Answers (1)

Ken
Ken

Reputation: 2335

this is a deprecated approach, most of the tutorial that you can find on the internet are old and deprecated, including the ones from NeHe, use a resource that is about OpenGL 3.0+ and you will be fine; there is no point about keep working on this code and keep learning OpenGL with this approach.

Upvotes: 1

Related Questions