Click here to Skip to main content
Click here to Skip to main content

Mouse Selection in OpenGL Scene

By , 25 Oct 2002
 

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.

 
//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.

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)

About the Author

Bahrudin Hrnjica
Software Developer (Senior)
Bosnia And Herzegovina Bosnia And Herzegovina
Member
Senior Software Developer and Microsoft MVP for Visual C#.

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

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberMohamed Aissiou21 Dec '12 - 20:24 
Very clear and nice algorithm Mr. Hrnjica
Generalabout gluUnProjectmemberfeifly26 Apr '10 - 16:02 
Could you give me a example of translation from 2-dimension to 3-dimension?
Questioni want help about mousesel projectmembersuuunil25 May '09 - 19:18 
if we want to change a project little bit.like adding a new menu ,adding new items.and how to give the functionalities to the menu. plese help me................ :(
GeneralGood Job~!memberdefineconst29 Apr '09 - 23:11 
Good Job~!   A Dream About Software。
Questionanother way?memberPorolfi4 Jun '07 - 22:31 
Hi, I've just started looking for a simple API to do some 3D rendering. Accepting user input is a requirement as well. OpenGL seems OK, but I'm wondering if there is a simpler way to do object picking. I think the renderer could maintain a buffer that stores an 'object ID' (supplied at runtime...
AnswerRe: another way?memberPorolfi5 Jun '07 - 0:55 
Hmmm pushing object names before rendering in selection mode is something like I wanted
Questionhow about gluUnProjectmemberMerlinblack11 Apr '05 - 16:26 
I've been looking at something similar. I was thinking of doing this.   1. Get a bounding rectangle from the user ie click-drag, so I have two 2d points in window co-ords. 2. Give both points z co-ords, the first with the smallest possible z and the other with the biggest. 3. Use...
AnswerRe: how about gluUnProjectmemberBahrudin Hrnjica13 Apr '05 - 20:02 
Yes, your solution is very simple and claer. The problem is in picking the object instead of selecting.   You have to select object with one mouse point not with two.   The goal of my article picking objects with mouse.   All in all the solution is very good. Thank you for...
GeneralRe: how about gluUnProjectmemberMerlinblack14 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...
GeneralRe: how about gluUnProjectmemberBahrudin Hrnjica17 Apr '05 - 19:52 
God idea, i will try to implement both solutions. thank you
GeneralFinishing the project in VC6? Thank you very much!memberaqing19 Jun '04 - 18:57 
dear Bahrudin Hrnjica , Thanking for your finishing the projects!
GeneralRe: Finishing the project in VC6? Thank you very much!memberBahrudin Hrnjica20 Jun '04 - 7:45 
Now, the project can be compiled bith VC6 and VC7   Click link below and choose: Mouse Selection in OpenGL Scene   http://www.baha.dreamstation.com/download.htm   Regards   -- modified at 15:44 Friday 14th April, 2006
GeneralRe: Finishing the project in VC6? Thank you very much!memberaqing20 Jun '04 - 16:51 
Thank you for answering the message. But I can't open the link above. I am sorry that you could provide other links . Thank you!   Regards
GeneralRe: Finishing the project in VC6? Thank you very much!sussAnonymous21 Jun '04 - 2:34 
From me its Ok, but try this: http://www.baha.dreamstation.com/Articles/mouseselection.html[^]   The article is updated! regards
GeneralRe: Finishing the project in VC6? Thank you very much!memberaqing25 Jun '04 - 20:48 
Sorry, I can not open the sitev... Something is wrong in link?
Generalfile not foundmembergok16 Feb '05 - 19:33 
File Not Found!   The file you are searching for is not located on our servers. Please check your spelling. File names may be case sensitive. Please verify the URL as this is the most common reason for this error.     Gennady
GeneralProblem existing after converting the code form the .NET to VC6 by prjconvertermemberaqing31 May '04 - 22:23 
As you suggested ,I converted the code form the .NET to the VC6,but so disappointed it didn't work .There exist the macro errors, VC6 said, as follows: -------------------------------------------------------------------------- error C2039: 'classCShape' : is not a member of 'CShape' ...
GeneralRe: Problem existing after converting the code form the .NET to VC6 by prjconvertermemberBahrudin Hrnjica1 Jun '04 - 2:26 
I will update the article to support both VC6 and VC7, soon.   regards
GeneralRe: Problem existing after converting the code form the .NET to VC6 by prjconvertermemberMerlinblack11 Apr '05 - 16:42 
Was something to do with missing IMPLEMENT_DYNAMIC etc. Unfortunatly I've forgoten where I added it. Some where in either CShape or CSphere.   "Land a'hoy!" * CRASH * "I should av said that sooner eh?" - Eckles, The Goon Show
QuestionHow to run 2 different(or same) OpenGL objects in one DialogBox?memberwerter13 May '04 - 21:17 
How to run 2 different(or same) OpenGL objects in one DialogBox? IDC_STATIC1 is a first OpenGL objects Scene window. IDC_STATIC2 is a second OpenGL objects Scene window. IDC_STATIC1 and IDC_STATIC2 ,they are placed on IDD_DIALOG1.   code: pclStatic = (CStatic...
AnswerRe: How to run 2 different(or same) OpenGL objects in one DialogBox?memberBahrudin Hrnjica25 May '04 - 9:54 
You have to create two thread, in each thred place one scene. For more info about Multithreaded programming see http://www.codeproject.com/threads/.   regards
GeneralOpenGL + JAI / JAVAmemberprabu_univ12 Apr '04 - 2:10 
i like to know how to connect openGL with java using JNI and i like to develop one 3D visualization og digital image..so any one knows about this reply...
Questionhow to run i tmemberwjiybb25 Nov '03 - 20:21 
I have downloaded the resource files, but it is writen under vc.net. I am using vc++6.0, how can do it?
AnswerRe: how to run i tmemberBahrudin Hrnjica26 Nov '03 - 11:22 
You can use http://www.codeproject.com/tools/prjconverter.asp project converter, to convert VC NET project to VC 6.  
GeneralRe: how to run i tmemberinfinitecmdz23 Oct '06 - 22:20 
Use the link in the in the previous posts to convert it to VS6.0 and then comment IMPLEMENT_SERIAL and DECLARE_SERIAL in the Sphere.h and Sphere.cpp..These are needed only for serialization. Then go to Project, Settings, link , Object/Library modules and add : opengl32.lib, glut32.lib and...

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 26 Oct 2002
Article Copyright 2002 by Bahrudin Hrnjica
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid