Qore Programming Language

  • Increase font size
  • Default font size
  • Decrease font size

morph3d demo

E-mail Print PDF

This is the classic polyhedron morphing demo for opengl, ported from C to Qore.

Here's a screenshot (source code below):

opengl morph3d demo

/Users/david/src/qore/module-glut/test/morph3d.q

#!/usr/bin/env qore

# the glut module automatically loads the opengl module
%requires glut

const Scale = 0.3;

# Increasing this values produces better image quality, the price is speed.
# Very low values produces erroneous/incorrect plotting
const tetradivisions = 23;
const cubedivisions = 20;
const octadivisions = 21;
const dodecadivisions = 10;
const icodivisions = 15;

const tetraangle = 109.47122063449069174;
const cubeangle = 90.000000000000000000;
const octaangle = 109.47122063449069174;
const dodecaangle = 63.434948822922009981;
const icoangle = 41.810314895778596167;

const Pi = 3.1415926535897932385;
const SQRT2 = 1.4142135623730951455;
const SQRT3 = 1.7320508075688771932;
const SQRT5 = 2.2360679774997898051;
const SQRT6 = 2.4494897427831778813;
const SQRT15 = 3.8729833462074170214;
const cossec36_2 = 0.8506508083520399322;
const cos72 = 0.3090169943749474241;
const sin72 = 0.9510565162951535721;
const cos36 = 0.8090169943749474241;
const sin36 = 0.5877852522924731292;

const TAU = ((SQRT5 + 1) / 2);

# *************************************************************************

our $mono=0;
our $smooth=1;
our $anim=1;
our $WindH = 480;
our $WindW = 640;
our $step=0.0;
our $seno;
our $object;
our $edgedivisions;

our $draw_object;

our $Magnitude;
our $MaterialColor;

our $t0 = -1.0;

const front_shininess = ( 60.0, );
const front_specular = ( 0.7, 0.7, 0.7, 1.0 );
const ambient = ( 0.0, 0.0, 0.0, 1.0 );
const diffuse = ( 1.0, 1.0, 1.0, 1.0 );
const position0 = ( 1.0, 1.0, 1.0, 0.0 );
const position1 = (-1.0,-1.0, 1.0, 0.0 );
const lmodel_ambient = ( 0.5, 0.5, 0.5, 1.0 );
const lmodel_twoside = ( GL_TRUE, );

const MaterialRed = ( 0.7, 0.0, 0.0, 1.0 );
const MaterialGreen = ( 0.1, 0.5, 0.2, 1.0 );
const MaterialBlue = ( 0.0, 0.0, 0.7, 1.0 );
const MaterialCyan = ( 0.2, 0.5, 0.7, 1.0 );
const MaterialYellow = ( 0.7, 0.7, 0.0, 1.0 );
const MaterialMagenta = ( 0.6, 0.2, 0.5, 1.0 );
const MaterialWhite = ( 0.7, 0.7, 0.7, 1.0 );
const MaterialGray = ( 0.2, 0.2, 0.2, 1.0 );

sub myVectMul($X1, $Y1, $Z1, $X2, $Y2, $Z2)
{
    return glNormal3f($Y1*$Z2-$Z1*$Y2,$Z1*$X2-$X1*$Z2,$X1*$Y2-$Y1*$X2);
}

sub sqr($A) { return $A*$A; }

sub TRIANGLE($Edge, $Amp, $Divisions, $Z)
{
    my ( $Xf,$Yf,$Xa,$Yb,$Xf2,$Yf2 );
    my ( $Factor,$Factor1,$Factor2 );
    my ( $VertX,$VertY,$VertZ,$NeiAX,$NeiAY,$NeiAZ,$NeiBX,$NeiBY,$NeiBZ );
    my ( $Ax,$Ay,$Bx );
    my ( $Ri,$Ti );

    my $Vr=($Edge)*SQRT3/3;
    my $AmpVr2=($Amp)/sqr($Vr);
    my $Zf=($Edge)*($Z);

    $Ax=($Edge)*( 0.5/($Divisions)); $Ay=($Edge)*(-SQRT3/(2*$Divisions));
    $Bx=($Edge)*(-0.5/($Divisions));

    for ($Ri=1; $Ri<=($Divisions); $Ri++) {
	glBegin(GL_TRIANGLE_STRIP);
	for ($Ti=0; $Ti<$Ri; $Ti++) {
	    $Xf=float($Ri-$Ti)*$Ax + float($Ti)*$Bx;
	    $Yf=$Vr+float($Ri-$Ti)*$Ay + float($Ti)*$Ay;
	    $Xa=$Xf+0.001; $Yb=$Yf+0.001;
	    $Factor=1-((($Xf2=sqr($Xf))+($Yf2=sqr($Yf)))*$AmpVr2);
	    $Factor1=1-((sqr($Xa)+$Yf2)*$AmpVr2);
	    $Factor2=1-(($Xf2+sqr($Yb))*$AmpVr2);
	    $VertX=$Factor*$Xf; $VertY=$Factor*$Yf; $VertZ=$Factor*$Zf;
	    $NeiAX=$Factor1*$Xa-$VertX; $NeiAY=$Factor1*$Yf-$VertY; $NeiAZ=$Factor1*$Zf-$VertZ;
	    $NeiBX=$Factor2*$Xf-$VertX; $NeiBY=$Factor2*$Yb-$VertY; $NeiBZ=$Factor2*$Zf-$VertZ;
	    myVectMul($NeiAX, $NeiAY, $NeiAZ, $NeiBX, $NeiBY, $NeiBZ);
	    glVertex3f($VertX, $VertY, $VertZ);

	    $Xf=float($Ri-$Ti-1)*$Ax + float($Ti*$Bx);
	    $Yf=$Vr+float($Ri-$Ti-1)*$Ay + float($Ti*$Ay);
	    $Xa=$Xf+0.001; $Yb=$Yf+0.001;
	    $Factor=1-((($Xf2=sqr($Xf))+($Yf2=sqr($Yf)))*$AmpVr2);
	    $Factor1=1-((sqr($Xa)+$Yf2)*$AmpVr2);
	    $Factor2=1-(($Xf2+sqr($Yb))*$AmpVr2);
	    $VertX=$Factor*$Xf; $VertY=$Factor*$Yf; $VertZ=$Factor*$Zf;
	    $NeiAX=$Factor1*$Xa-$VertX; $NeiAY=$Factor1*$Yf-$VertY; $NeiAZ=$Factor1*$Zf-$VertZ;
	    $NeiBX=$Factor2*$Xf-$VertX; $NeiBY=$Factor2*$Yb-$VertY; $NeiBZ=$Factor2*$Zf-$VertZ;
	    myVectMul($NeiAX, $NeiAY, $NeiAZ, $NeiBX, $NeiBY, $NeiBZ);
	    glVertex3f($VertX, $VertY, $VertZ);

	}
	$Xf=float($Ri*$Bx);
	$Yf=$Vr+float($Ri*$Ay);
	$Xa=$Xf+0.001; $Yb=$Yf+0.001;
	$Factor=1-((($Xf2=sqr($Xf))+($Yf2=sqr($Yf)))*$AmpVr2);
	$Factor1=1-((sqr($Xa)+$Yf2)*$AmpVr2);
	$Factor2=1-(($Xf2+sqr($Yb))*$AmpVr2);
	$VertX=$Factor*$Xf; $VertY=$Factor*$Yf; $VertZ=$Factor*$Zf;
	$NeiAX=$Factor1*$Xa-$VertX; $NeiAY=$Factor1*$Yf-$VertY; $NeiAZ=$Factor1*$Zf-$VertZ;
	$NeiBX=$Factor2*$Xf-$VertX; $NeiBY=$Factor2*$Yb-$VertY; $NeiBZ=$Factor2*$Zf-$VertZ;
	myVectMul($NeiAX, $NeiAY, $NeiAZ, $NeiBX, $NeiBY, $NeiBZ);
	glVertex3f($VertX, $VertY, $VertZ);
	glEnd();
    }
}

sub SQUARE($Edge, $Amp, $Divisions, $Z)
{
    my ($Xi,$Yi);
    my ($Xf,$Yf,$Y,$Xf2,$Yf2,$Y2,$Xa,$Yb);
    my ($Factor,$Factor1,$Factor2);
    my ($VertX,$VertY,$VertZ,$NeiAX,$NeiAY,$NeiAZ,$NeiBX,$NeiBY,$NeiBZ);
    my $Zf=($Edge)*($Z);
    my $AmpVr2=($Amp)/sqr(($Edge)*SQRT2/2);

    for ($Yi=0; $Yi<($Divisions); $Yi++) {
	$Yf=-(($Edge)/2.0) + (float($Yi))/($Divisions)*($Edge);
	$Yf2=sqr($Yf);
	$Y=$Yf+1.0/($Divisions)*($Edge);
	$Y2=sqr($Y);
	glBegin(GL_QUAD_STRIP);
	for ($Xi=0; $Xi<=($Divisions); $Xi++) {
	    $Xf=-(($Edge)/2.0) + (float($Xi))/($Divisions)*($Edge);
	    $Xf2=sqr($Xf);

	    $Xa=$Xf+0.001; $Yb=$Y+0.001;
	    $Factor=1-(($Xf2+$Y2)*$AmpVr2);
	    $Factor1=1-((sqr($Xa)+$Y2)*$AmpVr2);
	    $Factor2=1-(($Xf2+sqr($Yb))*$AmpVr2);
	    $VertX=$Factor*$Xf; $VertY=$Factor*$Y; $VertZ=$Factor*$Zf;
	    $NeiAX=$Factor1*$Xa-$VertX; $NeiAY=$Factor1*$Y-$VertY; $NeiAZ=$Factor1*$Zf-$VertZ;

	    $NeiBX=$Factor2*$Xf-$VertX; $NeiBY=$Factor2*$Yb-$VertY; $NeiBZ=$Factor2*$Zf-$VertZ;

	    myVectMul($NeiAX, $NeiAY, $NeiAZ, $NeiBX, $NeiBY, $NeiBZ);
	    glVertex3f($VertX, $VertY, $VertZ);

	    $Xa=$Xf+0.001; $Yb=$Yf+0.001;
	    $Factor=1-(($Xf2+$Yf2)*$AmpVr2);
	    $Factor1=1-((sqr($Xa)+$Yf2)*$AmpVr2);
	    $Factor2=1-(($Xf2+sqr($Yb))*$AmpVr2);
	    $VertX=$Factor*$Xf; $VertY=$Factor*$Yf; $VertZ=$Factor*$Zf;

	    $NeiAX=$Factor1*$Xa-$VertX; $NeiAY=$Factor1*$Yf-$VertY; $NeiAZ=$Factor1*$Zf-$VertZ;

	    $NeiBX=$Factor2*$Xf-$VertX; $NeiBY=$Factor2*$Yb-$VertY; $NeiBZ=$Factor2*$Zf-$VertZ;

	    myVectMul($NeiAX, $NeiAY, $NeiAZ, $NeiBX, $NeiBY, $NeiBZ);
	    glVertex3f($VertX, $VertY, $VertZ);
	}
	glEnd();
    }
}

sub PENTAGON($Edge, $Amp, $Divisions, $Z)
{
    my ($Ri,$Ti,$Fi);
    my ($Xf,$Yf,$Xa,$Yb,$Xf2,$Yf2);
    my ($x,$y);
    my ($Factor,$Factor1,$Factor2);
    my ($VertX,$VertY,$VertZ,$NeiAX,$NeiAY,$NeiAZ,$NeiBX,$NeiBY,$NeiBZ);
    my $Zf=($Edge)*($Z);
    my $AmpVr2=($Amp)/sqr(($Edge)*cossec36_2);

    for($Fi=0;$Fi<6;$Fi++) {
	$x[$Fi]=-cos( $Fi*2*Pi/5 + Pi/10 )/($Divisions)*cossec36_2*($Edge);
	$y[$Fi]= sin( $Fi*2*Pi/5 + Pi/10 )/($Divisions)*cossec36_2*($Edge);
    }

    for ($Ri=1; $Ri<=($Divisions); $Ri++) {
	for ($Fi=0; $Fi<5; $Fi++) {
	    glBegin(GL_TRIANGLE_STRIP);
	    for ($Ti=0; $Ti<$Ri; $Ti++) {
		$Xf=float($Ri-$Ti)*$x[$Fi] + float($Ti*$x[$Fi+1]);
		$Yf=float($Ri-$Ti)*$y[$Fi] + float($Ti*$y[$Fi+1]);
		$Xa=$Xf+0.001; $Yb=$Yf+0.001;
		$Factor=1-((($Xf2=sqr($Xf))+($Yf2=sqr($Yf)))*$AmpVr2);
		$Factor1=1-((sqr($Xa)+$Yf2)*$AmpVr2);
		$Factor2=1-(($Xf2+sqr($Yb))*$AmpVr2);
		$VertX=$Factor*$Xf; $VertY=$Factor*$Yf; $VertZ=$Factor*$Zf;
		$NeiAX=$Factor1*$Xa-$VertX; $NeiAY=$Factor1*$Yf-$VertY; $NeiAZ=$Factor1*$Zf-$VertZ;
		$NeiBX=$Factor2*$Xf-$VertX; $NeiBY=$Factor2*$Yb-$VertY; $NeiBZ=$Factor2*$Zf-$VertZ;
		myVectMul($NeiAX, $NeiAY, $NeiAZ, $NeiBX, $NeiBY, $NeiBZ);
		glVertex3f($VertX, $VertY, $VertZ);

		$Xf=float($Ri-$Ti-1)*$x[$Fi] + float($Ti*$x[$Fi+1]);
		$Yf=float($Ri-$Ti-1)*$y[$Fi] + float($Ti*$y[$Fi+1]);
		$Xa=$Xf+0.001; $Yb=$Yf+0.001;
		$Factor=1-((($Xf2=sqr($Xf))+($Yf2=sqr($Yf)))*$AmpVr2);
		$Factor1=1-((sqr($Xa)+$Yf2)*$AmpVr2);
		$Factor2=1-(($Xf2+sqr($Yb))*$AmpVr2);
		$VertX=$Factor*$Xf; $VertY=$Factor*$Yf; $VertZ=$Factor*$Zf;

		$NeiAX=$Factor1*$Xa-$VertX; $NeiAY=$Factor1*$Yf-$VertY; $NeiAZ=$Factor1*$Zf-$VertZ;

		$NeiBX=$Factor2*$Xf-$VertX; $NeiBY=$Factor2*$Yb-$VertY; $NeiBZ=$Factor2*$Zf-$VertZ;

		myVectMul($NeiAX, $NeiAY, $NeiAZ, $NeiBX, $NeiBY, $NeiBZ);
		glVertex3f($VertX, $VertY, $VertZ);

	    }
	    $Xf=float($Ri*$x[$Fi+1]);
	    $Yf=float($Ri*$y[$Fi+1]);
	    $Xa=$Xf+0.001; $Yb=$Yf+0.001;
	    $Factor=1-((($Xf2=sqr($Xf))+($Yf2=sqr($Yf)))*$AmpVr2);
	    $Factor1=1-((sqr($Xa)+$Yf2)*$AmpVr2);
	    $Factor2=1-(($Xf2+sqr($Yb))*$AmpVr2);
	    $VertX=$Factor*$Xf; $VertY=$Factor*$Yf; $VertZ=$Factor*$Zf;
	    $NeiAX=$Factor1*$Xa-$VertX; $NeiAY=$Factor1*$Yf-$VertY; $NeiAZ=$Factor1*$Zf-$VertZ;
	    $NeiBX=$Factor2*$Xf-$VertX; $NeiBY=$Factor2*$Yb-$VertY; $NeiBZ=$Factor2*$Zf-$VertZ;
	    myVectMul($NeiAX, $NeiAY, $NeiAZ, $NeiBX, $NeiBY, $NeiBZ);
	    glVertex3f($VertX, $VertY, $VertZ);
	    glEnd();
	}
    }
}

sub draw_tetra()
{
    my $list = glGenLists( 1 );
    glNewList( $list, GL_COMPILE );
    TRIANGLE(2,$seno,$edgedivisions,0.5/SQRT6);
    glEndList();

    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[0]);
    glCallList($list);
    glPushMatrix();
    glRotatef(180,0,0,1);
    glRotatef(-tetraangle,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[1]);
    glCallList($list);
    glPopMatrix();
    glPushMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-180+tetraangle,0.5,SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[2]);
    glCallList($list);
    glPopMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-180+tetraangle,0.5,-SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[3]);
    glCallList($list);

    glDeleteLists($list,1);
}

sub draw_cube()
{
    my $list;

    $list = glGenLists( 1 );
    glNewList( $list, GL_COMPILE );
    SQUARE(2, $seno, $edgedivisions, 0.5);
    glEndList();

    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[0]);
    glCallList($list);
    glRotatef(cubeangle,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[1]);
    glCallList($list);
    glRotatef(cubeangle,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[2]);
    glCallList($list);
    glRotatef(cubeangle,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[3]);
    glCallList($list);
    glRotatef(cubeangle,0,1,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[4]);
    glCallList($list);
    glRotatef(2*cubeangle,0,1,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[5]);
    glCallList($list);

    glDeleteLists($list,1);
}

sub draw_octa()
{
    my $list;

    $list = glGenLists( 1 );
    glNewList( $list, GL_COMPILE );
    TRIANGLE(2,$seno,$edgedivisions,1/SQRT6);
    glEndList();

    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[0]);
    glCallList($list);
    glPushMatrix();
    glRotatef(180,0,0,1);
    glRotatef(-180+octaangle,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[1]);
    glCallList($list);
    glPopMatrix();
    glPushMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-octaangle,0.5,SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[2]);
    glCallList($list);
    glPopMatrix();
    glPushMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-octaangle,0.5,-SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[3]);
    glCallList($list);
    glPopMatrix();
    glRotatef(180,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[4]);
    glCallList($list);
    glPushMatrix();
    glRotatef(180,0,0,1);
    glRotatef(-180+octaangle,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[5]);
    glCallList($list);
    glPopMatrix();
    glPushMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-octaangle,0.5,SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[6]);
    glCallList($list);
    glPopMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-octaangle,0.5,-SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[7]);
    glCallList($list);

    glDeleteLists($list,1);
}

sub draw_dodeca()
{
    my $list = glGenLists( 1 );
    glNewList( $list, GL_COMPILE );
    PENTAGON(1,$seno,$edgedivisions,sqr(TAU) * sqrt((TAU+2)/5) / 2);
    glEndList();

    glPushMatrix();
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[0]);
    glCallList($list);
    glRotatef(180,0,0,1);
    glPushMatrix();
    glRotatef(-dodecaangle,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[1]);
    glCallList($list);
    glPopMatrix();
    glPushMatrix();
    glRotatef(-dodecaangle,cos72,sin72,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[2]);
    glCallList($list);
    glPopMatrix();
    glPushMatrix();
    glRotatef(-dodecaangle,cos72,-sin72,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[3]);
    glCallList($list);
    glPopMatrix();
    glPushMatrix();
    glRotatef(dodecaangle,cos36,-sin36,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[4]);
    glCallList($list);
    glPopMatrix();
    glRotatef(dodecaangle,cos36,sin36,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[5]);
    glCallList($list);
    glPopMatrix();
    glRotatef(180,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[6]);
    glCallList($list);
    glRotatef(180,0,0,1);
    glPushMatrix();
    glRotatef(-dodecaangle,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[7]);
    glCallList($list);
    glPopMatrix();
    glPushMatrix();
    glRotatef(-dodecaangle,cos72,sin72,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[8]);
    glCallList($list);
    glPopMatrix();
    glPushMatrix();
    glRotatef(-dodecaangle,cos72,-sin72,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[9]);
    glCallList($list);
    glPopMatrix();
    glPushMatrix();
    glRotatef(dodecaangle,cos36,-sin36,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[10]);
    glCallList($list);
    glPopMatrix();
    glRotatef(dodecaangle,cos36,sin36,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[11]);
    glCallList($list);

    glDeleteLists($list,1);
}

sub draw_ico()
{
    my $list;

    $list = glGenLists( 1 );
    glNewList( $list, GL_COMPILE );
    TRIANGLE(1.5,$seno,$edgedivisions,(3*SQRT3+SQRT15)/12);
    glEndList();

    glPushMatrix();

    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[0]);
    glCallList($list);
    glPushMatrix();
    glRotatef(180,0,0,1);
    glRotatef(-icoangle,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[1]);
    glCallList($list);
    glPushMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-180+icoangle,0.5,SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[2]);
    glCallList($list);
    glPopMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[3]);
    glCallList($list);
    glPopMatrix();
    glPushMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-180+icoangle,0.5,SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[4]);
    glCallList($list);
    glPushMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-180+icoangle,0.5,SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[5]);
    glCallList($list);
    glPopMatrix();
    glRotatef(180,0,0,1);
    glRotatef(-icoangle,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[6]);
    glCallList($list);
    glPopMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[7]);
    glCallList($list);
    glPushMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[8]);
    glCallList($list);
    glPopMatrix();
    glRotatef(180,0,0,1);
    glRotatef(-icoangle,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[9]);
    glCallList($list);
    glPopMatrix();
    glRotatef(180,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[10]);
    glCallList($list);
    glPushMatrix();
    glRotatef(180,0,0,1);
    glRotatef(-icoangle,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[11]);
    glCallList($list);
    glPushMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-180+icoangle,0.5,SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[12]);
    glCallList($list);
    glPopMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[13]);
    glCallList($list);
    glPopMatrix();
    glPushMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-180+icoangle,0.5,SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[14]);
    glCallList($list);
    glPushMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-180+icoangle,0.5,SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[15]);
    glCallList($list);
    glPopMatrix();
    glRotatef(180,0,0,1);
    glRotatef(-icoangle,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[16]);
    glCallList($list);
    glPopMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[17]);
    glCallList($list);
    glPushMatrix();
    glRotatef(180,0,1,0);
    glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[18]);
    glCallList($list);
    glPopMatrix();
    glRotatef(180,0,0,1);
    glRotatef(-icoangle,1,0,0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, $MaterialColor[19]);
    glCallList($list);

    glDeleteLists($list,1);
}

sub draw ()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glPushMatrix();

    glTranslatef( 0.0, 0.0, -10.0 );

    if (!$WindW)
	printf("error! $WindW=%N\n", $WindW);

    glScalef( Scale*$WindH/$WindW, Scale, Scale );
    glTranslatef(2.5*$WindW/$WindH*sin($step*1.11),2.5*cos($step*1.25*1.11),0);
    glRotatef($step*100,1,0,0);
    glRotatef($step*95,0,1,0);
    glRotatef($step*90,0,0,1);

    $seno=(sin($step)+1.0/3.0)*(4.0/5.0)*$Magnitude;

    $draw_object();

    glPopMatrix();

    glFlush();

    glutSwapBuffers();

}

sub idle_()
{
    my $dt;
    my $t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;

    if ($t0 < 0.0)
	$t0 = $t;
    $dt = $t - $t0;
    $t0 = $t;

    $step += $dt;

    glutPostRedisplay();
}

sub reshape($width, $height)
{
    glViewport(0, 0, ($WindW=$width), ($WindH=$height));
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 );
    glMatrixMode(GL_MODELVIEW);
}

sub key($k, $x, $y)
{
    switch ($k) {
	case 49: $object=1; break; # '1'
	case 50: $object=2; break; # '2'
	case 51: $object=3; break; # '3'
	case 52: $object=4; break; # '4'
	case 53: $object=5; break; # '5'
	case 32: $mono^=1; break; # ' '
	case 115: $smooth^=1; break; # 's'
	case 97: { # 'a'
	    $anim^=1;
	    if ($anim)
		glutIdleFunc( \idle_() );
	    else
		glutIdleFunc();
	    break;
	}
	case 27:
	exit(0);
    }
    pinit();
    glutPostRedisplay();
}

sub pinit()
{
    switch($object) {
	case 1:
	$draw_object=\draw_tetra();
	$MaterialColor[0]=MaterialRed;
	$MaterialColor[1]=MaterialGreen;
	$MaterialColor[2]=MaterialBlue;
	$MaterialColor[3]=MaterialWhite;
	$edgedivisions=tetradivisions;
	$Magnitude=2.5;
	break;
	case 2:
	$draw_object=\draw_cube();
	$MaterialColor[0]=MaterialRed;
	$MaterialColor[1]=MaterialGreen;
	$MaterialColor[2]=MaterialCyan;
	$MaterialColor[3]=MaterialMagenta;
	$MaterialColor[4]=MaterialYellow;
	$MaterialColor[5]=MaterialBlue;
	$edgedivisions=cubedivisions;
	$Magnitude=2.0;
	break;
	case 3:
	$draw_object=\draw_octa();
	$MaterialColor[0]=MaterialRed;
	$MaterialColor[1]=MaterialGreen;
	$MaterialColor[2]=MaterialBlue;
	$MaterialColor[3]=MaterialWhite;
	$MaterialColor[4]=MaterialCyan;
	$MaterialColor[5]=MaterialMagenta;
	$MaterialColor[6]=MaterialGray;
	$MaterialColor[7]=MaterialYellow;
	$edgedivisions=octadivisions;
	$Magnitude=2.5;
	break;
	case 4:
	$draw_object=\draw_dodeca();
	$MaterialColor[ 0]=MaterialRed;
	$MaterialColor[ 1]=MaterialGreen;
	$MaterialColor[ 2]=MaterialCyan;
	$MaterialColor[ 3]=MaterialBlue;
	$MaterialColor[ 4]=MaterialMagenta;
	$MaterialColor[ 5]=MaterialYellow;
	$MaterialColor[ 6]=MaterialGreen;
	$MaterialColor[ 7]=MaterialCyan;
	$MaterialColor[ 8]=MaterialRed;
	$MaterialColor[ 9]=MaterialMagenta;
	$MaterialColor[10]=MaterialBlue;
	$MaterialColor[11]=MaterialYellow;
	$edgedivisions=dodecadivisions;
	$Magnitude=2.0;
	break;
	case 5:
	$draw_object=\draw_ico();
	$MaterialColor[ 0]=MaterialRed;
	$MaterialColor[ 1]=MaterialGreen;
	$MaterialColor[ 2]=MaterialBlue;
	$MaterialColor[ 3]=MaterialCyan;
	$MaterialColor[ 4]=MaterialYellow;
	$MaterialColor[ 5]=MaterialMagenta;
	$MaterialColor[ 6]=MaterialRed;
	$MaterialColor[ 7]=MaterialGreen;
	$MaterialColor[ 8]=MaterialBlue;
	$MaterialColor[ 9]=MaterialWhite;
	$MaterialColor[10]=MaterialCyan;
	$MaterialColor[11]=MaterialYellow;
	$MaterialColor[12]=MaterialMagenta;
	$MaterialColor[13]=MaterialRed;
	$MaterialColor[14]=MaterialGreen;
	$MaterialColor[15]=MaterialBlue;
	$MaterialColor[16]=MaterialCyan;
	$MaterialColor[17]=MaterialYellow;
	$MaterialColor[18]=MaterialMagenta;
	$MaterialColor[19]=MaterialGray;
	$edgedivisions=icodivisions;
	$Magnitude=2.5;
	break;
    }
    if ($mono) {
	my $loop;
	for ($loop=0; $loop<20; $loop++) $MaterialColor[$loop]=MaterialGray;
    }
    if ($smooth) {
	glShadeModel( GL_SMOOTH );
    } else {
	glShadeModel( GL_FLAT );
    }

}

sub main()
{
    printf("Morph 3D - Shows morphing platonic polyhedra\n");
    printf("Author: Marcelo Fernandes Vianna (vianna@cat.cbpf.br)\n\n");
    printf(" [1] - Tetrahedron\n");
    printf(" [2] - Hexahedron (Cube)\n");
    printf(" [3] - Octahedron\n");
    printf(" [4] - Dodecahedron\n");
    printf(" [5] - Icosahedron\n");
    printf("[SPACE] - Toggle colored faces\n");
    printf("[RETURN] - Toggle smooth/flat shading\n");
    printf(" [ESC] - Quit\n");

    $object=1;

    glutInit(\$ARGV);
    glutInitWindowPosition(0,0);
    glutInitWindowSize(640,480);

    glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB );

    if (glutCreateWindow("Morph 3D - Shows morphing platonic polyhedra") <= 0) {
	exit(0);
    }

    glClearDepth(1.0);
    glClearColor( 0.0, 0.0, 0.0, 1.0 );
    glColor3f( 1.0, 1.0, 1.0 );

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glFlush();
    glutSwapBuffers();

    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
    glLightfv(GL_LIGHT0, GL_POSITION, position0);
    glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
    glLightfv(GL_LIGHT1, GL_POSITION, position1);
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
    glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHT1);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_NORMALIZE);

    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);

    glHint(GL_FOG_HINT, GL_FASTEST);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
    glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);

    pinit();

    glutReshapeFunc( \reshape() );
    glutKeyboardFunc( \key() );
    glutIdleFunc( \idle_() );
    glutDisplayFunc( \draw() );
    glutMainLoop();
}

main();

 

Last Updated on Saturday, 25 December 2010 19:16