diff options
Diffstat (limited to 'PerlQt/examples/opengl')
-rw-r--r-- | PerlQt/examples/opengl/README | 12 | ||||
-rw-r--r-- | PerlQt/examples/opengl/box/GLBox.pm | 149 | ||||
-rw-r--r-- | PerlQt/examples/opengl/box/glbox | 90 | ||||
-rw-r--r-- | PerlQt/examples/opengl/gear/gear | 267 |
4 files changed, 518 insertions, 0 deletions
diff --git a/PerlQt/examples/opengl/README b/PerlQt/examples/opengl/README new file mode 100644 index 0000000..5c93086 --- /dev/null +++ b/PerlQt/examples/opengl/README @@ -0,0 +1,12 @@ +Before you can run the OpenGL examples, you need to install +the OpenGL module available on CPAN (http://www.cpan.org) + +Latest version is 0.54, as of 09/11/02 + +Both Smoke and Qt must also have been compiled with OpenGL support. + +If your Qt library has OpenGL support but PerlQt complains about lacking + methods or classes, check ./configure's config.log file for any +error that might have occured while detecting your OpenGL settings. + +You might also want to check if OpenGL is properly installed on your system. diff --git a/PerlQt/examples/opengl/box/GLBox.pm b/PerlQt/examples/opengl/box/GLBox.pm new file mode 100644 index 0000000..dd6ceb9 --- /dev/null +++ b/PerlQt/examples/opengl/box/GLBox.pm @@ -0,0 +1,149 @@ +package GLBox; + +use OpenGL qw(:all); + +use strict; + +use Qt; +use Qt::isa qw(Qt::GLWidget); +use Qt::slots + setXRotation => ['int'], + setYRotation => ['int'], + setZRotation => ['int']; +use Qt::attributes qw( + xRot + yRot + zRot + scale + object + list +); + +sub NEW { + shift->SUPER::NEW(@_); + xRot = yRot = zRot = 0.0; + scale = 1.25; + object = undef; +} + +sub paintGL +{ + glClear( GL_COLOR_BUFFER_BIT ); + glClear( GL_DEPTH_BUFFER_BIT ); + + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -10.0 ); + glScalef( scale, scale, scale ); + + glRotatef( xRot, 1.0, 0.0, 0.0 ); + glRotatef( yRot, 0.0, 1.0, 0.0 ); + glRotatef( zRot, 0.0, 0.0, 1.0 ); + + glCallList( object ); +} + +sub initializeGL +{ + qglClearColor( &black ); # Let OpenGL clear to black + object = makeObject(); # Generate an OpenGL display list + glShadeModel( GL_FLAT ); + glEnable( GL_DEPTH_TEST ); +} + +# Set up the OpenGL view port, matrix mode, etc. + +sub resizeGL +{ + my $w = shift; + my $h = shift; + glViewport( 0, 0, $w, $h ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 ); + glMatrixMode( GL_MODELVIEW ); +} + +# Generate an OpenGL display list for the object to be shown, i.e. the box + +sub makeObject +{ + my $list = glGenLists( 1 ); + + glNewList( $list, GL_COMPILE ); + + qglColor( &darkGreen ); # Shorthand for glColor3f or glIndex + + glLineWidth( 2.0 ); + + glBegin( GL_QUADS ); + glVertex3f( 1.0, 0.5, -0.4 ); + glVertex3f( 1.0, -0.5, -0.4 ); + glVertex3f( -1.0, -0.5, -0.4 ); + glVertex3f( -1.0, 0.5, -0.4 ); + glEnd(); + + qglColor( &blue ); + + glBegin( GL_QUADS ); + glVertex3f( 1.0, 0.5, 0.4 ); + glVertex3f( 1.0, -0.5, 0.4 ); + glVertex3f( -1.0, -0.5, 0.4 ); + glVertex3f( -1.0, 0.5, 0.4 ); + glEnd(); + + qglColor( &darkRed ); + + glBegin( GL_QUAD_STRIP ); + glVertex3f( 1.0, 0.5, -0.4 ); glVertex3f( 1.0, 0.5, 0.4 ); + glVertex3f( 1.0, -0.5, -0.4 ); glVertex3f( 1.0, -0.5, 0.4 ); + qglColor( &yellow ); + glVertex3f( -1.0, -0.5, -0.4 ); glVertex3f( -1.0, -0.5, 0.4 ); + qglColor( &green ); + glVertex3f( -1.0, 0.5, -0.4 ); glVertex3f( -1.0, 0.5, 0.4 ); + qglColor( &lightGray ); + glVertex3f( 1.0, 0.5, -0.4 ); glVertex3f( 1.0, 0.5, 0.4 ); + glEnd(); + + glEndList(); + + return $list; +} + + + +# Set the rotation angle of the object to \e degrees around the X axis. + +sub setXRotation +{ + my $deg = shift; + xRot = $deg % 360; + updateGL(); +} + + +# Set the rotation angle of the object to \e degrees around the Y axis. + +sub setYRotation +{ + my $deg = shift; + yRot = $deg % 360; + updateGL(); +} + + +# Set the rotation angle of the object to \e degrees around the Z axis. + +sub setZRotation +{ + my $deg = shift; + zRot = $deg % 360; + updateGL(); +} + +sub DESTROY +{ +# makeCurrent(); + glDeleteLists( object, 1 ); +} + +1; diff --git a/PerlQt/examples/opengl/box/glbox b/PerlQt/examples/opengl/box/glbox new file mode 100644 index 0000000..613a274 --- /dev/null +++ b/PerlQt/examples/opengl/box/glbox @@ -0,0 +1,90 @@ + +package GLObjectWindow; + +use strict; + +use Qt; +use Qt::isa qw(Qt::Widget); +use Qt::attributes qw( + file + frame + menu + box + xpos + ypos + zpos +); + +use GLBox; + +sub NEW +{ + shift->SUPER::NEW(@_); + + # Create a menu + file = Qt::PopupMenu( this ); + file->insertItem( "Exit", Qt::app(), SLOT 'quit()', Qt::KeySequence(int &CTRL + &Key_Q )); + + # Create a menu bar + menu = Qt::MenuBar( this ); + menu->setSeparator( &Qt::MenuBar::InWindowsStyle ); + menu->insertItem("&File", file ); + + # Create a nice frame to put around the OpenGL widget + frame = Qt::Frame( this, "frame" ); + frame->setFrameStyle( &Qt::Frame::Sunken | &Qt::Frame::Panel ); + frame->setLineWidth( 2 ); + + # Create our OpenGL widget + box = GLBox( frame, "glbox"); + + # Create the three sliders; one for each rotation axis + xpos = Qt::Slider ( 0, 360, 60, 0, &Qt::Slider::Vertical, this, "xsl" ); + xpos->setTickmarks( &Qt::Slider::Left ); + Qt::Object::connect( xpos, SIGNAL 'valueChanged(int)', box, SLOT 'setXRotation(int)' ); + + ypos = Qt::Slider ( 0, 360, 60, 0, &Qt::Slider::Vertical, this, "ysl" ); + ypos->setTickmarks( &Qt::Slider::Left ); + Qt::Object::connect( ypos, SIGNAL 'valueChanged(int)', box, SLOT 'setYRotation(int)' ); + + zpos = Qt::Slider ( 0, 360, 60, 0, &Qt::Slider::Vertical, this, "zsl" ); + zpos->setTickmarks( &Qt::Slider::Left ); + Qt::Object::connect( zpos, SIGNAL 'valueChanged(int)', box, SLOT 'setZRotation(int)' ); + + + # Now that we have all the widgets, put them into a nice layout + + # Put the sliders on top of each other + my $vlayout = Qt::VBoxLayout( 20, "vlayout"); + $vlayout->addWidget( xpos ); + $vlayout->addWidget( ypos ); + $vlayout->addWidget( zpos ); + + # Put the GL widget inside the frame + my $flayout = Qt::HBoxLayout( frame, 2, 2, "flayout"); + $flayout->addWidget( box, 1 ); + + # Top level layout, puts the sliders to the left of the frame/GL widget + my $hlayout = Qt::HBoxLayout( this, 20, 20, "hlayout"); + $hlayout->setMenuBar( menu ); + $hlayout->addLayout( $vlayout ); + $hlayout->addWidget( frame, 1 ); +} + +1; + +package main; + +use Qt; +use GLObjectWindow; + +my $a = Qt::Application(\@ARGV); + +my $w = GLObjectWindow; +$w->resize(350,350); +$w->show; + +$a->setMainWidget( $w); + +exit $a->exec; + diff --git a/PerlQt/examples/opengl/gear/gear b/PerlQt/examples/opengl/gear/gear new file mode 100644 index 0000000..2edc951 --- /dev/null +++ b/PerlQt/examples/opengl/gear/gear @@ -0,0 +1,267 @@ +#!/usr/bin/perl -w +# +# Draws a gear. +# +# This code is originally from Qt-1.44, by Troll Tech +# +# Portions of this code have been borrowed from Brian Paul's Mesa +# distribution. +# + +package GearWidget; +use OpenGL qw(:all); + +use Qt; +use Qt::attributes qw( + gear1 + gear2 + gear3 + view_rotx + view_roty + view_rotz + angle +); + +use Qt::isa qw(Qt::GLWidget); + +# +# Draw a gear wheel. You'll probably want to call this function when +# building a display list since we do a lot of trig here. +# +# Input: inner_radius - radius of hole at center +# outer_radius - radius at center of teeth +# width - width of gear +# teeth - number of teeth +# tooth_depth - depth of tooth +# + +sub gear { + my($inner_radius, $outer_radius, $width, $teeth, $tooth_depth) = @_; + my $i; + my($r0, $r1, $r2); + my($angle, $da); + my($u, $v, $len); + + $r0 = $inner_radius; + $r1 = $outer_radius - $tooth_depth/2.0; + $r2 = $outer_radius + $tooth_depth/2.0; + + my $pi = 3.141592654; + $da = 2.0*$pi / $teeth / 4.0; + + glShadeModel(GL_FLAT); + + glNormal3f(0.0, 0.0, 1.0); + + # draw front face + glBegin(GL_QUAD_STRIP); + for $i (0 .. $teeth) { + $angle = $i * 2.0*$pi / $teeth; + glVertex3f($r0*cos($angle), $r0*sin($angle), $width*0.5); + glVertex3f($r1*cos($angle), $r1*sin($angle), $width*0.5); + glVertex3f($r0*cos($angle), $r0*sin($angle), $width*0.5); + glVertex3f($r1*cos($angle+3*$da), $r1*sin($angle+3*$da), $width*0.5); + } + glEnd(); + + # draw front sides of teeth + glBegin(GL_QUADS); + $da = 2.0*$pi / $teeth / 4.0; + for $i (0 .. $teeth-1) { + $angle = $i * 2.0*$pi / $teeth; + + glVertex3f($r1*cos($angle), $r1*sin($angle), $width*0.5); + glVertex3f($r2*cos($angle+$da), $r2*sin($angle+$da), $width*0.5); + glVertex3f($r2*cos($angle+2*$da), $r2*sin($angle+2*$da), $width*0.5); + glVertex3f($r1*cos($angle+3*$da), $r1*sin($angle+3*$da), $width*0.5); + } + glEnd(); + + + glNormal3f(0.0, 0.0, -1.0); + + # draw back face + glBegin(GL_QUAD_STRIP); + for $i (0 .. $teeth) { + $angle = $i * 2.0*$pi / $teeth; + glVertex3f($r1*cos($angle), $r1*sin($angle), -$width*0.5); + glVertex3f($r0*cos($angle), $r0*sin($angle), -$width*0.5); + glVertex3f($r1*cos($angle+3*$da), $r1*sin($angle+3*$da), -$width*0.5); + glVertex3f($r0*cos($angle), $r0*sin($angle), -$width*0.5); + } + glEnd(); + + # draw back sides of teeth + glBegin(GL_QUADS); + $da = 2.0*$pi / $teeth / 4.0; + for $i (0 .. $teeth-1) { + $angle = $i * 2.0*$pi / $teeth; + + glVertex3f($r1*cos($angle+3*$da), $r1*sin($angle+3*$da), -$width*0.5); + glVertex3f($r2*cos($angle+2*$da), $r2*sin($angle+2*$da), -$width*0.5); + glVertex3f($r2*cos($angle+$da), $r2*sin($angle+$da), -$width*0.5); + glVertex3f($r1*cos($angle), $r1*sin($angle), -$width*0.5); + } + glEnd(); + + # draw outward faces of teeth + glBegin(GL_QUAD_STRIP); + for $i (0 .. $teeth-1) { + $angle = $i * 2.0*$pi / $teeth; + + glVertex3f($r1*cos($angle), $r1*sin($angle), $width*0.5); + glVertex3f($r1*cos($angle), $r1*sin($angle), -$width*0.5); + $u = $r2*cos($angle+$da) - $r1*cos($angle); + $v = $r2*sin($angle+$da) - $r1*sin($angle); + $len = sqrt($u*$u + $v*$v); + $u /= $len; + $v /= $len; + glNormal3f($v, -$u, 0.0); + glVertex3f($r2*cos($angle+$da), $r2*sin($angle+$da), $width*0.5); + glVertex3f($r2*cos($angle+$da), $r2*sin($angle+$da), -$width*0.5); + glNormal3f(cos($angle), sin($angle), 0.0); + glVertex3f($r2*cos($angle+2*$da), $r2*sin($angle+2*$da), $width*0.5); + glVertex3f($r2*cos($angle+2*$da), $r2*sin($angle+2*$da), -$width*0.5); + $u = $r1*cos($angle+3*$da) - $r2*cos($angle+2*$da); + $v = $r1*sin($angle+3*$da) - $r2*sin($angle+2*$da); + glNormal3f($v, -$u, 0.0); + glVertex3f($r1*cos($angle+3*$da), $r1*sin($angle+3*$da), $width*0.5); + glVertex3f($r1*cos($angle+3*$da), $r1*sin($angle+3*$da), -$width*0.5); + glNormal3f(cos($angle), sin($angle), 0.0); + } + + glVertex3f($r1*cos(0.0), $r1*sin(0.0), $width*0.5); + glVertex3f($r1*cos(0.0), $r1*sin(0.0), -$width*0.5); + + glEnd(); + + + glShadeModel(GL_SMOOTH); + + # draw inside radius cylinder + glBegin(GL_QUAD_STRIP); + for $i (0 .. $teeth) { + $angle = $i * 2.0*$pi / $teeth; + glNormal3f(-cos($angle), -sin($angle), 0.0); + glVertex3f($r0*cos($angle), $r0*sin($angle), -$width*0.5); + glVertex3f($r0*cos($angle), $r0*sin($angle), $width*0.5); + } + glEnd(); +} + + + +sub draw { + angle += 2.0; + view_roty += 1.0; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(view_rotx, 1.0, 0.0, 0.0); + glRotatef(view_roty, 0.0, 1.0, 0.0); + glRotatef(view_rotz, 0.0, 0.0, 1.0); + + glPushMatrix(); + glTranslatef(-3.0, -2.0, 0.0); + glRotatef(angle, 0.0, 0.0, 1.0); + glCallList(gear1); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(3.1, -2.0, 0.0); + glRotatef(-2.0*angle-9.0, 0.0, 0.0, 1.0); + glCallList(gear2); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-3.1, 2.2, -1.8); + glRotatef(90.0, 1.0, 0.0, 0.0); + glRotatef(2.0*angle-2.0, 0.0, 0.0, 1.0); + glCallList(gear3); + glPopMatrix(); + + glPopMatrix(); +} + +sub NEW { + shift->SUPER::NEW(@_); + this->startTimer(10); + view_rotx = 20.0; + view_roty = 30.0; + view_rotz = 0.0; + angle = 0.0; +} + +sub initializeGL { + my $pos = [ 5.0, 5.0, 10.0, 1.0 ]; + my $red = [ 0.8, 0.1, 0.0, 1.0 ]; + my $green = [ 0.0, 0.8, 0.2, 1.0 ]; + my $blue = [ 0.2, 0.2, 1.0, 1.0 ]; + + glLightfv_p(GL_LIGHT0, GL_POSITION, @$pos); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); + + # make the gears + gear1 = glGenLists(1); + glNewList(gear1, GL_COMPILE); + glMaterialfv_p(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, @$red); + gear(1.0, 4.0, 1.0, 20, 0.7); + glEndList(); + + gear2 = glGenLists(1); + glNewList(gear2, GL_COMPILE); + glMaterialfv_p(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, @$green); + gear(0.5, 2.0, 2.0, 10, 0.7); + glEndList(); + + gear3 = glGenLists(1); + glNewList(gear3, GL_COMPILE); + glMaterialfv_p(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, @$blue); + gear(1.3, 2.0, 0.5, 10, 0.7); + glEndList(); + + glEnable(GL_NORMALIZE); +} + +sub resizeGL { + my($width, $height) = @_; + my $w = $width / $height; + my $h = 1.0; + + glViewport(0, 0, $width, $height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-$w, $w, -$h, $h, 5.0, 60.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -40.0); +} + +sub paintGL { + draw(); +} + +sub timerEvent { + updateGL(); +} + +package main; + +use Qt; +use GearWidget; + +$app = Qt::Application(\@ARGV); + +if(!Qt::GLFormat::hasOpenGL()) { + warn("This system has no OpenGL support. Exiting."); + exit -1; +} + +$w = GearWidget; +$app->setMainWidget($w); +$w->show; +exit $app->exec; |