miércoles, 13 de noviembre de 2013

Algoritmos

1. ALGORITMO DDA PARA GENERACIÓN DE LÍNEAS
ANALIZADOR DIFERENCIAL DIGITAL
El Algoritmo DDA es un algoritmo de línea de conversión de rastreo que se basa en el cálculo ya sea en el incremento de X o en el incremento de Y. La finalidad de este algoritmo es determinar los valores enteros correspondientes más próximos a la trayectoria de la línea para la otra coordenada.
Como todos saben Open GL es una herramienta que nos facilita mucho la generación de gráficos por computadora. Aquí aplicamos conocimientos matemáticos, usando Open GL para generar rectas, circunferencias, elipses, etc.
Es un algoritmo preciso para la generación de líneas de rastreo que convierte mediante rastreo las líneas al utilizar solo cálculos incrementales con enteros que se pueden adaptar para desplegar circunferencias y curvas. Los ejes verticales muestran las posiciones de rastreo y los ejes horizontales identifican columnas de pixel.
CÓDIGO:
void DDA(int x0,int y0,int xFin,int yFin)
{
int dx = xFin - x0, dy = yFin - y0, steps, k;
float xIncremento, yIncremento;
float x = x0, y = y0;
if (fabs (dx) > fabs (dy))steps = fabs (dx);
/* |m|<1>elsesteps = fabs (dy);
/* |m|>=1 */xIncremento=float(dx)/float (steps);
yIncremento = float (dy) / float (steps);
setPixel (round (x), round (y));
for (k = 0; k <>; k++)
{
x += xIncremento;y += yIncremento;setPixel (round (x), round (y));
}
}


ALGORITMO DE BRESENHAM PARA TRAZAR LÍNEAS
El algoritmo de Bresenham es un algoritmo creado para dibujar rectas en los dispositivos de gráficos rasterizados, como por ejemplo un monitor de ordenador, que determina qué pixeles se rellenarán, en función de la inclinación del ángulo de la recta a dibujar.
El algoritmo sería el siguiente:
Si 0<|m|<1
  *Se capturan los extremos de la línea y se almacena el extremo izquierdo en (x0,y0).
  *Se carga (x0,y0) en el bufer de estructura (se traza el primer punto)
  *Se calculan las constantes Δx,Δy, 2Δy y 2Δy-Δx y se obtiene el valor inicial para el
    parametro de decisión p0=2Δy-Δx.
  Para j=0 mientras j<Δx
  *En cada xk a lo largo de la línea, que inicia en k=0 se efectúa la prueba siguiente:
      Si pk<0
          *Trazamos (xk+1,yk).
          *Asignamos pk+1= pk+2Δy.
      Sino
          *Trazamos (xk+1,yk+1).
          *Asignamos pk+1= pk+2Δy-2Δx.
  Fin Para
Si |m|>1
   *Recorremos la dirección en pasos unitarios y calculamos los valores sucesivos de x que se aproximen más a la trayectoria de la línea.





Algoritmo de Bresenham para trazar circunferencias
Una circunferencia se define como un conjunto de puntos que se encuentran, en su totalidad, a una distancia determinada r de una posición central.
Es posible reducir el cálculo al considerar la simetría de las circunferencias, la forma de la circunferencia es similar entre cuadrantes y simétrica entre octantes.
Para aplicar el método del punto medio, definimos una función de circunferencia como:
pk = fcircunferencia(x,y)= x2 + y2 − r2fcircunferencia(x,y)<0 si (x,y) está dentro de la frontera de la circunferencia.
fcircunferencia(x,y)=0 si (x,y) está en la frontera de la circunferencia.
fcircunferencia(x,y)>0 si (x,y) está fuera de la frontera de la circunferencia.
Los parámetros de decisión sucesivos se obtienen al utilizar cálculos incrementales.
El algoritmo será el siguiente:
 *Se capturan el radio r y el centro de la circunferencia (xc, yc).
 *Se obtiene el primer punto de la circunferencia centrada en origen (xc, yc) como (0, r).
 *Se calcula el valor inicial del parámetro de decisión como p0=5/4 - r.
 Para k=0 hasta x>=y incrementa k
    Si pk < 0
       *Siguiente punto de la circunferencia con centro (0,0) es (xk+1, yk).
       *pk+1=pk+2xk+1+1.
    Sino
        *Siguiente punto de la circunferencia con centro (0,0) es (xk+1, yk-1).
       *pk+1=pk+2xk+1+1-2yk+1.
    //Donde 2xk+1=2xk+2  y  2yk+1=2yk-2




CÓDIGO:

void Bres(int x0,int y0,int xFin,int yFin)
{
int dx = fabs(xFin - x0),dy = fabs(yFin - y0);
int p = 2 * dy - dx;
int dosDy = 2 * dy,dosDyMenosDx = 2 * (dy - dx);int x, y;
/* Determinamos que punto usamos como inicio. */
if (x0 > xFin) {x = xFin;y = yFin;
xFin = x0;
}
Else
 {
x = x0;
y = y0;
}
setPixel (x, y);
while
 (x <>x++;
if (p <>p += dosDy;
else
 {
y++;
p += dosDyMenosDx;
}
setPixel (x, y);
}
}


martes, 15 de octubre de 2013

Cubo rubik

CUBO RUBIK


Enlace Traducido



DISNEY DESARROLLA UN ALGORITMO PARA LA PRESTACIÓN DE FUNCIONES TÁCTILES 3D EN SUPERFICIES TÁCTILES

 
Disney investigadores han desarrollado un algoritmo para la representación táctil de características y texturas tridimensionales ( 3D ) . Al alterar la fricción encontrada en forma de deslizamiento punta de los dedos de un usuario a través de la superficie , el algoritmo de Disney crea una percepción de un bache en 3D en una superficie táctil sin tener que desplazarse físicamente a la superficie.

" Si podemos extender artificialmente la piel en un dedo mientras se desliza en la pantalla táctil , el cerebro se deje engañar en pensar un golpe físico real es en una pantalla táctil , aunque la superficie táctil es completamente lisa ", dice Disney investigador Ivan Poupyrev .

Durante las pruebas , los investigadores utilizaron electrovibración para modular la fricción entre el dedo deslizante y la superficie de contacto con fuerzas electrostáticas . Además , los investigadores crearon y validaron un modelo psicofísico que simula estrechamente las fuerzas de fricción percibidas por el dedo humano cuando se desliza sobre un bache real.

"Con nuestro algoritmo no tenemos uno o dos efectos , sino un conjunto de controles que permitan ajustar los efectos táctiles a un artefacto visual específica sobre la marcha ", señala Disney Ali Israr .

Los investigadores están presentando sus trabajos en el Simposio ACM de software de interfaz de usuario y la tecnología esta semana en St. Andrews , Escocia

 
Un nuevo algoritmo permite a los investigadores de Disney para crear la representación táctil de funciones 3D y texturas.
 

martes, 8 de octubre de 2013

Glosario

Método (informática)

En la programación orientada a objetos, un método es una subrutina cuyo código es definido en una clase y puede pertenecer tanto a una clase, como es el caso de los métodos de clase o estáticos, como a un objeto, como es el caso de los métodos de instancia. Análogamente a los procedimientos en los lenguajes imperativos, un método consiste generalmente de una serie de sentencias para llevar a cabo una acción, un juego de parámetros de entrada que regularán dicha acción o, posiblemente, un valor de salida (o valor de retorno) de algún tipo.


TÉCNICA

Es un procedimiento o conjunto de reglas, normas o protocolos que tiene como objetivo obtener un resultado determinado, ya sea en el campo de las ciencias, de la tecnología, del arte, del deporte, de la educación o en cualquier otra actividad.

GEOMETRÍA ANALÍTICA

La geometría analítica estudia las figuras geométricas mediante técnicas básicas del análisis matemático y del álgebra en un determinado sistema de coordenadas. Su desarrollo histórico comienza con la geometría cartesiana, continúa con la aparición de la geometría diferencial de Carl Friedrich Gauss y más tarde con el desarrollo de la geometría algebraica.

GEOMETRIA DESCRIPTIVA

La geometría descriptiva es un conjunto de técnicas geométricas que permite representar el espacio tridimensional sobre una superficie bidimensional. Por tanto, mediante «lectura» adecuada posibilita resolver problemas espaciales en dos dimensiones de modo que se garantiza la reversibilidad del proceso.

TOPOLOGIA                 

Es la rama de las matemáticas dedicada al estudio de aquellas propiedades de los cuerpos geométricos que permanecen inalteradas por transformaciones continuas.1 Es una disciplina que estudia las propiedades de los espacios topológicos y las funciones continuas.

 

TEORÍA DE CONJUNTOS

La teoría de conjuntos es una rama de las matemáticas que estudia las propiedades de los conjuntos: colecciones abstractas de objetos, consideradas como objetos en sí mismas. Los conjuntos y sus operaciones más elementales son una herramienta básica en la formulación de cualquier teoría matemática.

ANÁLISIS NUMÉRICO

El análisis numérico o cálculo numérico es la rama de las matemáticas que se encarga de diseñar algoritmos para, a través de números y reglas matemáticas simples, simular procesos matemáticos más complejos aplicados a procesos del mundo real.


ESTRUCTURA DE DATOS

En programación, una estructura de datos es una forma de organizar un conjunto de datos elementales con el objetivo de facilitar su manipulación. Un dato elemental es la mínima información que se tiene en un sistema.

CALCULO VECTORIAL

El cálculo vectorial o análisis vectorial es un campo de las matemáticas referidas al análisis real multivariable de vectores en 2 o más dimensiones. Es un enfoque de la geometría diferencial como conjunto de fórmulas y técnicas para solucionar problemas muy útiles para la ingeniería y la física.


MÉTODOS MATRICIALES

El método matricial de la rigidez es un método de cálculo aplicable a estructuras hiperestáticas de barras que se comportan de forma elástica y lineal. En inglés se le denomina direct stiffness method (DSM, método directo de la rigidez), aunque también se le denomina el método de los desplazamientos.

CAD

El diseño asistido por computadora, más conocido por sus siglas inglesas CAD (computer-aided design), es el uso de un amplio rango de herramientas computacionales que asisten a ingenieros, arquitectos y diseñadores.

CAM

La fabricación asistida por computadora (en Hispanoamérica) o fabricación asistida por ordenador (en España), también conocida por las siglas en inglés CAM (computer-aided manufacturing), implica el uso de computadores y tecnología de cómputo para ayudar en la fase directa de manufactura de un producto, es un puente entre el Diseño Asistido por Computadora CAD y el lenguaje de programación de las máquinas herramientas con una intervención mínima del operario.

Objeto CPU / CODIGO

 
 
 
#include <GL/glut.h>
#include <stdlib.h>
GLfloat ang = 1.0;
GLfloat ejex=0.5, ejey=0.5, escalar=1.0;


void reshape (int width,int height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-15,15,15,-15,15,-15);
glMatrixMode(GL_MODELVIEW);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();

glRotatef(ang, 2.0f, 0.0f, 0.0f);

glTranslatef(ejex,0.0f,0.0f);
glScalef(escalar, escalar, escalar);
//base

glColor3f(1,0,0);
glBegin(GL_POLYGON);

glVertex3f(0,0,4);
glVertex3f(0,6,4);
glVertex3f(4,6,0);
glVertex3f(4,0,4);
//glVertex3f(0,0,4);


glEnd();


//primer cara
glColor3f(0,1,0);
glBegin(GL_POLYGON);

glVertex3f(0,0,4);
glVertex3f(0,0,0);
glVertex3f(8,0,0);
glVertex3f(4,0,4);

glEnd();

//segunda cara
glColor3f(0,0,1);
glBegin(GL_POLYGON);

glVertex3f(0,6,4);
glVertex3f(0,10,0);
glVertex3f(8,10,0);
glVertex3f(4,6,0);


glEnd();
//tercer cara
glColor3f(1,0,1);
glBegin(GL_POLYGON);
glVertex3f(0,0,4);
glVertex3f(0,0,0);
glVertex3f(0,6,4);
glVertex3f(0,0,4);

glEnd();

//cuarta cara
glColor3f(1,1,0);
glBegin(GL_POLYGON);
glVertex3f(4,0,4);
glVertex3f(8,0,0);
glVertex3f(8,10,0);
glVertex3f(4,6,0);
glEnd();

glColor3f(1,0,0);
glBegin(GL_LINE_STRIP);
glVertex3f(0,5,3);
glVertex3f(0,4,3);
glVertex3f(3,5,0);
glVertex3f(3,4,0);

glEnd();

glColor3f(1,0,0);
glBegin(GL_LINE_STRIP);
glVertex3f(0,0,2);
glVertex3f(0,0,3);
glVertex3f(3,0,2);
glVertex3f(3,0,3);

glEnd();
glutSwapBuffers();
ang+=0.1f;
}
void piramide()

{

/* Idle callback, spin cube 2 degrees about selected axis */

ang += 2;

if( ang > 360 ) ang -= 360;


glutPostRedisplay();
}

void init()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glClearColor(0,0,0,0);
}
void idle()
{
display();
}
void ArrowKey(int key, int x, int y){
switch (key){
case GLUT_KEY_RIGHT:
if( ejex<8.0 ){ejex = ejex + 0.5;}//para moverse en la coordenada +x
if(ejex>0.1 && ejex<3){escalar = ejex;}
break;

case GLUT_KEY_LEFT:
if( ejex>-8.0 ){ejex = ejex - 0.5;}//para moverse en la coordenada -x
if(ejex>0.1 && ejex<3){escalar = ejex;}
break;
}


}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;}
}
int main (int argc,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glEnable(GL_DEPTH_TEST);
glutInitWindowPosition(50,50);
glutInitWindowSize(500,500);
glutCreateWindow("Hello");

glutIdleFunc(piramide);

init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutKeyboardFunc(keyboard);
glutSpecialFunc(ArrowKey);
glutMainLoop();
return 0;

}
 

lunes, 7 de octubre de 2013

Modelados


MODELADO GEOMÉTRICO

Los modelos gráficos también se les conocen como modelos geométricos, debido a que las partes componentes de un sistema se representan con entidades geométricas como líneas, polígonos o circunferencias de modo que el término modelo se refiere a una representación geométrica generada por la computadora.

Describen componentes con propiedades geométricas inherentes y por lo tanto se presentan en forma natural a la representación gráfica. Formas entre los que se puede representar un modelo geométrico:

 

EJEMPLOS

Formas entre los que se puede representar un modelo geométrico:

 

· Distribución espacial y forma de los componentes y otros componentes que afectan a la apariencia de los componentes.

· Conectividad de los componentes.              

· Los valores de datos específicos para la aplicación.

 

 


 

 

MODELADO DE SUPERFICIE.

Es la estimación de los valores de una superficie en cualquiera de sus puntos, partiendo de un conjunto de datos de muestreo (x, y, z), denominados puntos de control.

 EJEMPLOS

 

 

 


 

 

APLICACIONES:

 

* Geología.

* Geofísica.

* Meteorología.

* Ingeniería Ambiental.

* Economía.

* Medicina.

 

Las herramientas modelado de superficies de MicroStation le permiten crear todo tipo de superficies, desde las más sencillas hasta superficies complejas B-spline y, si es necesario, mallas. Por ejemplo, puede empezar con una superficie sencilla y, a continuación, modificarla y manipularla hasta conseguir la forma poligonal que desee.

Otras herramientas le permiten crear un “armazón” a partir de perfiles o secciones y a continuación cubrirlo con una superficie o también puede extraer y girar una superficie a partir de un perfil.

El modelo algebraico describe un sólido a partir de su frontera. (Conjunto de superficies que separa el sólido de la parte del espacio no ocupada por el). La frontera se puede ver como la piel del sólido. Obviamente cualquier superficie no determina un sólido. Para que un conjunto de superficies describan un sólido deben satisfacer la siguiente propiedad Encierra un volumen.

La piel es cerrada, orientada y completa. Que la piel sea cerrada y esté orientada permite determinar si un punto está dentro del sólido, y por tanto obtener el modelo topológico.  

MODELADO DE SÓLIDO.

El modelado de sólidos es una rama del modelado geométrico que hace énfasis en la aplicabilidad general de modelos, e insiste únicamente en la creación de representaciones “completas” de objetos físicos sólidos, esto es, representaciones que son adecuadas para la respuesta de preguntas geométricas arbitrarias de manera algorítmica.

El objetivo de la aplicabilidad general, separa al modelado de sólidos de otros tipos de modelado geométrico, los cuales están enfocados hacia propósitos especiales. Los modelos gráficos (Graphical Models) intentan describir un  dibujo de un objeto más que el objeto en sí mismo.

Los modelos de forma (Shape Models) representan una imagen de un objeto. Estos modelos pueden ser colecciones no estructuradas de elementos de imagen, o pueden tener alguna estructura interna para proporcionar operaciones de procesamiento de la imagen. Los modelos de superficie (Surface Models) proporcionan información detallada de una superficie curva, pero no siempre dan suficiente información para determinar todas las propiedades geométricas de un objeto limitado por la superficie.

El modelado de sólidos es el conjunto de teorías, técnicas y sistemas orientados a la representación “completa en cuanto a información” de sólidos. Dicha representación debe permitir (al menos en principio) calcular automáticamente cualquier propiedad bien conocida de cualquier solido almacenado.

Con los sólidos representados necesitaremos, además de visualizarlos y editarlos, calcular sus propiedades físicas (por ejemplo su peso o su centro de gravedad), y simular sobre ellos procesos físicos (como la transmisión de calor en su interior).

Antes de plantearnos como realizar la representación, es necesario concretar cuáles son los objetos a representar. Es decir, formalizar lo que entenderemos por sólido. Hay dos aproximaciones diferentes al problema, una que caracteriza al sólido como un conjunto de puntos 3D, conocida como modelo topológico o de conjunto de puntos, y otra que caracteriza matemáticamente al solido a partir de la superficie que lo delimita, esto es, su piel o frontera.

De este modo estableceremos un sistema de representación con tres niveles: sólidos físicos, modelos matemáticos de sólidos y representaciones.

 

EJEMPLOS:

BLOQUE:Origen, altura, anchura, profundidad.

 •CILINDRO: Origen, radio y longitud.

 •CONO: Origen, radio base, radio superior y altura.

 •ESFERA: Centro y radio (diámetro).

 •CUÑA: Origen, altura anchura y profundidad de la base.

 •TORO: Centro, radio interno y radio externo.


 


 

jueves, 26 de septiembre de 2013

Actividad Transformaciones


SECUENCIA EN QUE SE APLICAN LAS TRANSFORMACIONES

Estas transformaciones se aplican siempre sobre la matriz activa, que seleccionamos con la instrucción glMatrixMode. El orden con que se aplican estas transformaciones es importante, no es lo mismo aplicar una translacion y posteriormente un rotación que el orden inverson rotacion y translación.

El orden en que se aplican las transformaciones en OpenGL es al contrario de lo que parece intuitivo a primera vista. Por ejemplo:

glLoadIdentity();

glTranslatef(0.5, 0.5, 1.0);

glRotatef(45.0, 1.0, 1.0, 1.0)


glBegin(GL_TRIANGLE);

glVertex3f(0.0, 0.0, 0.0);

glVertex3f(1.0, 0.0, 0.0);

glVertex3f(0.0, 1.0, 0.0);

glEnd();

 

Primero carga la matriz identidad, luego multiplica por una matriz de translacion y por ultimo una de rotación. El resultado es que primero rota el triangulo y posteriormente lo traslada, esto es debido a que las multiplicaciones las realiza por el lado derecho:

I·R·T·vertice = (I·(R·(T·vertice)))
El vertice primero lo multiplica por la matriz T (de translacion) luego por R y finalmente por I.

La lectura se realiza de abajo arriba, hasta encontrar una funcion glLoadIdentity o glLoadMatrix. Las transformaciones que haya despues de la primitiva de dibujado glBegin - glEnd no se tienen en cuenta porque la primtiva ya ha sido renderizada.

Si deseamos realizar multiplicaciones por la izquierda de una matriz N podemos aplicar el siguiente método:

leer la matriz actual M

cargar la identidad

multiplicar por la nueva transformacion N

multiplicar por la matriz M

 
En OpenGL seria:
 

GLFloat fMatrizM[16];

glLoadMatrixf(fMatrizM);

glLoadIdentity();

glMultMatrixf(fMatrizN), glTranslatef(x, y, z), glScalef(sx, sy, sz) o glRotatef(ang, x, y, z);

glMultMatrixf(fMatrizM);

BIBLIOGRAFIA

http://dmi.uib.es/~josemaria/OpenGL/Transformaciones.html

Actividad Pilas / Programas Rotacion OpenGL


CONCEPTO DE PILA

Una pila (stack en inglés) es una lista ordenada o estructura de datos en la que el modo de acceso a sus elementos es de tipo LIFO (del inglés Last In First Out, último en entrar, primero en salir).

Las pilas suelen emplearse en los siguientes contextos:

 Evaluación de expresiones en notación postfija (notación polaca inversa).

 Reconocedores sintácticos de lenguajes independientes del contexto

 Implementación de recursividad.

PARA QUE NOS SIRVEN?

Permite almacenar y recuperar datos. Esta estructura se aplica en multitud de ocasiones en el área de informática debido a su simplicidad y ordenación implícita de la propia estructura.

Para el manejo de los datos se cuenta con dos operaciones básicas: apilar (push), que coloca un objeto en la pila, y su operación inversa, retirar (o desapilar, pop), que retira el último elemento apilado.

En cada momento sólo se tiene acceso a la parte superior de la pila, es decir, al último objeto apilado (denominado TOS, Top of Stack en inglés). La operación retirar permite la obtención de este elemento, que es retirado de la pila permitiendo el acceso al siguiente (apilado con anterioridad), que pasa a ser el nuevo TOS.

Por analogía con objetos cotidianos, una operación apilar equivaldría a colocar un plato sobre una pila de platos, y una operación retirar a retirarlo.

MANEJO DE PILAS EN OPENGL

PILA DE MATRICES

En algunos casos nos puede interesar guardar la transformación que tenemos en la matriz activa para posteriormente recuperarla, por ejemplo si deseamos renderizar un coche formado por la carroceria y cuatro ruedas. El coche entero tendra una transformación para colocarlo en el lugar (translacion + rotacion) y cada una de las ruedas tendra una transformación de rotación y transformación adicional que la colocara en relación al sistema de coordenadas del coche, para no tener que aplicar la misma transformación del coche a cada rueda podemos almacenarla en una pila y posteriormente recuperarla. Ejemplo:


glPushMatrix(); // Guardamos la transformacion del mundo
glTranslatef(cocheX, cocheY, cocheZ);
glRotatef(angulo, ejeX, ejeY, ejeZ);
RenderCarroceria();

glPushMatrix(); // Guardamos la transformacion del coche
glTranslatef(rueda1X, rueda1Y, rueda1Z);
glRotatef(anguloRueda1, eje1X, eje1Y, eje1Z);
RenderRueda();
glPopMatrix(); // Recuperamos la transformacion del coche

glPushMatrix();
glTranslatef(rueda2X, rueda2Y, rueda2Z);
glRotatef(anguloRueda2, eje2X, eje2Y, eje2Z);
RenderRueda();
glPopMatrix();

glPushMatrix();
glTranslatef(rueda3X, rueda3Y, rueda3Z);
glRotatef(anguloRueda3, eje3X, eje4Y, eje3Z);
RenderRueda();
glPopMatrix();
glPushMatrix();
glTranslatef(rueda4X, rueda4Y, rueda4Z);
glRotatef(anguloRueda4, eje4X, eje4Y, eje4Z);
RenderRueda();
glPopMatrix();

glPopMatrix(); // Recuperamos la transformacion del mundo

Disponemos de una pila de matrices para cada una de las matrices existentes: MODELVIEW, PROJECTION y TEXTURE.
 
PROGRAMAS ROTACION
 
#include "stdafx.h"

#include <stdlib.h>

#include <GL/glut.h>
GLfloat anguloCuboX = 0.0f;
GLfloat anguloCuboY = 0.0f;
GLfloat anguloEsfera = 0.0f;
GLint ancho=400;
GLint alto=400;
int hazPerspectiva = 0;
void reshape(int width, int height)
{
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
    if(Perspectiva)
     gluPerspective(60.0f, (GLfloat)width/(GLfloat)height, 1.0f, 20.0f);
    else

      glOrtho(-4,4, -4, 4, 1, 10);

    glMatrixMode(GL_MODELVIEW);
    ancho = width;
    alto = height;
}
void drawCube(void)
{
    glColor3f(1.0f, 0.0f, 0.0f);
    glBegin(GL_QUADS);      
    glVertex3f(-1.0f, -1.0f,  1.0f);
    glVertex3f( 1.0f, -1.0f,  1.0f);
    glVertex3f( 1.0f,  1.0f,  1.0f);
    glVertex3f(-1.0f,  1.0f,  1.0f);

    glEnd();

    glColor3f(0.0f, 1.0f, 0.0f);

    glBegin(GL_QUADS);       
    glVertex3f( 1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f,  1.0f, -1.0f);
    glVertex3f( 1.0f,  1.0f, -1.0f);

    glEnd();

    glColor3f(0.0f, 0.0f, 1.0f);
 
    glBegin(GL_QUADS);       
    glVertex3f(-1.0f,-1.0f, -1.0f);
    glVertex3f(-1.0f,-1.0f,  1.0f);
    glVertex3f(-1.0f, 1.0f,  1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glEnd();

    glColor3f(1.0f, 1.0f, 0.0f);
 
    glBegin(GL_QUADS);      
    glVertex3f(1.0f, -1.0f,  1.0f);
    glVertex3f(1.0f, -1.0f, -1.0f);
    glVertex3f(1.0f,  1.0f, -1.0f);
    glVertex3f(1.0f,  1.0f,  1.0f);
    glEnd(); 
    glColor3f(0.0f,      1.0f, 1.0f);
 
    glBegin(GL_QUADS);      
    glVertex3f(-1.0f, 1.0f,  1.0f);
    glVertex3f( 1.0f, 1.0f,  1.0f);
    glVertex3f( 1.0f, 1.0f, -1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glEnd();
    glColor3f(1.0f, 0.0f, 1.0f);
 
    glBegin(GL_QUADS);     
    glVertex3f( 1.0f,-1.0f, -1.0f);
    glVertex3f( 1.0f,-1.0f,  1.0f);
    glVertex3f(-1.0f,-1.0f,  1.0f);
    glVertex3f(-1.0f,-1.0f, -1.0f);
    glEnd();
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -5.0f);
    glRotatef(anguloCuboX, 1.0f, 0.0f, 0.0f);
    glRotatef(anguloCuboY, 0.0f, 1.0f, 0.0f);
    drawCube();
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -5.0f);
    glRotatef(anguloEsfera, 0.0f, 1.0f, 0.0f);
    glTranslatef(3.0f, 0.0f, 0.0f);
    glColor3f(1.0f, 1.0f, 1.0f);
    glutWireSphere(0.5f, 8, 8);
    glFlush();
    glutSwapBuffers();
    anguloCuboX+=0.1f;
    anguloCuboY-=0.1f;
    anguloEsfera+=0.2f;
}

void init()
{
    glClearColor(0,0,0,0);
    glEnable(GL_DEPTH_TEST);
    ancho = 400;
    alto = 400;
}

void idle()
{
    display();
}
void keyboard(unsigned char key, int x, int y)
{
    switch(key)
    {
    case 'p':
    case 'P':
      Perspectiva=1;
      reshape(ancho,alto);
      break;
    case 'o':
    case 'O':
      Perspectiva=0;
      reshape(ancho,alto);
      break;
    case 27:   // escape
      exit(0);
      break;
    }
}
int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(ancho, alto);
    glutCreateWindow("Cubo 1");
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
    glutKeyboardFunc(keyboard);
    glutMainLoop();
    return 0;
}




#include "GL/gl.h"
#include "gpu940.h"


#include <math.h> //necesario para la función gluPerspective



void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
void draw();


Nuestra función principal, main()
Aquí inicializamos OpenGL y configuramos algunos parámetros, así como la matriz de proyección


int main()
{
glOpen(DEPTH_BUFFER); // Inicializa el OpenGL
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Especifica el color que se usará para borrar la pantalla (rojo, verde, azul, alpha)
glClearDepth(1.0f);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST); // Activamos el test de profundidad
glShadeModel(GL_SMOOTH); // Sombreado suave
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); // Correción de perspectiva
glMatrixMode(GL_PROJECTION); //Cambiamos a la matriz de proyección...
glLoadIdentity(); //Y la reseteamos
gluPerspective(45.0f,(GLfloat)320/(GLfloat)240,0.1f,100.0f); // Esta función la definiremos más adelante
glMatrixMode(GL_MODELVIEW); //Cambiamos a la matriz de modelado

while(true) // Este bucle se ejecutara indefinidamente, por lo que no podremos terminar la aplicación sin matarla
{
draw(); // Función definida por nosotros para dibujar
glSwapBuffers(); // Intercambia los buffers y muestra uno en pantalla. Esto es así porque usamos double buffer
};

glClose(); 

return 0;
}




void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar){
GLdouble top, bottom, left, right;
top = zNear * tan(pi180*fovy/2);
bottom = -top;
right = aspect*top;
left = -right;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(left, right, bottom, top, zNear, zFar);
glMatrixMode(GL_MODELVIEW);
}


void draw()
{
static GLfloat xrot=0; //variables estáticas para guardar la rotación del cubo
static GLfloat yrot=0;
static GLfloat zrot=0;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //limpiamos la pantalla
glLoadIdentity(); // reseteamos
glTranslatef(0.0f,0.0f,-5.0f); // Nos desplazamos un poco

glRotatef(xrot,1.0f,0.0f,0.0f); //
glRotatef(yrot,0.0f,1.0f,0.0f); // Rotamos en cada eje según nuestras variables de rotación
glRotatef(zrot,0.0f,0.0f,1.0f); //


glBegin(GL_QUADS); // Comenzamos a dibujar polígonos de cuatro vértices

glVertex3f(-1.0f, -1.0f, 1.0f); //Primer vértice del primer polígono
glVertex3f( 1.0f, -1.0f, 1.0f); //Segundo vértice
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);

glVertex3f(-1.0f, -1.0f, -1.0f); //Primer vértice del segundo polígono
glVertex3f(-1.0f, 1.0f, -1.0f); //Segundo vértice
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);

glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);

glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);

glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);

glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);

glEnd(); // Terminamos con los polígonos de cuatro vértices

xrot+=1.3f; // Modificamos las variables de rotación
yrot+=1.2f;
zrot+=1.4f;

}