/usr/local/CPAN/Qt/GLWidget.pm
package GLWidget;
use strict;
use warnings;
use QtCore4;
use QtGui4;
use QtCore4::isa qw( Qt::GLWidget );
use List::Util qw(min);
use OpenGL;
# [1]
use QtCore4::slots
setXRotation => ['int'],
setYRotation => ['int'],
setZRotation => ['int'];
use QtCore4::signals
xRotationChanged => ['int'],
yRotationChanged => ['int'],
zRotationChanged => ['int'];
# [1]
sub object() {
return this->{object};
}
sub xRot() {
return this->{xRot};
}
sub yRot() {
return this->{yRot};
}
sub zRot() {
return this->{zRot};
}
sub lastPos() {
return this->{lastPos};
}
sub trolltechGreen() {
return this->{trolltechGreen};
}
sub trolltechPurple() {
return this->{trolltechPurple};
}
# [0]
sub NEW
{
my ($class, $parent) = @_;
$class->SUPER::NEW($parent);
this->{object} = 0;
this->{xRot} = 0;
this->{yRot} = 0;
this->{zRot} = 0;
this->{trolltechGreen} = Qt::Color::fromCmykF(0.40, 0.0, 1.0, 0.0);
this->{trolltechPurple} = Qt::Color::fromCmykF(0.39, 0.39, 0.0, 0.0);
}
# [0]
# [1]
sub DESTROY
{
this->makeCurrent();
glDeleteLists(this->object, 1);
}
# [1]
# [2]
sub minimumSizeHint
{
return Qt::Size(50, 50);
}
# [2]
# [3]
sub sizeHint
# [3] //! [4]
{
return Qt::Size(400, 400);
}
# [4]
# [5]
sub setXRotation
{
my ($angle) = @_;
this->normalizeAngle(\$angle);
if ($angle != this->xRot) {
this->{xRot} = $angle;
emit this->xRotationChanged($angle);
this->updateGL();
}
}
# [5]
sub setYRotation
{
my ($angle) = @_;
this->normalizeAngle(\$angle);
if ($angle != this->yRot) {
this->{yRot} = $angle;
emit this->yRotationChanged($angle);
this->updateGL();
}
}
sub setZRotation
{
my ($angle) = @_;
this->normalizeAngle(\$angle);
if ($angle != this->zRot) {
this->{zRot} = $angle;
emit this->zRotationChanged($angle);
this->updateGL();
}
}
# [6]
sub initializeGL
{
this->qglClearColor(this->trolltechPurple->dark());
this->{object} = this->makeObject();
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
}
# [6]
# [7]
sub paintGL
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslated(0.0, 0.0, -10.0);
glRotated(this->xRot / 16.0, 1.0, 0.0, 0.0);
glRotated(this->yRot / 16.0, 0.0, 1.0, 0.0);
glRotated(this->zRot / 16.0, 0.0, 0.0, 1.0);
glCallList(this->object);
}
# [7]
# [8]
sub resizeGL
{
my ($width, $height) = @_;
my $side = min($width, $height);
glViewport(($width - $side) / 2, ($height - $side) / 2, $side, $side);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0);
glMatrixMode(GL_MODELVIEW);
}
# [8]
# [9]
sub mousePressEvent
{
my ($event) = @_;
this->{lastPos} = $event->pos();
}
# [9]
# [10]
sub mouseMoveEvent
{
my ($event) = @_;
my $dx = $event->x() - this->lastPos->x();
my $dy = $event->y() - this->lastPos->y();
if ($event->buttons() & Qt::LeftButton()) {
this->setXRotation(this->xRot + 8 * $dy);
this->setYRotation(this->yRot + 8 * $dx);
} elsif ($event->buttons() & Qt::RightButton()) {
this->setXRotation(this->xRot + 8 * $dy);
this->setZRotation(this->zRot + 8 * $dx);
}
this->{lastPos} = $event->pos();
}
# [10]
sub makeObject
{
my $list = glGenLists(1);
glNewList($list, GL_COMPILE);
glBegin(GL_QUADS);
my $x1 = +0.06;
my $y1 = -0.14;
my $x2 = +0.14;
my $y2 = -0.06;
my $x3 = +0.08;
my $y3 = +0.00;
my $x4 = +0.30;
my $y4 = +0.22;
this->quad($x1, $y1, $x2, $y2, $y2, $x2, $y1, $x1);
this->quad($x3, $y3, $x4, $y4, $y4, $x4, $y3, $x3);
this->extrude($x1, $y1, $x2, $y2);
this->extrude($x2, $y2, $y2, $x2);
this->extrude($y2, $x2, $y1, $x1);
this->extrude($y1, $x1, $x1, $y1);
this->extrude($x3, $y3, $x4, $y4);
this->extrude($x4, $y4, $y4, $x4);
this->extrude($y4, $x4, $y3, $x3);
my $Pi = 3.14159265358979323846;
my $NumSectors = 200;
for (my $i = 0; $i < $NumSectors; ++$i) {
my $angle1 = ($i * 2 * $Pi) / $NumSectors;
my $x5 = 0.30 * sin($angle1);
my $y5 = 0.30 * cos($angle1);
my $x6 = 0.20 * sin($angle1);
my $y6 = 0.20 * cos($angle1);
my $angle2 = (($i + 1) * 2 * $Pi) / $NumSectors;
my $x7 = 0.20 * sin($angle2);
my $y7 = 0.20 * cos($angle2);
my $x8 = 0.30 * sin($angle2);
my $y8 = 0.30 * cos($angle2);
this->quad($x5, $y5, $x6, $y6, $x7, $y7, $x8, $y8);
this->extrude($x6, $y6, $x7, $y7);
this->extrude($x8, $y8, $x5, $y5);
}
glEnd();
glEndList();
return $list;
}
sub quad
{
my ($x1, $y1, $x2, $y2, $x3, $y3, $x4, $y4) = @_;
this->qglColor(this->trolltechGreen);
glVertex3d($x1, $y1, -0.05);
glVertex3d($x2, $y2, -0.05);
glVertex3d($x3, $y3, -0.05);
glVertex3d($x4, $y4, -0.05);
glVertex3d($x4, $y4, +0.05);
glVertex3d($x3, $y3, +0.05);
glVertex3d($x2, $y2, +0.05);
glVertex3d($x1, $y1, +0.05);
}
sub extrude
{
my ($x1, $y1, $x2, $y2) = @_;
this->qglColor(this->trolltechGreen->dark(250 + (100 * $x1)));
glVertex3d($x1, $y1, +0.05);
glVertex3d($x2, $y2, +0.05);
glVertex3d($x2, $y2, -0.05);
glVertex3d($x1, $y1, -0.05);
}
sub normalizeAngle
{
my ($angle) = @_;
while ($$angle < 0) {
$$angle += 360 * 16;
}
while ($$angle > 360 * 16) {
$$angle -= 360 * 16;
}
}
1;