root/samples/glut/glut_example.php

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. CreateEnvironment
  2. Display
  3. MakeGeometry
  4. MakeLighting
  5. MakeCamera
  6. HandleKeyboard
  7. HandleSpecialKeyboard
  8. HandleMouse
  9. HandleMainMenu
  10. HandleSpeedMenu
  11. HandleVisibility
  12. HandleIdle
  13. DrawTextXY
  14. GiveUsage

<?php

        /*

                Converted example from http://astronomy.swin.edu.au/pbourke/historical/glut/



                Original Author Paul Bourke <pbourke@swin.edu.au>



                Converted to PHP by Markus Fischer <mfischer@guru.josefine.at>

        */

        error_reporting(E_ALL);

        define('DRAFT',         0);
        define('MEDIUM',        1);
        define('BEST',          2);

        $drawquality = DRAFT;
        $spincamera = TRUE;
        $cameradirection = 1;
        $updownrotate = 60.0;
        $ballbounce = TRUE;
        $ballspeed = 2.0;

        foreach(array('OVALID', 'SPHEREID', 'BOXID', 'PLANEID', 'TEXTID') as $i => $const)
                define($const, $i+1);

        for ($i=1;$i<$argc;$i++) {
                if (strstr($argv[$i],"-h") != NULL) 
                        GiveUsage($argv[0]);
                if (strstr($argv[$i],"-q") != NULL) {
                        if ($i+1 >= $argc)
                                GiveUsage($argv[0]);
                        $drawquality = $argv[$i+1];
                        if ($drawquality < DRAFT)
                                $drawquality = DRAFT;
                        if ($drawquality > BEST)
                                $drawquality = BEST;
                        $i++;
                }
        }

   /* Set things up and go */
   glutInit($argv);
   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
   glutCreateWindow("OpenGL Demo");
   glutDisplayFunc('Display');
   glutVisibilityFunc('HandleVisibility');
   glutKeyboardFunc('HandleKeyboard');
   glutSpecialFunc('HandleSpecialKeyboard');
   glutMouseFunc('HandleMouse');
   CreateEnvironment();

   /* Set up some menus */
   $speedmenu = glutCreateMenu('HandleSpeedMenu');
   glutAddMenuEntry("Slow",1);
   glutAddMenuEntry("Medium",2);
   glutAddMenuEntry("fast",3);
   $mainmenu = glutCreateMenu('HandleMainMenu');
   glutAddMenuEntry("Toggle camera spin",1);
   glutAddMenuEntry("Toggle ball bounce",2);
   glutAddSubMenu("Ball speed",$speedmenu);
   glutAddMenuEntry("Quit",100);
   glutAttachMenu(GLUT_RIGHT_BUTTON);

   glutMainLoop();
   exit;

        /*

           This is where global settings are made, that is, 

           things that will not change in time 

        */
        function CreateEnvironment() {
                global $drawquality;

                glEnable(GL_DEPTH_TEST);
                if ($drawquality == DRAFT)
                glShadeModel(GL_FLAT);
                if ($drawquality == MEDIUM)
                        glShadeModel(GL_SMOOTH);
                if ($drawquality == BEST) {
                        glEnable(GL_LINE_SMOOTH);
                        glEnable(GL_POINT_SMOOTH);
                        glEnable(GL_POLYGON_SMOOTH); 
                        glShadeModel(GL_SMOOTH);    
                        glDisable(GL_DITHER);         /* Assume RGBA capabilities */
                }

                glLineWidth(1.0);
                glPointSize(1.0);
                glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
                glFrontFace(GL_CW);
                glDisable(GL_CULL_FACE);
                glClearColor(0.0,0.0,0.0,0.0);         /* Background colour */
                glEnable(GL_COLOR_MATERIAL);
        }

        /*

           This is the basic display callback routine

           It creates the geometry, lighting, and viewing position

           In this case it rotates the camera around the scene

        */
        function Display() {

                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                glPushMatrix();
                MakeCamera(FALSE,0,0);
                MakeLighting();
                MakeGeometry();
                glPopMatrix();

                /* glFlush(); This isn't necessary for double buffers */
                glutSwapBuffers();
        }

        /*

                Create the geometry

        */
        function MakeGeometry() {
                global $drawquality, $ballbounce, $ballspeed;
                static $theta = 0.0;

                $radius = 0.5;
                $mshin1 = array(5.0);               /* For the sphere */
                $mspec1 = array(0.5,0.5,0.5,1.0);
                $mdiff1 = array(0.6,0.0,0.6,1.0);
                $mamb1  = array(0.1,0.0,0.1,1.0);
                $mdiff2 = array(0.0,1.0,0.0,1.0);   /* Green plane */
                $mamb2  = array(0.0,0.2,0.0,1.0);
                $mdiff3 = array(0.5,0.5,0.5,1.0);  /* Grey boxes */
                $mamb3  = array(0.2,0.2,0.2,1.0);

                /* Create a green ground plane */
                glLoadName(PLANEID);
                if ($drawquality > DRAFT)
                        glBegin(GL_POLYGON);
                else
                        glBegin(GL_LINE_LOOP);
                glColor3f(0.0,1.0,0.0);
                if ($drawquality > DRAFT) {
                        glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE, $mdiff2);
                        glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT, $mamb2);
                }
                glNormal3f( 0.0, 1.0, 0.0);
                glVertex3f( 2.0, 0.0, 2.0);
                glVertex3f( 2.0, 0.0,-2.0);
                glVertex3f(-2.0, 0.0,-2.0);
                glVertex3f(-2.0, 0.0, 2.0); 
                glEnd();

                /* Place a few grey boxes around the place */
                glLoadName(BOXID);
                glColor3f(0.5,0.5,0.5);
                if ($drawquality > DRAFT) {
                        glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE, $mdiff3);
                        glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT, $mamb3);
                }
                glPushMatrix();
                glTranslatef(1.8,0.2,1.8);
                if ($drawquality > DRAFT)
                        glutSolidCube(0.4);
                else
                        glutWireCube(0.4);
                glTranslatef(-3.6,0.0,0.0);
                if ($drawquality > DRAFT)
                        glutSolidCube(0.4);
                else
                        glutWireCube(0.4);
                glPopMatrix();

                /* Create a magenta bouncing ball */
                glLoadName(SPHEREID);
                glColor3f(0.6,0.0,0.6);
                if ($drawquality > DRAFT) {
                        glMaterialfv(GL_FRONT,GL_SHININESS,$mshin1);
                        glMaterialfv(GL_FRONT,GL_SPECULAR,$mspec1);
                }
                glPushMatrix();
                glTranslatef(0.0,$radius+0.5*(1+sin(M_PI*$theta/180)),0.0);
                glScalef($radius,$radius,$radius);
                if ($ballbounce)
                        $theta += $ballspeed;
                if ($drawquality > DRAFT)
                        glutSolidSphere(1.0,16,16);
                else
                        glutWireSphere(1.0,32,32);
                glPopMatrix();
   
                /* Create a white half-oval loop at one end */
                glLoadName(OVALID);
                glBegin(GL_LINE_STRIP);
                glColor3f(1.0,1.0,1.0);
                glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
                for ($i=0;$i<=180;$i++)
                        glVertex3f(2*cos($i*M_PI/180),1.5*sin($i*M_PI/180),-2.0);
                glEnd();

                /* Write some text */
                glLoadName(TEXTID);
                DrawTextXY(-2.0,-0.25,2.0,0.002,"PHP OpenGL Demo");
        }

        /*

           Set up the lighing environment

        */
        function MakeLighting() {
                global $drawquality;

                $globalambient = array(0.3,0.3,0.3,1.0);

                /* The specifications for 3 light sources */
                $pos0 = array(1.0,1.0,0.0,0.0);      /* w = 0 == infinite distance */
                $dif0 = array(0.8,0.8,0.8,1.0);

                $pos1 = array(5.0,-5.0,0.0,0.0);   /* Light from below */
                $dif1 = array(0.4,0.4,0.4,1.0);      /* Fainter */

                if ($drawquality > DRAFT) {

                        /* Set ambient globally, default ambient for light sources is 0 */
                        glLightModelfv(GL_LIGHT_MODEL_AMBIENT,$globalambient);

                        glLightfv(GL_LIGHT0,GL_POSITION,$pos0);
                        glLightfv(GL_LIGHT0,GL_DIFFUSE,$dif0);

                        glLightfv(GL_LIGHT1,GL_POSITION,$pos1);
                        glLightfv(GL_LIGHT1,GL_DIFFUSE,$dif1);

                        glEnable(GL_LIGHT0);
                        glEnable(GL_LIGHT1);
                        glEnable(GL_LIGHTING);
                }
        }
        

        /*

           Set up the camera

           Optionally creating a small viewport about 

           the mouse click point for object selection

        */
        function MakeCamera($pickmode,$x,$y) {
                global $updownrotate, $spincamera, $cameradirection;
                static $theta = 0;

                $viewport = array();

                /* Camera setup */
                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                if ($pickmode == TRUE) {
                        glGetIntegerv(GL_VIEWPORT, $viewport); /* Get the viewport bounds */
                        gluPickMatrix($x,$viewport[3]-$y,3.0,3.0,$viewport);
                }
                gluPerspective(70.0,          /* Field of view */
                           1.0,          /* aspect ratio  */
                       0.1,1000.0);  /* near and far  */

                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(5*cos($theta*M_PI/180)*sin($updownrotate*M_PI/180),
                     5*cos($updownrotate*M_PI/180),
                 5*sin($theta*M_PI/180)*sin($updownrotate*M_PI/180), 
                     0.0,0.0,0.0,                                   /* Focus    */
                 0.0,1.0,0.0);                                  /* Up       */
                if ($spincamera)
                        $theta += ($cameradirection * 0.2);
        }

        /*

           Deal with plain key strokes

        */
        function HandleKeyboard($key,$x,$y) {
                global $spincamera, $ballbounce;

                switch (ord($key)) {
                        case 27: /* ESC */
                        case ord('Q'):
                        case ord('q'): exit(); break;
                        case ord('s'):
                        case ord('S'): $spincamera = !$spincamera; break;
                        case ord('b'):
                        case ord('B'): $ballbounce = !$ballbounce; break;
                }
        }

        /*

           Deal with special key strokes

        */
        function HandleSpecialKeyboard($key,$x,$y) {
                global $updownrotate, $cameradirection;

                switch ($key) {
                        case GLUT_KEY_LEFT:  $cameradirection = -1; break;
                        case GLUT_KEY_RIGHT: $cameradirection = 1;  break;
                        case GLUT_KEY_UP:    $updownrotate -= 2;  break;
                        case GLUT_KEY_DOWN:  $updownrotate += 2;  break;
                }
        }

        /*

           Handle mouse events

        */
        function HandleMouse($button,$state,$x,$y) {
        
                $maxselect = 100;
                $nhits = 0;
                $selectlist = array();

                if ($state == GLUT_DOWN) {
                        glSelectBuffer($maxselect);
                        glRenderMode(GL_SELECT);
                        glInitNames();
                        glPushName(-1);

                        glPushMatrix();
                        MakeCamera(TRUE,$x,$y);
                        MakeGeometry();
                        glPopMatrix();
                        $nhits = glRenderMode(GL_RENDER);

                        if ($button == GLUT_LEFT_BUTTON) {

                        } else if ($button == GLUT_MIDDLE_BUTTON) {

                        } /* Right button events are passed to menu handlers */

                        if ($nhits == -1)
                                error_log("Select buffer overflow");

                        $selectlist = glGetSelectBuffer();
                        #var_dump($selectlist);

                        if ($nhits > 0) {
                                echo "\tPicked $nhits objects: ";
                                for ($i=0;$i<$nhits;$i++)
                                        echo $selectlist[4*$i+3] . " ";
                                echo "\n";
                        }
                }
        }

        /*

           Handle the main menu

        */
        function HandleMainMenu($whichone) {
                global $spincamera, $ballbounce;

                switch ($whichone) {
                        case 1: $spincamera = !$spincamera; break;
                        case 2: $ballbounce = !$ballbounce; break;
                        case 100: exit(); break;
                }
        }

        /*

           Handle the ball speed sub menu

        */
        function HandleSpeedMenu($whichone) {
                global $ballspeed;
                
                switch ($whichone) {
                        case 1: $ballspeed = 0.5; break;
                        case 2: $ballspeed = 2;   break;
                        case 3: $ballspeed = 10;  break;
                }
        }

        /*

           How to handle visibility

        */
        function HandleVisibility($visible) {

                if ($visible == GLUT_VISIBLE)
                        glutIdleFunc('HandleIdle');
                else
                        glutIdleFunc(array());
        }

        /*

           What to do on an idle event

        */
        function HandleIdle() {

                glutPostRedisplay();
        }

        /*

           Draw text in the x-y plane

           The x,y,z coordinate is the bottom left corner (looking down -ve z axis)

        */
        function DrawTextXY($x,$y,$z,$scale,$s) {

                glPushMatrix();
                glTranslatef($x,$y,$z);
                glScalef($scale,$scale,$scale);
                for ($i=0;$i<strlen($s);$i++)
                        glutStrokeCharacter(GLUT_STROKE_ROMAN,$s[$i]);
                glPopMatrix();
        }

        /*

           Display the program usage information

        */
        function GiveUsage($cmd) {

                echo <<<USAGE
Usage:    $cmd [-h] [-q n]
          -h   this text
          -q n quality, 0,1,2

Key Strokes and Menus:
           q - quit
           s - toggle camera spin
           b - toggle ball bounce
  left arrow - change rotation direction
 right arrow - change rotation direction
  down arrow - rotate camera down
    up arrow - rotate camera up

USAGE;
                        exit;
                }

/* [<][>][^][v][top][bottom][index][help] */