#!/usr/local/bin/perl

# Uncomment this to run the example without installing the
# built modules. 

#sub BEGIN
#  {
#    push @INC, ("./OpenGL",
#                "./OpenGL/blib/arch",
#                "./OpenGLU",
#                "./OpenGLU/blib/arch",
#                "./GLUT",
#                "./GLUT/blib/arch");
#  }


use OpenGL;
use OpenGLU;
use GLUT;

use vars qw(
	    $idling
	    $x0 $y0
	    $dx $dy
	    $xrot; $yrot;
	    $rotscale;
	    );

&execute;

sub execute
  {
    $rotscale = .01;
    $xrot = 0;
    $yrot = 0;
    $idling = 0;
    glutInit;
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH|GLUT_RGBA);
    glutCreateWindow("OpenGL Perl Scripting!");
    glClearColor(0,0,1,1);
    glMatrixMode(GL_PROJECTION);
    gluPerspective(60, 1, 1, 3);
    glMatrixMode(GL_MODELVIEW);
    glTranslatef(0,0,-1.5);
    glutDisplayFunc(\&display);
    glutKeyboardFunc(\&key);
    glutMotionFunc(\&motion);
    glutMouseFunc(\&mouse);

    glEnable(GL_DEPTH_TEST);

    my $texture;
    my $i;
    for($i = 0; $i < 256; $i++)
      { $texture .= pack("f", abs(sin($i/255.0*6.28))); }
    glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 256, 0, GL_LUMINANCE, GL_FLOAT, $texture);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    glEnable(GL_TEXTURE_1D);

    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    glTexGenfv(GL_S, GL_EYE_PLANE, pack("f*", 1, 1, 1, 0));

    glEnable(GL_TEXTURE_GEN_S);

    glutMainLoop();
  }    

sub motion
  {
    my ($x, $y) = @_;
    if($idling & 1)
      {
	$dx = ($x - $x0) * $rotscale;
	$dy = ($y - $y0) * $rotscale;
      }
    
  }

sub mouse
  {
    my ($b, $s, $x, $y) = @_;
    
    if($b == GLUT_LEFT_BUTTON)
      {
	if($s == GLUT_DOWN)
	  {
	    if($idling == 0) { glutIdleFunc(\&idle); }
	    $idling |= 1;
	    $x0 = $x;
	    $y0 = $y;
	  }
	else
	  {
	    $idling &= ~1;
	    if($idling == 0) { glutIdleFunc(undef); }	    
	  }
      }
  }

sub idle
  {
    if($idling & 1)
      {
	$xrot -= $dy;
	$yrot += $dx;
      }
    glutPostRedisplay();
  }

sub display
  {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
    glRotatef($xrot,1,0,0);
    glRotatef($yrot,0,1,0);
    glColor3f(1,0,0);

    glutSolidSphere(.3,10,10);

    glBegin(GL_QUADS);
      {
	glTexCoord1f(0);
	glVertex2f(-.5, -.5);
	glTexCoord1f(.333);	
	glVertex2f( .5, -.5);
	glTexCoord1f(.667);	
	glVertex2f( .5,  .5);
	glTexCoord1f(1);	
	glVertex2f(-.5,  .5);
      }
    glEnd();
    glPopMatrix();
    glutSwapBuffers();
  }

sub key
  {
    my ($k, $x, $y) = @_;
    
    if($k == 27) { exit(0); }
    elsif(chr $k eq 'c')
      {
	print "Enter commands:\n";
	my ($cmd, $done) = ("", 0);
	while(! $done)
	  {
	    $cmd = <>;
	    chop $cmd;
	    if(length $cmd != 0)
	      { eval $cmd; }
	    else
	      { $done = 1; }
	  }
	glutPostRedisplay();
      }
  }
