#!/usr/bin/perl -w
gear1
gear2
gear3
view_rotx
view_roty
view_rotz
angle
)
;
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);
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();
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);
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();
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();
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);
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);
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();
}
$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
;