Results 1 to 7 of 7
  1. #1
    Join Date
    Oct 2010
    Posts
    3

    Question C++ Object Picking w/ OpenGL

    While following the C++ openGL VTMs (Selecting and Deleting Objects), I've encountered an error with 3d object picking, that I cannot seem to nail down. The issue seems to be triggered as soon as I change the glRenderMode to GL_SELECT. Even totally stripped out, switching to GL_SELECT, and back to GL_RENDERER triggers an error in the back end c++ code. (like mlock.c, or other default locked files) The errors it spits out are inconsistant as well. Usually, I get something like this:

    Code:
    First-chance exception at 0x77dcea16 in SDL_Demo.exe: 0xC0000005: Access violation writing location 0x7ffffb94.
    Unhandled exception at 0x77dcea16 in SDL_Demo.exe: 0xC0000005: Access violation writing location 0x7ffffb94.
    I'm not sure if it's relevant, but I'm running windows 7, 64bit. Visual Studio 2010. Any help at all would be great. I've been stuck on this issue for about a week now, and I'm totally out of ideas.

    Here is the code to the mouse click handling:
    Code:
    void handleSelections(void)
    {
    	static bool buttonDown = false;
    
    	if( state.MiddleButtonDown )
    		buttonDown = true;
    	else if ( buttonDown )
    	{
    		buttonDown = false;
    
    		//a click
    		GLuint buffer[512];
    		GLint viewport[4];
    	
    		//set up the selection viewport
    		glGetIntegerv(GL_VIEWPORT, viewport);
    		glSelectBuffer(512, buffer);
    
    		//for debugging purposes, just toggle the glRenderMode
    		
    		glRenderMode(GL_SELECT);		//If I remove this line, the program runs fine.
    		glRenderMode(GL_RENDERER);
    	}
    }

  2. #2
    Join Date
    Jul 2008
    Location
    Portsmouth, England
    Posts
    436
    Are you absolutely certain it's crashing on that line and not some time after? Picking using this method is known to be broken in a lot of OpenGL implementations and it's no longer the recommended way to implement picking in 3D applications, so that could be your problem: the OpenGL driver is just bugged for that functionality.

    If it's crashing some time after when you're actually making draw calls, it'll be because your variable buffer is a local variable so it doesn't exist when you get round to actually doing the rendering.

  3. #3
    Join Date
    Oct 2010
    Posts
    3
    Thanks, yes, it crashes after, during the draw calls. I'll change the variable scope, and let you know how it goes.

    You mentioned that this is no longer the recommended way to implement picking. What is the preferred way?

  4. #4
    Join Date
    Jul 2008
    Location
    Portsmouth, England
    Posts
    436
    The usual way is to render the scene to an off-screen render target but with all lighting/textures, etc disabled and just assigning a unique colour to each object. Then you look at what the color is at the location under the mouse pointer.

    For efficiency, if you are updating the scene every frame (e.g. in a game) then rather than rendering the complete scene at the same resolution as the screen you define a custom view transform that represents the 8x8 pixels (or whatever) closest to the mouse pointer's location on that frame. This is quite an advanced topic, but you get the idea.

  5. #5
    Join Date
    Jun 2003
    Location
    Trier, Germany
    Posts
    1,350
    I'm tempted to also blame the driver. AMD/ATI cards are particularly well-known for not supporting this properly, so even if you get it to work on your machine, it's likely to fail on others.

    Quote Originally Posted by Donutfiend84 View Post
    What is the preferred way?
    Do the whole thing by hand, in software. This can be a little tricky to get right at first (and really tricky to get fast), but that's just how it is.
    Basically you'll need to do a back-projection, transforming the 2d-point covered by the mouse cursor in screen space into a ray in world space. gluUnproject can help with this, but you can just as easily do the whole thing yourself.
    The result of the back projection is a ray with the origin at the cursor's position in the screen plane and the direction parallel to the camera's view vector. You then compute a ray-triangle intersection against all faces that you consider valid for picking. It's not too different from writing a primitive ray-caster.

    The main performance hit here is digging through all the geometry data, so you will need some kind of acceleration structure to make this reasonably fast for larger scenes. A BVH may be the best tool here, although an Octree will imho be easier to implement and still give good performance.

    If you plan to implement this, don't worry about the speed for now. Make sure you get it right with a brute-force approach, and only address the speed problems afterwards if you're really into it. Writing your first acceleration structure can be a frustrating experience, as they are very difficult to debug, so you don't want to start this project without the proper motivation.

    edit: just read rhm's reply. that is of course a valid alternative, although it has its drawbacks. it's probably easier to implement though, so if you want to avoid digging into the details of the transformation pipeline, you should go with that.
    Last edited by ComicSansMS; 02-22-2012 at 05:44 PM.

  6. #6
    Join Date
    Aug 2004
    Location
    little rock arkansas
    Posts
    3,482
    in your code i do not see the line

    glInitNames();

    that should come before
    glRenderMode(GL_RENDERER);

    i have the picking code from the videos and it works fine for me , you may want to re-watch the video to see what you may have missed in the code
    ME WANT AGENTS ME WANT AGENTS ME WANT AGENTS

  7. #7
    Join Date
    Oct 2010
    Posts
    3
    Thanks everyone for your help. I changed the variable scope, and that solved the crashing problem, however the display locks up on me. It's strange, because my code all continues to run, but the screen simply stops updating.

    Quote Originally Posted by ostamo2
    in your code i do not see the line

    glInitNames();
    You are correct. What I posted up there was from the video code, but while I was debugging, I slowly pulled out things one line at a time, trying to locate what was causing the error. I did add that line back in (as well as the rest of the video code) but the current issue (display locks up) does not seem to be related, since adding back the old code, did not change the functionality at all.

    Since this type of picking is known to cause issues, I'm going to start trying out a few other ways to do this. I found some examples in the opengl spec documents: http://www.opengl.org/resources/faq/.../selection.htm, but I also like you ideas, so I'll give them a go as well. Thanks again for all your help.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •