ManuelRomero/grafica/ej1

Practica 2

 * Enunciado
 * Se trata de realizar de forma diferente el mismo dibujo
 * Vamos a dibujar un disco o agujero de tres formas diferentes
 * Obtenemos la misma imagen, pero de la forma real nos permite modificar facilmente su aspecto

Imagen:OpenGEPractica2.png
 * Observamos el escenario

Crear un nuevo proyecto
Archivo ==> Nuevo ==> Proyecto Seleccionamos Proyecto vacío
 * Creamos un nuevo proyecto según hemos visto en el capítulo anterior
 * Ponemos nombre al proyecto
 * Seleccionamos la opción crear directorio para la solución

Creamos el proyecto
Imagen:VCPPNuevoArchivo3.png Imagen:VCPPNuevoArchivo4.png
 * Ahora creamos un nuevo archivo fuente para nuestro proyecto
 * Para ello abrimos la venta Explorador de soluciones
 * Esta ventana muestra la estructura de directorios creada para nuestra solución o proyecto
 * En él seleccionamos la carpeta de Archivo de código fuente y con el botón derecho creamos un nuevo fichero
 * Pegamos el fuente que se nos ha facilitado en la práctica.

Explicación del fuente

 * A continuación se va a explicar el código que genera el escenario anterior
 * Por ser esta práctica la primera se explicará de forma detallada
 * de esta forma servirá para empezar a entender cómo usar OpenGL en programación

Cabecera

 * definimos bibliotecas stardar de C++
 * Se incluye la biblioteca para usar glut
 * Todas las funciones que empiecen por glut serán de esta biblioteca
 * Constantes
 * 1) PI para operaciones matemáticas
 * 2) N el número de vértices para el límite de un disco
 * Se define un namespace para el proyecto


 * Variables globales que son estáticas y por lo tanto inicializadas

Programa principal

 * El programa principal de nuestra aplicación es el siguientes

Rutinas de inicialización de OpenGL y GLUT
Ver referencia web en página oficial
 * Los primeros métodos de la librería glut se invocan al principio
 * Sirven para inicalizar la librería.
 * void glutInit(int *argcp, char **argv);
 * Inicializa la librería GLUT para que pueda usar una sesión con el sistema de ventanas. En caso de que no se pueda retorna un error
 * argcp Es un puntero a la variable argc del main (ver ''int main(char* argv, int argc); Sirve para poder pasar de la línea de comandos valores para GLUT
 * argcv Igual que en el caso anterior, pero ahora a la variable argv del main.


 * Toma los valores que le pasamos al main y se los envía a la bibliteca de GLUT
 * void glutInitDisplayMode(unsigned int mode);
 * Establece el modo de visualización incial.

http://www.opengl.org/documentation/specs/glut/spec3/node12.html#SECTION00033000000000000000 *El int que retorna servirá para identificar la ventana
 * Este valor por defecto es RGBA (colores básicos y el canal Alpha)
 * Se pueden concatenar bits para especificar el modo de visualización. ver la siguiente lista de valores posibles
 * En nuestro caso el método es invocado glutInitDisplayLaod(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
 * 1) GLUT_SINGLE establece un single buffered window.
 * 2) GLUT_RGB es como GLUT_RGBA establece este mode de visualización
 * 3) GLUT_DEPTH establece buffer de profundidad (para que objetos de adelante oculten a los de atrás, sin que éstos desaparezcan de la escena)
 * void glutInitWindowSize(int width, int height);
 * void glutInitWindowPosition(int x, int y);
 * Establecen el tamaño y la posición inicial de la ventana cuando es creada con el método glutCreateWindow(...) 
 * int glutCreateWindow(char *name);
 * Crea la ventana de nivel superior de nuestra aplicación.
 * el parámetro name será el título de la ventana
 * Este valor se puede usar al invocar al método glutSetWindow.

Nuestro código

 * Una vez inicializado el entorno vienen nuestra acciones
 * El el programa principal son las siguientes invocaciones
 * void printInteraction(void)
 * Se imprime un mensaje por la pantalla para interactuar con el usuario.
 * Este contenido va a la consola no a la ventana windows
 * es código c++ (objetos de la clase iostream)
 * Por ello hay que hacer el include de la clase iostream
 * El código de esta parte quedaría


 * void glutDisplayFunc(void (*func)(void));
 * glutDisplayFunc Carga la funcion pasada como parámetro en la ventana de window actual
 * void glutReshapeFunc(void (*func)(int width, int height));
 * glutReshapeFunc vuelve a dibujar la ventana de window con la función que recibe como parámetro
 * void glutKeyboardFunc(void (*func)(unsigned char key,int x, int y));
 * glutKeyboardFunc Asigna el callback del teclado a la ventana actual de windows,
 * cuando presionemos una tecla la función pueda recoger el valor y reaccionar ante el evento

glutMainLoop hace que glut entre en su blucle de procesamiento
 * void glutMainLoop(void);
 * Esta función no retorna una vez invocada
 * Sí que se invocarán a las fucniones que previamente han sido registradas.

El contenido de nuestro código

 * glClearColor
 * Es una función propia de OpenGl como todas las que empiezan por gl
 * La función glClearColor(float red, float green, flota green, float alpha)
 * Especifica el color que pasamos como argumentos con el que se borrara el buffer al hacer un glClear.
 * Los parámetros son valores reales entre 0 y 1
 * Los tres primeros espefician el color
 * El cuarto es el nivel de transparencia canal alpha.


 * Ahora es cuando vamos a hacer funcionar nuestro código
 * glColor3f(float red, float green, float blue);
 * Estableciendo un color, previamente borramos el que hubiera
 * void glPolygonMode(	GLenum face,GLenum mode);
 * especifica el modo de rasterización de los polígonos,
 * el parámetro face En este caso GL_FILL hace que todo el área del polígono se rellene.
 * Otras opciones GL_POINT o GL_LINE
 * Dibujando el círculo o disco

Discos sobredibujados

 * drawDisc(float radio ,float x, float y, float z)
 * Dibuja un disco con un radio con un espesor y orientación, y una posición (x,y,z)
 * Esta sección dibujaría dos circulos uno negro y pequeño (10 de radio)y otro rojo y grando (20 de radio)
 * Ambos con el mismo centro (25,75,0)
 * Observar la coordenada z a 0 hace que estén a la misma profundidad, por lo que el orden en el que se dibuja es importante (primero el grande y luego el pequeño)
 * La consecuencia es que el pequeño se superpone al grande

Usando el Z-buffer o test de profundidad

 * En este caso con la componente z hacemos que uno esté por delante del otro
 * Peviamente habilitamos el test de profundidad para que un objeto que esté por delante de otro lo oculte


 * En este caso da lo mismo el orden en el que dibujemos los discos

Dibujando realmente un disco

 * En esta caso vamos a dibujar una serie de vértices que vamos a contectar entre ellos
 * Así generaremos la forma deseada
 * isWire es un booleano que actualizamos al tocar la tecla de espacio
 * 1) true se visualiza en el polígono formado sólo líneas GL_LINES
 * 2) fasle se visualiza el polígono formado relleno GL_FILL
 * 1) glBegin(tipoPrimitiva).. glEnd
 * Esta estructura permite definir una primitiva


 * Primitivas geométricas básicas
 * 1) GL_POINTS
 * 2) GL_LINES
 * 3) GL_LINES_STRIP
 * 4) GL_LINE_LOOP
 * 5) GL_TRIANGLES
 * 6) GL_TRIANGLES_STRIP
 * 7) GL_QUADS
 * 8) GL_QUADS_STRIPS
 * También existen primitivas de objetos predeterminados
 * 1) glutWireSphere(radius, slices, stacks) glutSolidSphere(radius, slices, stacks)
 * 2) glutWireCube(size) glutSolidCube(size)
 * 3) glutWireCone(base,height, slices, stacks) glutSolidCone(base,height, slices, stacks)
 * 4) glutWireDodecahedron(void) glutSolidDodecahedron(void)
 * 5) glutWireOctahedron(void) glutSolidOctahedron(void)
 * 6) glutWireTetrahedron(void) glutWireTetrahedron(void)
 * 7) GL_POLYGON

Funcion de remodelado

 * Esta funcion se ejecuta cada vez que tengamos que volver a cargar la pantalla
 * Aquí es donde aplicamos las matrices para ajustar nuestro modelo
 * Es importante entender estas funciones
 * void glViewport(GLint x, GLint y, GLsizei w, GLsizei h);
 * permite definur un viewport.


 * x, y es la esquina inferior izquierda del rectángulo, con respecto a la esquina inferior izquirda de la ventana.
 * w,h son la anchura y la altura de nuestra ventana
 * glMatixMode(GL_MODELVIEW)
 * glLoadIdentity;
 * Inicializamos la matriz de transformación.
 * Todas las transformaciones que hagamos son acumulativas y se van quedando en esta matriz
 * Al cargar la matriz identidad glLoadIdentity gargamos la matriz identidad que es el elemento neutro de la multiplicación