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();
}
| [reply] [d/l] |