domingo, 23 de marzo de 2014

Sistema Planetario

El trabajo que se presenta a continuación es una recopilación de varios de los trabajos presentados a lo largo de todo el blog.
El objetivo principal consiste en dibujar una serie de esferas que simulen un sistema planetario. Para lo cual debe permitir que los planetas giren alrededor de un eje en común, en este caso un sol. Cada planeta a su vez tendrá una luna, la cual también deberá girar alrededor del mismo.
Para realizar estos movimientos, debe mantenerse presionada una tecla, para este caso será la letra a para trasladar los planetas alrededor del sol y la letra s para girar las lunas alrededor de los planetas.
El código final utilizado quedó de la siguiente manera:
--------------------------------------------------------------------------------------------
/*
 Sáenz Morales Carlos Giovanni
 */

#include <GL/gl.h>
 #include <GL/glu.h>
 #include <GL/glut.h>

int anio=0, dia=0, luna=0;
int anio1=0, dia1=0, luna1=0;
int anio2=0, dia2=0, luna2=0;
int anio3=0, dia3=0, luna3=0;
int angulo_z= 10;
int angulo_z1= 220;
int angulo_z2= 50;
int angulo_z3= 70;

 void init(void){
     glClearColor (0.0, 0.0, 0.0, 0.0);
     glShadeModel (GL_FLAT);
 }

 void display(void){
     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glClearDepth(1.0);
     glColor3f (1.0, 1.0, 0.0);// color del sol
     glPushMatrix();

         glutWireSphere(0.7, 20, 16);/* Dibuja el Sol */
         glRotatef (angulo_z, 0.0, 0.0, 1.0);    //angulo constante de inclinacion en z
         glRotatef ((GLfloat)anio, 0.0, 1.0, 0.0);    //angulo segun el numero de años
         glTranslatef (3.0, 0.0, 0.0);    //Distancia entre el sol y el primer planeta

         glPushMatrix();
             glRotatef ((GLfloat) dia, 0.0, 1.0, 0.0);    //angulo del planeta segun el dia
             glColor3f (0.0, 0.0, 1.0);                 // color del planeta
             glutWireSphere(0.3, 10, 8);                /* Dibuja el primer planeta */

         glPopMatrix();
         glRotatef (25, 0.0, 0.0, 1.0);               //Angulo constante de la luna respecto al primer planeta
         glRotatef ((GLfloat) luna, 0.0, 1.0, 0.0);   //Angulo de la luna segun la hora
         glTranslatef (0.5, 0.0, 0.0);                //Distancia de la luna respecto al primer planeta
         glColor3f (0.7, 0.7, 0.7);
         glutWireSphere(0.07, 10, 8);                 // dibuja la luna del primer planeta

     glPopMatrix();
     //glutSwapBuffers();

     //Segundo planeta
     glPushMatrix();
         glRotatef (angulo_z1, 0.0, 1.0, 0.0);    //angulo constante de inclinacion en z
         glRotatef ((GLfloat)anio1, 0.0, 0.0, 1.0);    //angulo segun el numero de años
         glTranslatef (0.0, 2.0, 0.0);    //Distancia entre el sol y el segundo planeta

         glPushMatrix();
             glRotatef ((GLfloat) dia1, 0.0, 0.0, 1.0);    //angulo del planeta segun el dia
             glColor3f (1.0, 0.0, 0.0);                 // color del planeta
             glutWireSphere(0.2, 10, 8);                /* Dibuja el segundo planeta */

         glPopMatrix();
         glRotatef (25, 0.0, 1.0, 0.0);               //Angulo constante de la luna respecto al segundo planeta
         glRotatef ((GLfloat) luna1, 0.0, 0.0, 1.0);   //Angulo de la luna segun la hora
         glTranslatef (0.0, 0.4, 0.0);                //Distancia de la luna respecto al segundo planeta
         glColor3f (0.5, 0.5, 0.5);
         glutWireSphere(0.06, 10, 8);                 // dibuja la luna del segundo planeta

     glPopMatrix();

     //Tercer planeta
      glPushMatrix();
         glRotatef (angulo_z2, 1.0, 0.0, 0.0);    //angulo constante de inclinacion en z
         glRotatef ((GLfloat)anio2, 1.0, 0.0, 0.0);    //angulo segun el numero de años
         glTranslatef (0.0, 0.0, 2.0);    //Distancia entre el sol y el segundo planeta

         glPushMatrix();
             glRotatef ((GLfloat) dia1, 1.0, 0.0, 0.0);    //angulo del planeta segun el dia
             glColor3f (0.6, 0.2, 0.7);                 // color del planeta
             glutWireSphere(0.4, 10, 8);                /* Dibuja el segundo planeta */

         glPopMatrix();
         glRotatef (25, 0.0, 1.0, 0.0);               //Angulo constante de la luna respecto al segundo planeta
         glRotatef ((GLfloat) luna1, 1.0, 0.0, 0.0);   //Angulo de la luna segun la hora
         glTranslatef (0.0, 0.0, 0.6);                //Distancia de la luna respecto al segundo planeta
         glColor3f (0.9, 0.9, 0.9);
         glutWireSphere(0.08, 10, 8);                 // dibuja la luna del segundo planeta

     glPopMatrix();

     //Cuarto planeta
     glPushMatrix();
         glRotatef (angulo_z3, 0.0, 0.0, 1.0);    //angulo constante de inclinacion en z
         glRotatef ((GLfloat)anio3, 0.0, 1.0, 0.0);    //angulo segun el numero de años
         glTranslatef (3.0, 0.0, 0.0);    //Distancia entre el sol y el primer planeta

         glPushMatrix();
             glRotatef ((GLfloat) dia3, 0.0, 1.0, 0.0);    //angulo del planeta segun el dia
             glColor3f (0.0, 1.0, 0.8);                 // color del planeta
             glutWireSphere(0.3, 10, 8);                /* Dibuja el primer planeta */

         glPopMatrix();
         glRotatef (25, 0.0, 0.0, 1.0);               //Angulo constante de la luna respecto al primer planeta
         glRotatef ((GLfloat) luna3, 0.0, 1.0, 0.0);   //Angulo de la luna segun la hora
         glTranslatef (0.5, 0.0, 0.0);                //Distancia de la luna respecto al primer planeta
         glColor3f (1.0, 1.0, 1.0);
         glutWireSphere(0.07, 10, 8);                 // dibuja la luna del primer planeta

     glPopMatrix();
     glutSwapBuffers();
 }

 void keyInput(unsigned char key,int x, int y){
    switch(key){
        case 27:
        case 'q':
            exit(0);
        break;
        case 'a':
            anio=anio+2;
            anio1=anio1+5;
            anio2=anio2+2;
            anio3=anio3+5;
        break;
        case 'd':
            dia=dia+2;
            dia1=dia1+5;
            dia2=dia2+2;
            dia3=dia3+5;
        break;
        case 's':
            luna=luna+2;
            luna1=luna1+5;
            luna2=luna2+2;
            luna3=luna3+5;
        break;
    }
    glutPostRedisplay();
}

 void reshape (int w, int h){
     glViewport (0, 0, (GLsizei) w, (GLsizei) h);
     glMatrixMode (GL_PROJECTION);
     glLoadIdentity ();
     gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     gluLookAt (0.0, 1.0, 6.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
 }


 int main(int argc, char** argv){
     glutInit(&argc, argv);
     glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
     glutInitWindowSize (500, 500);
     glutInitWindowPosition (100, 100);
     glutCreateWindow (argv[0]);
     init ();
     glutDisplayFunc(display);
     glutKeyboardFunc(keyInput);
     glutReshapeFunc(reshape);

     glutMainLoop();
     return 0;
 }
---------------------------------------------------------------------------------
Al final, en la ejecución del programa, podemos obtener una secuencia de imágenes como la siguiente:

Práctica.- Menú básico

Esta práctica es una conjunción entre dos de loas trabajos subidos en este blog.
En primer lugar se utilizan las funciones del ratón. Y en segundo lugar se dibujan figuras predeterminadas.
El objetivo fundamental consiste en hacer clic derecho en determinado punto de la pantalla. Acto seguido debe desplegarse un menú en el cual existe la opción de seleccionar un figura para después dibujarla en la pantalla sobre el mismo punto en el que se ha hecho clic.
El código es el siguiente:
---------------------------------------------------------------------------------------------
#include <GL/gl.h>
#include <GL/glut.h>
#include <iostream>
#include <math.h>
#include <stdlib.h>

using namespace std;

#define NP 4000
#define AGE 200

float winWid,winHeight;
int rx,ry;
float valores[50];
int count=0;
int countfig=0;
int figure[20];


void redraw( void ){
      glClearColor(0.0,0.0,0.0,0);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
       glLoadIdentity();
     glColor3f(0.0,0.0,1.0);

        for(int i=0,j=0;i<count;i++,j++){
    glPushMatrix();
      double x=valores[i];
      i++;
      double y=valores[i];
        x=(x-310)/310;
        y=(y-250)/250;

       glTranslatef(x,y,0);
        glColor3f(0.0,0.0,1.0);
     if(figure[j]==1)
       {  glRotatef(60,1,1,0);
           glutWireCube(0.5);

       }
     if(figure[j]==2){
             glRotated(60,1,0,1);
        glutWireSphere(.5,16,16);
     }
     if(figure[j]==3){
      glRotatef(60,1,0,0);
      glutWireTorus(0.1,0.15,12.0,32.0);
     }
     if(figure[j]==4)
       glutWireTeapot(0.1);

     if(figure[j]==5){
      glRotatef(60,1,1,0);
       glutWireCone(0.3,0.5,22.0,5.0);

        }


      glPopMatrix();

    }
    glFlush();
}




void mousebutton(int button, int state, int x, int y){
    cerr << "mousebutton. x:" << x << ", y:" << y << " \n";
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){
        rx = float(x);
        ry = winHeight - float(y);

    }
}
void menu(int opc){
   switch(opc)
     {
    case 1:
     valores[count]=rx;
      count++;
      valores[count]=ry;
      count++;
   figure[countfig]=1;
   countfig++;
        redraw();
        break;
            case 2:
     valores[count]=rx;
      count++;
      valores[count]=ry;

      count++;
   figure[countfig]=2;
   countfig++;
        redraw();
        break;
            case 3:
     valores[count]=rx;
      count++;
      valores[count]=ry;

      count++;
   figure[countfig]=3;
   countfig++;
        redraw();
        break;
            case 4:
     valores[count]=rx;
      count++;
      valores[count]=ry;

      count++;
   figure[countfig]=4;
   countfig++;
        redraw();
        break;

         case 5:
     valores[count]=rx;
      count++;
      valores[count]=ry;

      count++;
   figure[countfig]=5;
   countfig++;
        redraw();
        break;


     }

}


int main(int argc, char *argv[]){
    winWid = 620.0;
    winHeight = 500.0;
    glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
    glutCreateWindow("Hola Mundo");
    glutPositionWindow(200,100);
    glutReshapeWindow(int(winWid),int(winHeight));
    glClearColor(0.0,0.0,0.0,1.0);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0,winWid,0.0,winHeight, -100.0, 100.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glutCreateMenu(menu);
glutAddMenuEntry("Cubo",1);
glutAddMenuEntry("Esfera",2);
glutAddMenuEntry("Dona",3);
glutAddMenuEntry("Tetera",4);
glutAddMenuEntry("Cono",5);

glutAttachMenu(GLUT_RIGHT_BUTTON);

    glutDisplayFunc(redraw);
  //  glutIdleFunc(redraw);
 //   glutMotionFunc(motion);
    glutMouseFunc(mousebutton);
    glutMainLoop();

    return 0;
}
-------------------------------------------------------------------------------------
Una vez implementado, obtendremos un resultado como el que se muestra en la imagen a continuación:

Práctica.- Figuras predeterminadas

La siguiente práctica tiene el propósito de mostrar las diferentes figuras en 3D predeterminadas que vienen por default en las librerías de OpenGL.
El código se presenta a continuación:
------------------------------------------------------------------------------------------
/*
Sáenz Morales Carlos Giovanni
*/

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <iostream>

using namespace std;

void Dibuja(){
    cerr << "Dibuja() \n";
    glClearColor(0,0,0,0);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

/*    glPushMatrix();
    glTranslatef(-0.8,0.8,0.0);
    glColor3f(0.0, 1.0, 0.0);
    glutWireSphere(0.2, 15, 15);
    glPopMatrix();
*/
     /* Este bloque permite que se dibuje la segunda esfera pero borra la primera.. es necesario para trasladar el eje
     glClearColor(0,0,0,0);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    */
    //Sin embrago puede sustituirse por la siguientes lineas


    glPushMatrix(); //Esta linea es para guardar la matriz
    glTranslatef(0.75,0.4,0.0);
    glScalef(1.0, 1.0, 1.0); //Esta linea permite hacer figuras a escala.. en este caso a la mitad
    glRotatef(45, 0, 1, 1); //Esta linea permite rotar la imagen
    glColor3f(0.0, 0.0, 1.0);
    glutWireSphere(0.2, 15, 15);
    glPopMatrix();//Esta otra linea permite cambiar las coordenadas al centro nuevamente

    glPushMatrix();
    glTranslatef(0.75,-0.05,0.0);
    glRotatef(45, 0, 1, 1);
    glScalef(1.0, 1.0, 1.0);
    glColor3f(0.0, 0.0, 1.0);
    glutSolidSphere(0.2,30,30);
    glPopMatrix();
/*
    glPushMatrix();
    glTranslatef(0.8,-0.8,0.0);
    glColor3f(1.0, 0.0, 0.0);
    glutWireSphere(0.2, 15, 15);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-0.5,-0.5,0.0);
    glRotatef(45, 0, 1, 1);
    glScalef(2.0, 2.0, 2.0);
    glColor3f(1.0, 1.0, 1.0);
    glutWireSphere(0.2, 15, 15);
    glPopMatrix();
*/

    glPushMatrix();
    glTranslatef(-0.75,-0.75,0.0);
    glRotatef(90, 0, 1, 1);
    glScalef(2.0, 2.0, 2.0);
    glColor3f(0.0, 1.0, 0.0);
    glutWireCube(0.1);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-0.75,-0.45,0.0);
    glRotatef(90, 0, 1, 1);
    glScalef(2.0, 2.0, 2.0);
    glColor3f(0.0, 1.0, 0.0);
    glutSolidCube(0.1);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-0.3,-0.7,0.0);
    glRotatef(70, 45, 1, 1);
    glScalef(0.5, 0.5, 0.5);
    glColor3f(1.0, 0.0, 0.0);
    glutWireCone(0.2,0.4,15,15);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-0.3,-0.45,0.0);
    glRotatef(70, 45, 1, 1);
    glScalef(0.5, 0.5, 0.5);
    glColor3f(1.0, 0.0, 0.0);
    glutSolidCone(0.2,0.4,15,15);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0.2,-0.75,0.0);
    glRotatef(60, 1, 0, 0);
    glScalef(0.7, 0.7, 0.7);
    glColor3f(1.0, 0.5, 0.0);
    glutWireTorus(0.10,0.15,15,15);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0.2,-0.45,0.0);
    glRotatef(60, 1, 0, 0);
    glScalef(0.7, 0.7, 0.7);
    glColor3f(1.0, 0.5, 0.0);
    glutSolidTorus(0.10,0.15,15,15);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0.7,-0.80,0.0);
    glRotatef(60, 1, 0, 0);
    glScalef(0.1, 0.1, 0.1);
    glColor3f(1.0, 1.0, 0.0);
    glutWireDodecahedron();
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0.7,-0.45,0.0);
    glRotatef(60, 1, 0, 0);
    glScalef(0.1, 0.1, 0.1);
    glColor3f(1.0, 1.0, 0.0);
    glutSolidDodecahedron();
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-0.75,0.4,0.0);
    glRotatef(75, 1, 0, 0);
    glScalef(0.2, 0.2, 0.2);
    glColor3f(1.0, 0.7, 1.0);
    glutWireOctahedron();
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-0.75,0.0,0.0);
    glRotatef(75, 1, 0, 0);
    glScalef(0.2, 0.2, 0.2);
    glColor3f(1.0, 0.7, 1.0);
    glutSolidOctahedron();
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-0.2,0.4,0.0);
    glRotatef(60, 1, 1, 0);
    glScalef(0.3, 0.3, 0.3);
    glColor3f(1.0, 0.7, 0.2);
    glutWireTetrahedron();
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-0.2,-0.05,0.0);
    glRotatef(60, 1, 1, 0);
    glScalef(0.3, 0.3, 0.3);
    glColor3f(1.0, 0.7, 0.2);
    glutSolidTetrahedron();
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0.3,0.4,0.0);
    glRotatef(30, 1, 0, 0);
    glScalef(0.15, 0.15, 0.15);
    glColor3f(0.5, 0.5, 0.5);
    glutWireIcosahedron();
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0.3,0.0,0.0);
    glRotatef(30, 1, 0, 0);
    glScalef(0.15, 0.15, 0.15);
    glColor3f(0.5, 0.5, 0.5);
    glutSolidIcosahedron();
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-0.4,0.8,0.0);
    glRotatef(20, 1, 0, 0);
    glScalef(0.7, 0.7, 0.7);
    glColor3f(0.0, 0.5, 0.0);
    glutWireTeapot(0.3);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0.4,0.8,0.0);
    glRotatef(20, 1, 0, 0);
    glScalef(0.7, 0.7, 0.7);
    glColor3f(0.0, 0.5, 0.0);
    glutSolidTeapot(0.3);
    glPopMatrix();

    glFlush();
}

int main (){
    cerr << "main() \n" ;
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(920, 680);
    glutCreateWindow("");
    glutDisplayFunc(Dibuja);
    glutMainLoop();
}
------------------------------------------------------------------------------------------
Y las figuras que se representan gráficamente son las siguientes:

Práctica.- Eventos del teclado

La práctica que a continuación se presenta se basa en otro trabajo publicado en este blog anteriormente denominado "Francotirador".
El objetivo fundamental es realizar un dibujo en la pantalla y por medio de las teclas, asignar eventos, como por ejemplo, el desplazamiento a través de la pantalla o la posibilidad de poder modificar el tamaño de la figura.
El código del programa quedó de la siguiente manera:
-------------------------------------------------------------------------------------------
/*
Sáenz Morales Carlos Giovanni
*/

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <iostream>

using namespace std;
float valor_x=0.0;
float valor_y=0.0;
double tama=0.1;


void Dibuja(){
    cerr << "Dibuja() \n";
    glClearColor(0,0,0,0);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();


    glPushMatrix();
    glTranslatef(valor_x,valor_y,0.0);
    glutWireTeapot(tama);
    glPopMatrix();

    glFlush();
}

void keyInput(unsigned char key,int x, int y){
    switch(key){
        case 27:
        case 'q':
            exit(0);
        break;
        case '+':
            tama=tama+0.1;
        break;
        case '-':
            tama=tama-0.1;
        break;
    }
    glutPostRedisplay();
}

void specialKeyInput(int key,int x, int y){
    if(key==GLUT_KEY_DOWN){
                valor_y=valor_y-0.1;
                valor_x=valor_x;
        if(valor_y<-1){
            valor_y=1;
        }
        glutPostRedisplay();
    }
    if(key==GLUT_KEY_UP){
                valor_y=valor_y+0.1;
                valor_x=valor_x;
        if(valor_y>1){
            valor_y=-1;
        }

        glutPostRedisplay();
    }
    if(key==GLUT_KEY_LEFT){
                valor_x=valor_x-0.1;
                valor_y=valor_y;
        if(valor_x<-1){
            valor_x=1;
        }

        glutPostRedisplay();
    }
    if(key==GLUT_KEY_RIGHT){
                valor_x=valor_x+0.1;
                valor_y=valor_y;
        if(valor_x>1){
            valor_x=-1;
        }
        glutPostRedisplay();
    }
}

int main (){
    cerr << "main() \n" ;
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(720, 680);
    glutCreateWindow("");
    glutDisplayFunc(Dibuja);
    glutKeyboardFunc(keyInput);
    glutSpecialFunc(specialKeyInput);
    glutMainLoop();

}
-----------------------------------------------------------------------------------------
Como podemos observar, en el código se asignó la tecla q para terminar la ejecución del programa y las teclas + y - para cambiar el tamaño de la figura.
También se acomodó para que la figura no saliera del cuadro, antes bien, se prefiere que al salir por uno de los lados de la pantalla, reaparezca por el lado contrario. Finalmente se obtiene un trabajo como el siguiente:

Práctica.- Francotirador

Esta práctica puede expresarse como una base para desarrollar algún tipo de juego de disparos.
Su objetivo principal es mostrar una marca en algún lugar de la pantalla, sobre la cual, al presionar un tecla se puede dibujar alguna imagen.

El funcionamiento es básicamente con el teclado, aunque también pudiera implementarse con el mouse con una de las prácticas que también se encuentran en este blog. El código utilizado es el siguiente:
---------------------------------------------------------------------------------------------------
/*Sáenz Morales Carlos Giovanni

*/

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <iostream>

using namespace std;
float valor_x=0.0;
float valor_y=0.0;
float vx[10000];
float vy[10000];
int con=0;
double tama=0.02;

void circulo(){
     for(int i=0;i<con;i++)
            {
                glPushMatrix();
                glColor3f(1.0,1.0,1.0);
                glTranslatef(vx[i],vy[i],0.0);
                glutSolidSphere(tama,20,20);
                glFlush();
                glPopMatrix();
            }
}

void Dibuja(){
    cerr << "Dibuja() \n";
    glClearColor(0,0,0,0);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();


    glPushMatrix();
    glBegin(GL_LINES);
    glColor3f(1.0,1.0,1.0);
    glVertex2f(valor_x+0.1,valor_y);
    glVertex2f(valor_x-0.1,valor_y);
    glVertex2f(valor_x,valor_y+0.1);
    glVertex2f(valor_x,valor_y-0.1w);
    glEnd();
    circulo();
    glFlush();
    //glPopMatrix();
}

void keyInput(unsigned char key,int x, int y){
    switch(key){
        case 27:
        case 'a':
            vx[con]=valor_x;
            vy[con]=valor_y;
            con++;
            //for(int i=0;i<con;i++)
            //{
              //  glPushMatrix();
               // glColor3f(1.0,1.0,1.0);
               // glTranslatef(vx[i],vy[i],0.0);
               // glutSolidSphere(tama,20,20);
               // glFlush();
               // glPopMatrix();
            //}

                //glutPostRedisplay();
        break;
        case 'q':
            exit(0);
        break;
        /*case '+':
            tama=tama+0.01;
        break;
        case '-':
            tama=tama-0.01;
        break;*/
    }
}

void specialKeyInput(int key,int x, int y){
    if(key==GLUT_KEY_DOWN){
                valor_y=valor_y-0.05;
                valor_x=valor_x;
        if(valor_y<-1){
            valor_y=1;
        }
        glutPostRedisplay();
    }
    if(key==GLUT_KEY_UP){
                valor_y=valor_y+0.05;
                valor_x=valor_x;
        if(valor_y>1){
            valor_y=-1;
        }

        glutPostRedisplay();
    }
    if(key==GLUT_KEY_LEFT){
                valor_x=valor_x-0.05;
                valor_y=valor_y;
        if(valor_x<-1){
            valor_x=1;
        }

        glutPostRedisplay();
    }
    if(key==GLUT_KEY_RIGHT){
                valor_x=valor_x+0.05;
                valor_y=valor_y;
        if(valor_x>1){
            valor_x=-1;
        }
        glutPostRedisplay();
    }
}

int main (){
    cerr << "main() \n" ;
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(720, 680);
    glutCreateWindow("");
    glutDisplayFunc(Dibuja);
    glutKeyboardFunc(keyInput);
    glutSpecialFunc(specialKeyInput);
    glutMainLoop();

}
----------------------------------------------------------------------
El resultado final muestra inicialmente la marca en el centro. Pero moviendo adecuadamente el apuntador con las flechas del teclado y dibujando con la tecla a se puede dibujar casi cualquier cosa. La siguiente imagen muestra un ejemplo: