Click here to Skip to main content
Licence CPOL
First Posted 29 Oct 2003
Views 106,694
Bookmarked 42 times

How to select an object using OpenGL

By | 29 Oct 2003 | Article
This article explains how to select an object using OpenGL.

Sample Image

Introduction

I am Vietnamese and my English is not good. But I hope you will understand my article. I tried to write a game as my project in school. I decided to write it using 3D technique, and I used OpenGL for this. I looked for a way to select an object on a lot object overunder on 3D and I have found it. In this article I want to introduce you to how to do it.

Using the code

In this example I use MFC wizard. All my code was written on CView.

Add variables:

private:
    GLdouble gldAspect;
    GLsizei glnWidth, glnHeight;
    HGLRC hRC;
    Cube cube[4];
    double r;

Cube is defined in MyOpenGL.h.

Use "class wizard" for message map: WM_CREATE, WM_DESTROY, WM_EARSEBKGND, WM_LBUTTONDOWN, WM_PAINT, WM_SIZE, WM_TIMER.

On another article in CodeProject about OpenGL you can see the code for WM_SIZE and WM_PAINT, WM_CREATE (I use the code again! Thanks to the owner's code!).

Additionally, on WM_CREATE, init for some variables and start the timer for animation.

int CTry_OpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
     if (CView::OnCreate(lpCreateStruct) == -1)
          return -1;
     
     // TODO: Add your specialized creation code here
     hRC=SetUpOpenGL(m_hWnd);
     for(int i=0;i<4;i++) cube[i].x=i*2-3;
     r=0;
     SetTimer(1000,100,NULL);

     return 0;
}

Of course, kill timer in OnDestroy().

Timer:

void CTry_OpenGLView::OnTimer(UINT nIDEvent) 
{
     r+=5;
     if(r>=360) r=0;
     RedrawWindow();

     CView::OnTimer(nIDEvent);
}

In OnEraseBkgnd: delete all (if not, the screen will "flick").

And now, the code to pick an object:

void CTry_OpenGLView::OnLButtonDown(UINT nFlags, CPoint point) 
{
     // TODO: Add your message handler code here and/or call default
    GLuint selectBuf[BUFSIZE];
    GLint hits;
    GLint viewport[4];

     HDC hDC = ::GetDC(this->m_hWnd);
     wglMakeCurrent(hDC,hRC);

    glGetIntegerv (GL_VIEWPORT, viewport);
    glSelectBuffer (BUFSIZE, selectBuf);

    glRenderMode(GL_SELECT); // Enter the SELECT render mode
    glInitNames();
    glPushName(-1);

    glMatrixMode (GL_PROJECTION);
    glPushMatrix ();
    glLoadIdentity ();
    gluPickMatrix((GLdouble) point.x, 
          (GLdouble) (viewport[3] - point.y), 
          5.0, 5.0, viewport);
    gluPerspective(30.0,gldAspect,1.0,20.0);
    glMatrixMode(GL_MODELVIEW);
    PaintScreen(GL_SELECT);//function paint the objects.
    glPopMatrix ();
    glFlush ();

    hits = glRenderMode (GL_RENDER);

     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     glViewport(0,0,glnWidth,glnHeight);
     gluPerspective(30.0,gldAspect,1.0,20.0);
    
     /*for(int i=0;i<hits;i++)
     {
          cube[selectBuf[3+i*4]].selected= 
             !cube[selectBuf[3+i*4]].selected;
     }//select all (include the hide object)!
     */
     if (hits)
     {
          int n=0;double minz=selectBuf[1];
          for(int i=1;i<hits;i++)
          {
               if (selectBuf[1+i*4]<minz) 
                 {n=i;minz=selectBuf[1+i*4];}
          }
          cube[selectBuf[3+n*4]].selected=
              !cube[selectBuf[3+n*4]].selected;
     }//only select the object we see (nearest object)!

     wglMakeCurrent( NULL, NULL );
    ::ReleaseDC( this->m_hWnd, hDC );

     CView::OnLButtonDown(nFlags, point);
}

Points of interest

Is it easy, isn't it? My source has some wastes, I think. Thanks a lot if you can help me to remove it! ^_^

History

  • This is the first!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

ICE_WIZARD

Software Developer (Junior)

Vietnam Vietnam

Member

My subject is Information technology. I like programming and learn more about everything.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 4 Pinmemberchizhaojuan16:41 28 Jul '10  
GeneralGood 1 OpenGL Pinmemberse7en_hunter1:05 8 Apr '08  
QuestionHow to move an object follow mouse? Pinmemberzrockmanx21:25 21 Nov '06  
AnswerRe: How to move an object follow mouse? PinmemberICE_WIZARD5:14 22 Nov '06  
QuestionRe: How to move an object follow mouse? Pinmemberzrockmanx2:44 26 Nov '06  
AnswerRe: How to move an object follow mouse? PinmemberICE_WIZARD5:12 28 Nov '06  
GeneralgluUnProject PinmemberMerlinblack16:56 3 Jul '05  
QuestionAnother method to realize the function? Pinmemberaqing20:16 25 Jun '04  
GeneralNEWBIE Pinmembertarzanviet15:43 7 Jun '04  
GeneralRe: NEWBIE Pinmemberzrockmanx21:14 21 Nov '06  
GeneralRe: NEWBIE PinmemberICE_WIZARD5:04 22 Nov '06  
GeneralRe: NEWBIE Pinmemberzrockmanx2:49 26 Nov '06  
QuestionHow to run 2 different(or same) OpenGL objects in one DialogBox? Pinmemberwerter121:16 3 May '04  
AnswerRe: How to run 2 different(or same) OpenGL objects in one DialogBox? PinmemberICE_WIZARD3:12 4 May '04  
QuestionHow the pros do it Pinmemberdog_spawn5:09 30 Oct '03  
AnswerRe: How the pros do it PinmemberEpicBoy4:31 31 Oct '03  
GeneralRe: How the pros do it Pinmemberdog_spawn4:59 31 Oct '03  
GeneralRe: How the pros do it PinmemberFrançois Gasnier12:13 2 Nov '03  
GeneralRe: How the pros do it PinmemberMerlinblack16:53 3 Jul '05  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120517.1 | Last Updated 30 Oct 2003
Article Copyright 2003 by ICE_WIZARD
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid