#!/usr/bin/perl -w use strict; use Time::HiRes qw(sleep); use OpenGL ':old', ':glutfunctions', ':glutconstants'; my $where = (@ARGV ? 'far away' : 'near Earth'); print "Camera position: $where.\n"; print "Give arguments to position camera far away.\n"; my $field_of_view = (@ARGV ? 20 : 100); # Degrees my $minviewdist = 0.1; my $maxviewdist = 1000; my $mercury = 0; my $venus = 0; my $earth = 0; my $earthMoon = 0; my $earthspin = 0; my $mars = 0; my $jupiter = 230; # Make them visible my $jups1 = 0; my $jups2 = 0; my $jups3 = 0; my $jups4 = 0; my $saturn = 250; # Make them visible sub resizeHandler { # Not auto yet my ($wind_w, $wind_h) = @_; glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( $field_of_view, $wind_w/$wind_h, $minviewdist, $maxviewdist ); glMatrixMode( GL_MODELVIEW ); } sub display { # clear the canvas glClearColor(0,0,0,1); glDrawBuffer(GL_FRONT_AND_BACK); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glDrawBuffer(GL_BACK); glLoadIdentity(); if (@ARGV) { # move the squares back a bit glTranslatef( 0, 0, -500 ); # and add a tilt glRotatef(-70, 1,0,0); } else { # place viewpoint on the surface of the planet glRotatef(30, 1,0,0); glTranslatef( 0, -5, 2 ); glRotatef(-$earthspin, 0,1,0); glTranslatef( 0, 0, -60 ); glRotatef(-90, 1,0,0); glRotatef(90-$earth, 0,0,1); } # Sun light glLightfv(GL_LIGHT0, GL_POSITION, pack "f4", 0, 0, 0, 1); #glLightfv(GL_LIGHT1, GL_DIFFUSE, pack "f4", 1, 1, 1, 1); #glLightfv(GL_LIGHT0, GL_DIFFUSE, pack "f4", 0, 0, 0, 1); # Same for specular? # Moon light glPushMatrix(); # Position the moon glRotatef($earth,0,0,1); glTranslatef( -60, 0, 0 ); glRotatef($earthMoon,0,0,1); glTranslatef( -10, 0, 0 ); glLightfv(GL_LIGHT1, GL_POSITION, pack "f4", 0, 0, 0, 1); my $moon_bright = 0.1*(1 + cos($earthMoon*3.1415926/180)); glLightfv(GL_LIGHT1, GL_AMBIENT, pack "f4", $moon_bright, $moon_bright, $moon_bright, 1); glPopMatrix(); # Sun # glColor3f(1,1,1); glMaterialfv( GL_FRONT, GL_EMISSION, pack 'f4', 1, 1, 0, 1); glutSolidSphere(20,10,10); glMaterialfv( GL_FRONT, GL_EMISSION, pack 'f4', 0, 0, 0, 1); glPushMatrix(); # Position the mercury glRotatef($mercury,0,0,1); glTranslatef( -30, 0, 0 ); glColor3f(0.6, 0.6, 0.6); glutSolidSphere(2,10,10); glPopMatrix(); glPushMatrix(); # Position the venus glRotatef($venus,0,0,1); glTranslatef( -40, 0, 0 ); glColor3f(0,1,0); glutSolidSphere(5,10,10); glPopMatrix(); glPushMatrix(); # Position the earth glRotatef($earth,0,0,1); glTranslatef( -60, 0, 0 ); glColor3f(0,0,1); glPushMatrix(); # Rotate the planet earth glRotatef($earthspin,0,0,1); glEnable( GL_LIGHT1 ); glutSolidSphere(5,10,10); glDisable( GL_LIGHT1 ); glPopMatrix(); # Position the earth's moon glRotatef($earthMoon,0,0,1); glTranslatef( -10, 0, 0 ); glColor3f(0.5,0.5,0.5); glutSolidSphere(1,10,10); glPopMatrix(); glPushMatrix(); # Position the mars glRotatef($mars,0,0,1); glTranslatef( -80, 0, 0 ); glColor3f(1,0,0); glutSolidSphere(4,10,10); glPopMatrix(); glPushMatrix(); # Position the jupiter glRotatef($jupiter,0,0,1); glTranslatef( -120, 0, 0 ); glColor3f(0.6,0.6,0.6); glutSolidSphere(9,10,10); glPushMatrix(); # Position the jup's moon1 glRotatef($jups1,0,0,1); glTranslatef( -6, 0, 0 ); glColor3f(0.5,0.5,0.5); glutSolidSphere(1,10,10); glPopMatrix(); glPushMatrix(); # Position the jup's moon2 glRotatef($jups2,0,0,1); glTranslatef( -8, 0, 0 ); glColor3f(0.5,0.5,0.5); glutSolidSphere(1,10,10); glPopMatrix(); glPushMatrix(); # Position the jup's moon3 glRotatef($jups3,0,0,1); glTranslatef( -10, 0, 0 ); glColor3f(0.5,0.5,0.5); glutSolidSphere(1,10,10); glPopMatrix(); glPushMatrix(); # Position the jup's moon4 glRotatef($jups4,0,0,1); glTranslatef( -12, 0, 0 ); glColor3f(0.5,0.5,0.5); glutSolidSphere(1,10,10); glPopMatrix(); glPopMatrix(); glPushMatrix(); # Position the saturn glRotatef($saturn,0,0,1); glTranslatef( -150, 0, 0 ); glColor3f(0.5,0.5,0.5); glutSolidSphere(8,10,10); glRotatef(-$saturn,0,0,1); glRotatef(14, 0.707, -0.707, 0); # What is the actual tilt? glScalef(1,1,0.2); # Giving smaller values makes it white?! eval {glutSolidTorus(4.5,13,10,10)}; glPopMatrix(); glPopMatrix(); glutSwapBuffers(); } glutInit(); glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH ); glutCreateWindow('Planets Example'); glutDisplayFunc(\&display); glutReshapeFunc(\&resizeHandler); #glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glEnable( GL_DEPTH_TEST ); glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0 ); glEnable( GL_COLOR_MATERIAL ); glLightModelfv( GL_LIGHT_MODEL_AMBIENT, pack 'f4', 0.1, 0.1, 0.1, 1); while ( sleep(0.1) ) { glutMainLoopEvent(); $mercury += 1/0.24; $mercury -= 360 if $mercury >= 360; $venus += 1/0.62; $venus -= 360 if $venus >= 360; $earthMoon += 12.36; # Relative to sun-earth line $earthMoon -= 360 if $earthMoon >= 360; $earthspin += 3.65; # 1/100 of real $earthspin -= 360 if $earthspin >= 360; $earth += 1; $earth -= 360 if $earth >= 360; $venus += 1/0.62; $venus -= 360 if $venus >= 360; $mars += 1/1.88; # Wrong $mars -= 360 if $mars >= 360; $jupiter += 1/11.86; $jupiter -= 360 if $jupiter >= 360; $jups1 += -1/11.86 + 365.2/1.77; $jups1 -= 360 if $jups1 >= 360; $jups2 += -1/11.86 + 365.2/3.55; $jups2 -= 360 if $jups2 >= 360; $jups3 += -1/11.86 + 365.2/7.16; $jups3 -= 360 if $jups3 >= 360; $jups4 += -1/11.86 + 365.2/16.69; $jups4 -= 360 if $jups4 >= 360; $saturn += 1/29.46; $saturn -= 360 if $saturn >= 360; glutPostRedisplay(); }