in reply to Perl and OpenGL object selection

The OpenGL bindings in the SDL_perl version 1 branch work; I've had success here.

If you try them, make sure that you're converting between SDL and OpenGL coordinate systems appropriately. The origin for SDL is in the upper left while the origin for OpenGL is in the lower left. (That may be backwards, but the point is that they don't agree.)

Replies are listed 'Best First'.
Re^2: Perl and OpenGL object selection
by Anonymous Monk on Feb 11, 2006 at 22:11 UTC
    I could not use the SDL openGL libary as it has no gluProject function somehow... Or am I wrong? What do you mean by success with the module? Did you do this object selection somehow? If yes let me know how?

      I didn't use gluProject(), I just rendered the selectable objects in select and projection modes and set a pick matrix of four by four pixels around the cursor, setting a new unique ID for each object. After that, if you call glRenderMode() with GL_RENDER, you get back an array of selected ids.

      It's pretty straightforward in the red book.

        Dear Chromatic,
        After a few week struggling you seem to be the only man on Earth who is aware of the picking technique in perl. I tried everything, the farest point I was able to get to is that my code syntactically seems to be good but does not work anyhow. I even returned to OpenGL module as I can not find functions is sdl::opengl, but it did not help on the problem. Please somehow help me: one possible method if I could see your working code and try to do the rest of myself, the other possibility would be if you take a glance on my false working code and make some remarks. What should I do?
        heres is the not working code:
        #!/usr/bin/perl # This example exists in three different versions, # one using OpenGL.pm # one using SDL::OpenGL # one using PDL::Graphics::OpenGL (this one) # It's main purpose is to show how different OpenGL-implementations in + perl # differ. #use strict; use Gtk2 '-init'; use Gtk2::GLExt; #use PDL::Graphics::OpenGL; #use SDL::OpenGL; use OpenGL qw/:all/; # this is nothing, a better example should be created! my $length = 20; my $width = 12; my $height = 8; my $room_rot=0; # a 3ds lista elkeszitese draw(); main(); sub main { my $glconfig; my $window; my $vbox; my $drawing_area; my $button; # Init GtkGLExt. Gtk2::GLExt->init; # Try double-buffered visual $glconfig = Gtk2::Gdk::GLExt::Config->new_by_mode(['rgb', 'depth', + 'double']); unless( $glconfig ) { print "*** Cannot find the double-buffered visual.\n"; print "*** Trying single-buffered visual.\n"; # Try single-buffered visual $glconfig = Gtk2::Gdk::GLExt::Config->new_by_mode(['rgb', 'dep +th']); unless( $glconfig ) { print "*** No appropriate OpenGL-capable " ." visual found.\n"; exit 1; } } # Top-level window. $window = Gtk2::Window->new; $window->set_title ("Reflections"); # Perform the resizes immediately if on win32 $window->set_resize_mode ('immediate') if( $^O eq 'MSWin32' ); # Get automatically redrawn if any of their children changed alloc +ation. $window->set_reallocate_redraws (1); $window->signal_connect (delete_event => sub { Gtk2->main_quit; 1} +); # VBox. $vbox = Gtk2::VBox->new (0, 0); $window->add($vbox); $vbox->show; # Drawing area for drawing OpenGL scene. $drawing_area = Gtk2::DrawingArea->new (); $drawing_area->set_size_request (640, 512); # Set OpenGL-capability to the widget. $drawing_area->set_gl_capability ($glconfig, undef, 1, 'rgba-type' +); $drawing_area->signal_connect_after (realize => \&realize); $vbox->pack_start ($drawing_area, 1, 1, 0); $drawing_area->show; # Simple quit button. $button = Gtk2::Button->new ("_Quit"); $button->signal_connect (clicked => sub { #for the quit button, the hit check is examined pickSquares(); #Gtk2->main_quit; }); $vbox->pack_start ($button, 0, 0, 0); $button->show; # Show window. $window->show; Glib::Timeout->add( 30, \&draw_scene, $drawing_area ); # Main loop. Gtk2->main; return 0; } sub realize { my $widget = shift; my $data = shift; my $glcontext = $widget->get_gl_context; my $gldrawable = $widget->get_gl_drawable; # OpenGL BEGIN return unless( $gldrawable->gl_begin ($glcontext) ); my @LightAmbient = ( 0.5, 0.5, 0.5, 1.0 ); my @LightDiffuse = ( 1.0, 1.0, 1.0, 1.0 ); my @LightPosition = ( 0.0, 0.0, 2.0, 1.0 ); my $alloc = $widget->allocation; glViewport(0, 0, $alloc->width, $alloc->height); glShadeModel(GL_SMOOTH); glClearColor(0, 0, 0, 0); glClearDepth(1.0); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glLightfv_p(GL_LIGHT1, GL_AMBIENT, @LightAmbient); glLightfv_p(GL_LIGHT1, GL_DIFFUSE, @LightDiffuse); glLightfv_p(GL_LIGHT1, GL_POSITION, @LightPosition); glEnable(GL_LIGHT1); glPolygonMode( GL_BACK, GL_FILL ); glPolygonMode( GL_FRONT, GL_LINE ); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0,$alloc->width/$alloc->height,0.1,500.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); draw("GL_RENDER"); $gldrawable->gl_end; # OpenGL END } sub pickSquares() { my $BUFSIZE=100; my @selectBuf=(); my $hits; my @viewport=(); my $x, $y; $x = 100; #these would be the mouse coordinates once $y = 100; @viewport=OpenGL::glGetIntegerv_p(GL_VIEWPORT); glSelectBuffer_c($BUFSIZE, $selectBuf); glRenderMode(GL_SELECT); glInitNames(); glPushName(-1); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); #/* create 5x5 pixel picking region near cursor location */ gluPickMatrix_p($x, ($viewport[3] - $y), 5.0, 5.0, @viewport); gluOrtho2D(0.0, 3.0, 0.0, 3.0); draw("GL_SELECT"); glPopMatrix(); glFlush(); $hits = glRenderMode(GL_RENDER); processHits ($hits, @selectBuf); # glutPostRedisplay(); } sub processHits { my ($hits, @buffer)=@_; my $i, $j; printf ("hits = %d\n", $hits); for ($i = 0; $i < $hits; $i++) { #/* for each hit */ printf (" number of names for this hit = %d\n", $buffer[$i]); printf ("\n"); } } # The main drawing function. sub draw_scene { my $widget = shift; my $glcontext = $widget->get_gl_context; my $gldrawable = $widget->get_gl_drawable; # OpenGL BEGIN return unless( $gldrawable->gl_begin ($glcontext) ); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslated(0, 0, -100); glRotated($room_rot, 0, 1, 0); glCallList($graphic); $room_rot += 0.5; if( $gldrawable->is_double_buffered ) {$gldrawable->swap_buffer +s;} else {glFlush();} $gldrawable->gl_end; 1; } sub draw { my $mode=shift; $graphic = glGenLists(1); glNewList($graphic, GL_COMPILE); if ($mode eq "GL_SELECT") {glLoadName(1);} glTranslated(0, 0, 10); Gtk2::Gdk::GLExt::Shapes->draw_sphere (1, 3, 10,10); glEndList(); #glPopName(); }
        Ok, thanx, I will try it out and if something fails I ask again. Thanks again!