[GtkGLExt] 3d object picking help please



Dear All,
I am struggling for about a week with doing a simple working
perl program where 3d object can be picked with mouse. I try
to use this module abnd my initial point was an example
shipped with the source files but always got stuck with some
problem. 
Don't you have accidentally a working example which do this
picking thing which you can send me? I would be a great help
for me!!! Please-please!!! I can hardly find any opengl-perl
tutorial and example mainly in this picking topic... 
 
Thanks a lot in advance!
 
Regards,
Geza Szabo

Here is the code I have now, which should be theoritically
working (accordingn to the opengl red book) but after the
picking my objects are not redrawn, and I think that picking
do not works correctly. How should I fix it?

------------------------------------------------------
#!/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',
'depth']);

		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 allocation.
	$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_buffers;}
	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();
}



___________________________________________________________________________
[origo] klikkbank lakossági számlacsomag havi 199 Ft-ért, bankkártya éves díj nélkül!
www.klikkbank.hu





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]