Click here to Skip to main content
15,867,453 members
Articles / Desktop Programming / MFC
Article

Mouse Selection in OpenGL Scene

Rate me:
Please Sign up or sign in to vote.
4.82/5 (20 votes)
25 Oct 2002CPOL3 min read 248.1K   12.5K   82   27
One another approach for picking objects with the mouse in OpenGL scene.

Sample Image - OpenGLMouseSellection.jpg

Introduction

This article explains how to implement mouse selection in OpenGL scene, as well as moving, rotating and zooming OpenGL scene and sterilization in MDI applications. The project uses MFC Template classes to hold object primitives. There are several methods how you can implement selection in OpenGL scene. Here is a short description.

Selection

Selection method is OpenGL mechanism and it works in the following way. Draw your scene into the framebuffer, and then you enter selection mode and redraw the scene. When you're in selection mode, the contents of the framebuffer doesn't change until you exit selection mode. When you exit selection mode, OpenGL returns a list of the primitives that intersect the viewing volume. A selection hit is caused by intersection between primitive and viewing volume. The list of primitives is actually returned as an array of integers. You construct the name stack by loading names onto it as you issue primitive drawing commands while in selection mode. Thus, when the list of names is returned, you can use it to determine which primitives might have been selected on the screen by the user.

Feedback

Feedback is similar to selection in that once you're in either mode, no pixels are produced and the screen is frozen. Drawing does not occur; instead, information about primitives that would have been rendered is sent back to the application. The key difference between selection and feedback modes is what information is sent back. In feedback mode, information about transformed primitives is sent back to an array of floating-point values. The values sent back to the feedback array consist of tokens that specify what type of primitive (point, line, polygon, image, or bitmap) has been processed and transformed, followed by vertex, color, or other data for that primitive.

Pick ray

Yet another method involves shooting a pick ray through the mouse location and testing for intersections with the currently displayed objects. OpenGL doesn't contain any function for ray intersections. To generate pick ray, you need OpenGL matrix transformation, and some knowledge about linear algebra.

Implementation

The method which I implemented for mouse selection involves projection of small area from the object (primitive) to the screen and testing the mouse click. The code below shows how you can project the object point to the screen.

C++
//Needs to retrieve OpenGL transformation matrices before projection
glGetIntegerv(GL_VIEWPORT, m_spheres->viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, m_spheres->modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, m_spheres->projMatrix);

//Projection 
gluProject(m_spheres->m_xc,m_spheres->m_yc,
        m_spheres->m_zc,m_spheres->modelMatrix, 
        m_spheres->projMatrix,m_spheres->viewport,
        &m_spheres->winx,&y,&m_spheres->winz);
m_spheres->winy=m_spheres->viewport[3] - (GLint) y - 1;

Every shape object contains projected point and rectangle. When you want to select shape, use the LButtonDown message handler and test its point in rectangle. The code below shows the test for Sphere object.

C++
void CMyView::OnLButtonDown(UINT nFlags, CPoint point) 
{
    m_LeftButtonDown = TRUE;
    m_LeftDownPos = point;
    SetCapture();

    CMyDoc* pDoc = (CMyDoc*)GetDocument();
    ASSERT(pDoc);
    CTypedPtrList<CObList,CSphere*>& sphereList =pDoc->m_SphereList;
    POSITION pos = sphereList.GetHeadPosition();
    while (pos != NULL)
    {
        CSphere* spheres = sphereList.GetNext(pos);
        spheres->m_Select=FALSE;
        if(spheres->GetRect().PtInRect(point))
        {
            m_sph=spheres;
            m_sph->m_Select=TRUE;
        }
    }

    Invalidate();
    CView::OnLButtonDown(nFlags, point);
}

Summary

The problem of the implementation is how much can be the projected area of the object. If you set projected area too big, it will be possible that two different areas can be merged. If projected area is too small it's hard to pick it with the mouse.

References

  1. OpenGL Programming Guide The Official Guide to Learning OpenGL, Version 1.1
  2. Open GL Super Bible (Publisher: Macmillan Computer Publishing) Author(s): Waite group Press ISBN: 1571690735 Publication date: 08/01/96

License

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


Written By
Software Developer (Senior)
Bosnia and Herzegovina Bosnia and Herzegovina
Bahrudin Hrnjica holds a Ph.D. degree in Technical Science/Engineering from University in Bihać.
Besides teaching at University, he is in the software industry for more than two decades, focusing on development technologies e.g. .NET, Visual Studio, Desktop/Web/Cloud solutions.

He works on the development and application of different ML algorithms. In the development of ML-oriented solutions and modeling, he has more than 10 years of experience. His field of interest is also the development of predictive models with the ML.NET and Keras, but also actively develop two ML-based .NET open source projects: GPdotNET-genetic programming tool and ANNdotNET - deep learning tool on .NET platform. He works in multidisciplinary teams with the mission of optimizing and selecting the ML algorithms to build ML models.

He is the author of several books, and many online articles, writes a blog at http://bhrnjica.net, regularly holds lectures at local and regional conferences, User groups and Code Camp gatherings, and is also the founder of the Bihac Developer Meetup Group. Microsoft recognizes his work and awarded him with the prestigious Microsoft MVP title for the first time in 2011, which he still holds today.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Mohamed Aissiou21-Dec-12 20:24
Mohamed Aissiou21-Dec-12 20:24 
Generalabout gluUnProject Pin
feifly26-Apr-10 16:02
feifly26-Apr-10 16:02 
Questioni want help about mousesel project Pin
suuunil25-May-09 19:18
suuunil25-May-09 19:18 
GeneralGood Job~! Pin
Watson Jason29-Apr-09 23:11
Watson Jason29-Apr-09 23:11 
Questionanother way? Pin
Porolfi4-Jun-07 22:31
Porolfi4-Jun-07 22:31 
AnswerRe: another way? Pin
Porolfi5-Jun-07 0:55
Porolfi5-Jun-07 0:55 
Questionhow about gluUnProject Pin
Nigel Atkinson11-Apr-05 16:26
Nigel Atkinson11-Apr-05 16:26 
AnswerRe: how about gluUnProject Pin
Bahrudin Hrnjica13-Apr-05 20:02
professionalBahrudin Hrnjica13-Apr-05 20:02 
GeneralRe: how about gluUnProject Pin
Nigel Atkinson14-Apr-05 17:47
Nigel Atkinson14-Apr-05 17:47 
You could support both ways of selection by doing the following:

If the user does a click-drag, use the start and end points of the drag to define a rect and select every thing inside.

If the user simply clicks, do the same except use the x,y from the mouse click as the centre of the rect and make the rect a certain size. This size could be hard coded or even user selectable.

I've done some experimenting with using gluUnProject now, and found a catch, although a minor one. You have to make sure that when you grab the model view matrix, that it has been transformed in the same way as the view you are dealing with. Ie I had setup to draw a cube after glTranslatef( -70.0, 0, 0 ); This ment that when I used gluUnProject to convert the mouse co-ords, I had to do a glTranslatef( -70.0, 0, 0 ); before retreiving the model view matrix.

Other than that is works very well for what I want to do.;)

"Land a'hoy!" * CRASH * "I should av said that sooner eh?" - Eckles, The Goon Show
GeneralRe: how about gluUnProject Pin
Bahrudin Hrnjica17-Apr-05 19:52
professionalBahrudin Hrnjica17-Apr-05 19:52 
GeneralFinishing the project in VC6? Thank you very much! Pin
aqing19-Jun-04 18:57
aqing19-Jun-04 18:57 
GeneralRe: Finishing the project in VC6? Thank you very much! Pin
Bahrudin Hrnjica20-Jun-04 7:45
professionalBahrudin Hrnjica20-Jun-04 7:45 
GeneralRe: Finishing the project in VC6? Thank you very much! Pin
aqing20-Jun-04 16:51
aqing20-Jun-04 16:51 
GeneralRe: Finishing the project in VC6? Thank you very much! Pin
Anonymous21-Jun-04 2:34
Anonymous21-Jun-04 2:34 
GeneralRe: Finishing the project in VC6? Thank you very much! Pin
aqing25-Jun-04 20:48
aqing25-Jun-04 20:48 
Generalfile not found Pin
gok16-Feb-05 19:33
professionalgok16-Feb-05 19:33 
GeneralProblem existing after converting the code form the .NET to VC6 by prjconverter Pin
aqing31-May-04 22:23
aqing31-May-04 22:23 
GeneralRe: Problem existing after converting the code form the .NET to VC6 by prjconverter Pin
Bahrudin Hrnjica1-Jun-04 2:26
professionalBahrudin Hrnjica1-Jun-04 2:26 
GeneralRe: Problem existing after converting the code form the .NET to VC6 by prjconverter Pin
Nigel Atkinson11-Apr-05 16:42
Nigel Atkinson11-Apr-05 16:42 
QuestionHow to run 2 different(or same) OpenGL objects in one DialogBox? Pin
werter13-May-04 21:17
werter13-May-04 21:17 
AnswerRe: How to run 2 different(or same) OpenGL objects in one DialogBox? Pin
Bahrudin Hrnjica25-May-04 9:54
professionalBahrudin Hrnjica25-May-04 9:54 
GeneralOpenGL + JAI / JAVA Pin
prabu_univ12-Apr-04 2:10
prabu_univ12-Apr-04 2:10 
Questionhow to run i t Pin
wjiybb25-Nov-03 20:21
wjiybb25-Nov-03 20:21 
AnswerRe: how to run i t Pin
Bahrudin Hrnjica26-Nov-03 11:22
professionalBahrudin Hrnjica26-Nov-03 11:22 
GeneralRe: how to run i t Pin
infinitecmdz23-Oct-06 22:20
infinitecmdz23-Oct-06 22:20 

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

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