martes, 29 de mayo de 2007

Previo 10

Animación esqueletal

Es una técnica de animación por computadora, esta es particularmente usada en la animación de vertebrados, en donde un personaje esta representado en dos partes, una representación superficial usada para dibujar al personaje, llamada la piel, y una construcción jerárquica de huesos usada solo para la animación, a este se le llama el esqueleto.

Esta técnica es usada construyendo una serie de “huesos”, cada hueso tiene una transformación en tres dimensiones, la cual incluye su posición, escala y orientación, y un hueso opcional padre. De esta manera los huesos forman una jerarquía. La trasformada completa de un nodo hijo es el producto de su transformada padre y de su propia transformada. Así que mover el hueso del muslo también moverá el hueso de la pantorrilla. Conforme el personaje es animado, los huesos cambian su transformación mientras pasa el tiempo, bajo la influencia de algunos controles de animación.

Cada hueso del esqueleto esta asociado con alguna porción de la representación visual del personaje. En el caso más común de un personaje poligonal de malla, la malla esta asociado con un grupo de vértices; por ejemplo, en un modelo de un ser humano, el hueso del muslo estará asociado con los vértices que hacen el polígono del modelo del muslo. Porciones de la piel de personaje pueden ser asociadas con múltiples huesos, cada uno teniendo un factor de escala llamado peso del vértice, o peso de la mezcla. El movimiento de la piel cercana a las articulaciones, pueden por lo tanto ser influenciados por los dos huesos.

Para una malla poligonal, cada vértice puede tener un peso de mezcla para cada hueso. Para calcular la posición final del vértice, cada transformada de hueso es aplicada a la posición del vértice. Escalada por su correspondiente peso. Este algoritmo se llama matriz de paleta de piel, porque el conjunto de transformadas de hueso, almacenada como matrices de trasformadas, forman una paleta para cada vértice de la piel para ser elegido.

La animación esqueletal es útil porque permite a los animadores controlar solo aquellas características del modelo que se mueven independientemente. Un personaje no puede mover su parte inferior de la espinilla independientemente de la parte superior. En vez de hace una animación vértice por vértice solo se moverá el hueso y los vértices relacionados s éste. La desventaja de este tipo de animación es que no provee una animación realista de los músculos, para resolver esto se agregan controles especiales del músculo los cuales son adjuntados a los huesos, todo esto para representar el movimiento completo del músculo.

La animación esqueletal es una forma estándar de animar personajes u objetos mecánicos por un tiempo prolongado, generalmente mas de 100 cuadros, es generalmente usado en videojuegos y en la industria cinematográfica, también puede ser aplicada a objetos mecánicos y cualquier otro objeto que tenga elementos rígidos y junturas.


FBX

FBX provee un intercambio universal de recursos 3D, este es un formato de cración e intercambio 3D, independiente de la plataforma y completamente gratuito (mas no libre), el formato de archivo FBX admite los principales elementos de datos 3D, así como elementos 2D, de audio y de medios de video.

En si FBX es un formato combinado entre binario y código ASCII, debido a esto puede soportar, almacenar, convertir y transportar complejas escenas 3D convinado con 2D, como ejemplo de esto es:

· Mallas poligonales y NURBS

· Mapeo de texturas y materiales

· Vértices normales y mapeo de colores por vértice

· Enlaces a los puntos de control

· Múltiples cámaras e intercambio de cámaras

· Múltiples tipos de luces

· Marcadores

· Segmentos de esqueleto (raíz, extremidades y nodos de extremidades)

· Varias tomas en animaciones mocap

· Posiciones enlazadas en una lista de nodos

· Clips de video (incrustado o referenciado)

· Clips de audio (incrustado o referenciado)

· Shaders

Formato X

El formato X es el formato de archivo de DirectX, este formato es una arquitectura y un formato de archivo libre de contexto. Es conducido por plantillas y es libre de cualquier uso. El formato de archivo podrá ser usado por cualquier aplicación de cliente y actualmente esta siendo usado en Direct3D Retained Mode para describir los datos de geometría, jerarquía de cuadros y animación

El formato .X almacena todo en un método jerárquico. Cada nivel de la jerarquía puede tener cualquier número de “objetos” para mantener datos, pero es recomendable solo tener un número pequeño de “objetos” por cada nivel. El “objeto” principal del modelo de jerarquía geométrica es un cuadro. Para animaciones, el “objeto” principal de la jerarquía es una set de animación.

Fuentes:

http://en.wikipedia.org/wiki/Skeletal_animation
http://images.autodesk.com/emea_s_main/files/fbx_whitepaper.pdf
http://local.wasp.uwa.edu.au/~pbourke/dataformats/directx/

martes, 22 de mayo de 2007

Previo 9

1- Investigue acerca de los métodos manuales de animación
- Key frames (cuadros llave)
- Forward Kinematics (cinemática directa)
- Inverse Kinematics (cinemática inversa)
- Motion capture (captura de movimiento)

Key Frames

Los Key Frames son los dibujos principales para definir puntos de inicio y de fin en una transición. Una secuencia de Key Frames define cual movimiento se vera, mientras que la posición de estos en la película definen el tiempo del movimiento. Debido a que los Key Frames definen el movimiento, pero son muy pocos para dar la ilusión de un movimiento continúo por segundo, se agregan marcos llamadas “inbeteweens” o intermedios.

Forward Kinematics

El concepto central de esta animación es las posiciones de partes particulares del modelo en momentos específicos, esto se logra moviendo las articulaciones del modelo del modelo que tengan un
atributo específico. Es decir que si tenemos una construcción con diferentes articulaciones, si se quiere mover alguna, las demás serán afectadas por este movimiento, todo esto tomando en cuanta los grados de libertad de cada articulación, este movimiento se logra cambiando cuadro por cuadro la posición de la articulación deseada.

Inverse Kinematics

Es el proceso de determinar los parámetros de un objeto articulado y flexible con tal de lograr la posición deseada, es decir conocer los ángulos de posición para cada posición del modelo deseado. Esta programación es vital para robótica, programación de videojuegos y animación 3D, estos tres ejemplos llevan el movimiento en un espacio continuo y físico, es decir que no hay marcos y frames, en cambio, el modelo o robot se mueve fluidamente durante toda la animación .


Motion Capture

La captura de movimiento es una técnica para grabar digitalmente movimientos. Se utiliza en la industria del entretenimiento, en los deportes y en la medicina.
Comenzó como una herramienta de análisis fotogramético en investigaciones de biomecánicas en los 1970s y 1980s y se expandió a la educación, entrenamiento de deportes y, recientemente, a la animación por computadora para el cine y los videojuegos, al madurar la tecnología. Un actor utiliza marcadores cerca de cada articulación para identificar el movimiento de las posiciones o los ángulos entre marcas. Las marcas acústicas, inerciales, LED, magnéticas o de reflexión son rastreadas, óptimamente al menos con un índice de al menos el doble del movimiento deseado, a posiciones submilimétricas. El software de computadora de captura de movimiento graba las posiciones, los ángulos, las velocidades, aceleraciones e impulsos, proveyendo así una muy acertada aproximación digital del movimiento.
Existen diversos sistemas de captura de movimiento:



Sistemas ópticos: triangulan la posición en 3D de una marca entre dos o más cámaras calibradas para proveer proyecciones superpuestas. El rastrear un gran número de marcas o de múltiples actores o el expandir el área de captura se logra con la adición de más cámaras. Estos sistemas producen información con 3 grados de libertad para cada marca, y información rotacional debe ser inferida desde orientación relativa de tres o cuatro marcas; por ejemplo, las marcas para el hombro, el codo y la muñeca dado el ángulo del codo.

Sistema óptico pasivo: utilizan marcadores revestidos con material retro-reflexivo que se genera cerca de los lentes de las cámaras. La sensibilidad de las cámaras puede ser ajustada aprovechando el rango estrecho de la mayoría de las cámaras de la sensitividad de la luz para que tan sólo los marcadores brillantes sean capturados, ignorando la piel y la vestimenta.

Marca óptica activa por modulación: los sistemas de marcas activas pueden ser refinados todavía más al encender una marca en un momento o rastrear marcas múltiples en un periodo de tiempo y modulando la amplitud o el ancho de pulso para proveer una identificación para cada marca. Una resolución de sistemas modulados espaciales de 12 mega-píxeles muestra movimientos más sutiles que sistemas ópticos de 4 mega-píxeles puesto que tiene resoluciones temporal y espacial más altas. Los directores pueden ver la actuación de los actores en tiempo real y ver los resultados con un personaje generado por computadora. Los identificadores particulares de cada marca reducen las vueltas eliminando el canjeado de marcas y proveyendo información más limpia que otras tecnologías.

Marca óptica activa: los sistemas de marca activa óptica triangulan las posiciones iluminando un LED a la vez muy rápidamente o múltiples LEDs. El software sofisticado para identificarlos por sus posiciones relativas es similar a la navegación celestial. En vez de reflejar luz que se genera externamente, las marcas por sí mismas tienen la capacidad de emitir su luz propia. Ya que la ley de cuadrado invertido provee 1/4 de potencia al doble de la distancia, esto puede incrementar las distancias y el volumen de la captura.

Sistemas Internos: la tecnología de captura de movimiento interno se basa en sensores inerciales miniatura, modelos biomecánicos y algoritmos de fusión de sensores. Es un método barato y fácil de utilizar para la captura de movimiento de un cuerpo humano entero. La información de movimiento de los sensores inerciales (sistema de guía inercial) se transmite inalámbricamente a una PC o Laptop, donde el movimiento de cuerpo completo se graba o se ve. No hay cámaras externas, emisores o marcas que se necesiten para movimientos relativos, pero para posiciones absolutas, se utilizan sistemas ópticos o magnéticos externos. Los sistemas de captura de movimiento inerciales toman los 6 grados de libertad de movimiento de cuerpo de un humano en tiempo real.

Moción mecánica: estos sistemas rastrean ángulos de articulación del cuerpo directamente y con frecuencia se les llama sistemas de captura de movimiento de exoesqueleto, debido al modo en que los sensores se ajustan al cuerpo. El actor viste una estructura que parece ser un esqueleto sobre su cuerpo y conforme se mueven, también lo hacen las partes mecánicas articuladas, midiendo el movimiento relativo del actor. Los sistemas de captura de movimiento mecánicos son hechos en tiempo real, son relativamente baratos, libres de oclusión e inalámbricos que tiene un volumen de captura ilimitado.

Sistemas magnéticos: calculan la posición y la orientación por su flujo magnético relativo de tres bobinas ortogonales en el transmisor y cada receptor. La intensidad relativa de voltaje o corriente en las tres bobinas le permite a estos sistemas calcular la distancia y la orientación al trazar mapas meticulosos del volumen de rastreo. En particular, estas marcas no son ocluidas por objetos no metálicos, pero son susceptibles a interferencias magnéticas y eléctricas de objetos de metal en el ambiente, como barras de acero en el concreto o cableado, los cuales afectan el campo magnético y las fuentes eléctricas tales como monitores, luces, cables y computadoras. La respuesta del sensor no es lineal, especialmente hacia los extremos del área de captura. El cableado desde los sensores tiende a excluir movimientos extremos.

Captura de actuación: esta técnica difiere de la captura de movimiento estándar debido a la naturaleza interactiva de la actuación, capturando el cuerpo, las manos y las expresiones faciales al mismo tiempo, de modo opuesto a capturar datos para referencia de movimiento y editar los movimientos después. El actor generalmente interactúa con modelos de objetos en la escena. La información de actuación puede ser utilizada para animar diferentes actores.

2- Discuta acerca de las ventajas/desventajas de cada método y dé ejemplos (al menos dos) de situaciones en las que cada uno esté mejor aplicado.

Key Frame

Ventajas: el animador conoce y controla toda la animación, además de la existencia de varios frames repetidos.

Desventajas: el realismo es complicado y los escenarios con un movimiento continuo son complicados.

Ejemplos: utilizado en las caricaturas y en animaciones Flash

Forward Kinematics

Ventajas: el movimiento del modelo es especificado por el animador, no es necesario conocer ninguna consecuencia física hacia el modelo.

Desventajas: el animador debe tener en cuenta todos los movimientos para tener una animación natural

Ejemplos: animaciones 2D y 3D, a veces utilizados en robótica.

Inverse Kinematics

Ventajas: la animación solo requiere de posiciones iniciales y finales para completarse

Desventajas: la física del modelo debe estar bien definida y en los parámetros naturales (a menos que se especifique lo contrario)

Ejemplo: son utilizados en la robótica y en animaciones 3D.

Motion Capture

Ventajas: los resultados son directos y la animación es igual de compleja en cada caso, la física de colisiones en interacción de cuerpos es muy sencilla a comparación de los otros métodos

Desventajas: requiere de un hardware y software específico, este tiene un costo elevado, se requieren de un set especial para la grabación, si la captura es fallida se tendrá que repetir la escena una y otra vez, el movimiento esta limitado a la física de nuestro mundo, no es fácil simular situación de moviendo irreal.

Ejemplos: se usa en películas, por ejemplo Space Jam y en los videojuegos generalmente en los de deportes.


3- Investigue qué método de animación usan los modelos de Quake y de Unreal Tournament. Busque código que utilizando OpenGL permita visualizar un modelo de éstos juegos y ejecútelo.

UNREAL TOURNAMENT

Utiliza un sistema de animación de esqueleto que soporta hasta cuatro influencias de hueso por vértice y esqueletos complejos.
Soporte LOD completo para mallas y huesos.
Herramienta de AnimSet Viewer para animaciones de organización y búsqueda y mallas:
Habilidad para añadir notificaciones específicas al juego en puntos específicos de la animación.
Herramientas para colocar ‘Sockets’ gráficamente en los huesos a ser usados para adjuntar objetos al esqueleto en el juego, completo con vista previa.
Habilidad ver previamente mallas revestidas basadas en el mismo esqueleto (por ejemplo, armadura).
La animación es guiada por un “AnimTree” – un árbol de nodos de animación, que incluye:
Controles mezclados, que desempeñan una mezcla de n modos entre objetos de animación anidada.
Controles manejados por datos, encapsulando captura de movimiento o información de animación a mano.
Controles de física, atando el motor de dinámicas de cuerpo rígido para un jugador de “muñeco de trapo” y animación NPC y respuesta física a impulsos.
Controles de procedimiento de esqueleto, para características del juego, como el tener un la cabeza y los ojos del NPC rastrear al jugador que camina por un nivel.
Una herramienta que resuelve cinemática inversa para calcular las posiciones del miembro basadas en localizaciones globales (por ejemplo, colocación de pies).
AnimTree Editor le permite a los programadores o animadores crear mezclas complejas y ajustes de controles para tener una vista previa de ellos en tiempo real en el editor.
Los tipos de nuevo nodo y de controlador pueden ser añadidos fácilmente para un control específico del juego.
· Herramientas de exportación para 3D Studio Max, Maya y XSI para traer mallas con peso, esqueletos y secuencias de animación al motor.

QUAKE

El motor de Quake (III) carga modelos en 3D en formato MD3. El formato utilizaba vértices de movimiento, contrario a la animación de esqueleto usada para guardar la animación. Las características de animación en el formato MD3 son superiores a las del formato MD2 usado en Quake II, porque un animador puede hacer que el número de key frames por segundo sea menor y mayor que 10 key frames por segundo. Esto permite animaciones más complejas que son menos “temblorosas” que los modelos de Quake II.
Otra característica importante del formato MD3 es que los modelos se descomponen en 3 partes diferentes ancladas la una a la otra. Típicamente, esto se usa para separar la cabeza, el torso y las piernas para que cada parte se pueda mover independientemente en bien de una animación de procedimiento. Cada parte del modelo tiene su propia serie de texturas.
Los modelos de personajes están iluminados y sombreados utilizando sombreado de Gouraud mientras que los niveles (almacenados en formatos BSP) se iluminan ya sea con mapas de luz o sombreado de Gouraud dependiendo de la preferencia del usuario. El motor es capaz de tomar luces de colores del alambrado de luces y aplicarlo a los modelos, resultando en una calidad de luz, la cual fue, para su época, muy avanzada.
El motor es capaz de reproducir tres tipos de sombras. Uno sólo coloca un círculo con extremos desvanecidos en los pies del personaje, mientras que las otras dos modalidades proyectan una sombra poligonal acertada en el piso. La diferencia entre las últimas dos modalidades es la dependencia de sombras negras, opacas y sólidas mientras que el otro tipo intenta (con éxito mezclado) proyectar sombras de volumen de sombra estarcido de profundidad en un medio transparente negro.
Otras características incluyen lenguajes de sombras de alto nivel y un método para desplegar niebla.

Fuentes:

http://en.wikipedia.org/wiki/Key_frame
http://www.cs.jhu.edu/~cohen/RendTech99/Lectures/Computer_Animation.color.pdf
http://www.unrealtechnology.com/html/technology/ue30.shtml

lunes, 14 de mayo de 2007

Tarea 8

LLenado por barrido

Básicamente, el método consiste en :

Recorrer las líneas de barrido desde y=0 hasta y=YMAX (donde YMAX es la máxima coordenada y que se puede encontrar en la pantalla.

Determinar las intersecciones de la línea de barrido con las aristas del polígono, variando x desde 0 hasta XMAX. Para ello se utiliza una función que indica si el pixel actual está iluminado o no con el color de la frontera.

Llamemos bitpantalla a esta función:

int bitpantalla (int x, int y)
{
return getpixel(x, y);
}

La intersección del lado izquierdo del polígono se etiqueta como xinicio y xfin representa al intersección con el lado derecho. Luego se traza una línea

linea(xinicio, y, xfin, y, color)

Algoritmo:

Para cada línea de barrido (y=0,..., YMAX) hacer

1. inicializar x=0
2. mientras (bitpantalla <> color de frontera)
x=x+1
3. xinicio=x
4. mientras (bitpantalla <> color de frontera)
x=x+1
5. xfin=x
6. linea (xinicio, y, xfin, y, color)

Tarea 7 corrección

Componente especular del modelo de la luz

Cuando una pelota bota en una pared y vuelve, lo hace con el mismo ángulo. Del mismo modo, la luz que se refleja en el mismo ángulo, pero opuesto, que la fuente de luz se denomina luz reflejada especularmente. Este componente especular se refleja como si se tratara de un espejo. La luz que no es reflejada especularmente sino dispersada en muchas direcciones se denomina reflectancia difusa. La suma de la reflectancia especular más la reflectancia difusa se llama reflectancia total.
Para los objetos con superficies brillantes, la luz reflejada especularmente es relativamente fuerte y la luz difusa es más débil. En superficies rugosas con bajo brillo, el componente especular es débil y la luz difusa es más fuerte.

La formación de la luz proviene de la formulación matemática las cuales las leyes de la regraccion especular

Ambos rayos, el refractado y el incidente se encuentran en el mismo plano (L) y su normal (N), usando la ley de Snell para el ángulo de rayo transmitido:

ni sen α=nt sen β

Donde, ni y nt son los índices de refracción del rayo incidente (ni) y el rayo transmitido (nt) y α β son los ángulos con respecto a la normal de ambos rayos

Rayo transmitido:
El cuales el índice de refracción relativo y calculando el factor de incidencia

La intensidad aproximada se calcula con:



Donde, krs es el coeficiente de la refractividad especular y k es el exponente de rugosidad.

Además se pueden considerar efecto de distancia, para componente de color, Rojo, Verde y Azul hay valores de Its, lp y krs




martes, 8 de mayo de 2007

Previo 8

A Continuacion se presenta el Previo 8:

1.- Investigar como crear y definir una fuente de luz con OpenGL
- Creación de la luz
- Cuantas luces se pueden definir
- Parámetros de la fuente de luz
- Tipos de luces
- Color de la luces
- Habilitación, Deshabilitación de luces.
- Luz por default y características por default

Para la iluminación de una escena se debe seguir lo siguiente:

- Definir los vectores normales para todos los vértices de los objetos
- Colocar las fuentes de luz
- Elegir el tipo de luz
- Escoger el tipo de material de cada objeto

Primero se ejecutara el comando glEnable( GL_LIGHTING ), con esto se activan los cálculos de iluminación necesarios. En la definición estándar hay 8 fuentes de luz desde LIGHT0 a LIGHT7

En OpenGL se pueden definir tres formas de luz distintas, estas son: AMBIENTE, DIFUSA y ESPECULAR

AMBIENTE.- la luz llega de todas las direcciones de forma distribuida y es reflejada de igual forma por los polígonos de la escena.

DIFUSA.- la luz llega de una fuente puntual en particular y toca la superficie con una intensidad que depende de la cara hacia la cual llega la luz, este tipo de iluminación es la que mejor define el contorno en los objetos 3D

ESPECULAR.- es la luz emitida desde el objeto de forma distribuida en todas direcciones.

La luz tiene las propiedades de color, posición y dirección. El color que las luces tendrán esta determinado por las tres componentes de color que maneja OpenGL, rojo, verde y azul. El comando utilizado para especificar todas las propiedades de la luz es glLiht(), este comando tiene tres argumentos para identificar la luz que se está utilizando, la propiedad y el valor deseado para la propiedad.

Después de definir las características de las luces se encienden con el comando glEnable(nombre de la fuente de luz a activar). También existe una función para desactivar la iluminación, que es glDisable y desactiva la luz especificada.

Las características de la luz por default para glLight son: GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_POSITION, GL_SPOT_DIRECTION, GL_SPOT_EXPONENT, GL_SPOT_CUTOFF, GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION.

GL_DIFFUSE Y GL_ESPECULAR sólo se usan con la primera fuente de luz.

GL_AMBIENT: Define los valores de la luz ambiental. Valor RGBA, su valor por defecto es (0.0,0.0,0.0,1.0)
GL_DIFFUSE: Define los valores de la luz difusa. Valor RGBA. su valor por defecto es (1.0,1.0,1.0,1.0)
GL_SPECULAR: Define los valores de la luz especular. Valor RGBA. Su valor por defecto es (1.0,1.0,1.0,1.0)
GL_POSITION: Posición de la luz, en coordenadas { x, y, z, w }, su valor por defecto es (0.0,0.0,1.0,0.0)
GL_SPOT_DIRECTION: Vector de dirección de la luz, en coordenadas { x, y, z }, su valor por defecto es (0.0,0.0,-1.0)
GL_SPOT_EXPONENT: Representa la concentración de la intensidad de la luz. Valor escalar, por defecto 0.
GL_SPOT_CUTOFF: Ángulo del cono de luz. Valor escalar, por defecto 180.
GL_CONSTANT_ATTENUATION: Atenuación constante a aplicar a la luz según la distancia. Valor escalar, por defecto 1
GL_LINEAR_ATTENUATION: Atenuación lineal a aplicar a la luz según la distancia. Valor escalar, por defecto 0
GL_QUADRATIC_ATTENUATION: Atenuación cuadrática a aplicar a la luz según la distancia. Valor escalar, por defecto 0
2.- Investigue la diferencia entre luz e iluminación (light/lighting)
- Habilitacion/Deshabilitacion de la ilumnacion (¿Cómo?)
- ¿Para que hay que habilitar y desabilitar la iluminación?

La luz es un punto focal el cual ilumina los objetos en un cierto rango, es un punto muy definido y fácil de encontrar, en cambio la iluminación da una intensidad de luz en un rango más amplio dando la sensación de que no hay un punto focal donde la luz es emitida, la iluminación es un tipo de luz la cual no incide directamente en los objetos.

Para habilitar y deshabilitar a uno de los puntos de iluminación se utilizan los comandos glEnable(nombre_iluminación) y glDisable(nombre_iluminación). La fuente de luz es creada con glLightfv (GL_LIGHT0, GL_AMBIENT, luz ambiental);


3.- Investigue la definición de propiedades de material a una superficie
- Características de los materiales (difuso, especular, brillantez, emisividad, etc)
- ¿Como se definen?
- Sobre que cara(s) de un poligono se aplican los materiales

Dependiendo de las propiedades de los materiales la luz tiene un efecto distinto sobre ellos
Estas propiedades se definen con glMaterial:
void glMaterial(GLenum cara, GLenum nombre, TYPOparam);
El argumento cara, determina la cara del objeto en la que aplicamos las propiedades, tiene los siguientes valores:
GL_FRONT,GL_BACK,GL_FRONT_AND_BACK.
El siguiente indica la propiedad que va utilizarse para dicha cara, puede ser:
GL_AMBIENT, GL_DIFFUSE, GL_AMBIENT_AND_DIFFUSE, GL_SPECULAR, GL_SHININESS, GL_EMISSION, GL_COLOR_INDEXES.
El ultimo parámetro especifica un puntero al valor o valores que el parámetro nombre tomara.
· GL_AMBIENT .- color ambiente del material, sus valores por defecto son (0.2, 0.2, 0.2, 1.0).
· GL_DIFFUSE .- color difuso del material, sus valores por defecto son (0.8, 0.8, 0.8, 1.0).
· GL_AMBIENT_AND_DIFFUSE .- color ambiente y difuso del material
· GL_SHININESS.- exponente especular, su valor por defecto es 0.
· GL_EMISSION.- el color de emisión del material, sus valores por defecto son (0.0, 0.0, 0.0, 1.0).
· GL_COLOR_INDEXES.- índice de color ambiente, difuso y especular, sus valores por defecto son (0, 1, 1).
4.- Investigar acerca del mapeo de texturas con OpenGL
- Carga, definición del bitmap
- Transformaciones de la textura
- Modos de Aplicación de una textura (repeat, wrap, etc.)
- Mapeo de la textura a una superficie

TEXTURAS
Cargando texturas en memoria
El proceso de cargar la textura en memoria, no es propio de OpenGL. Se tiene que realizar una funcion externa. Existen algunas limitaciones que la librería impone. Las dimensiones de todas las texturas que carguentienen que ser potencias de 2, como por ejemplo 64x64, 128x64, etc.
Se tiene que tener en cuenta que si sedebe estar dibujando en RGB, sin color indexado, o bien cargando texturas en formato RGB. Si se carga una imagen GIF, que tiene color indexado, se tiene que programar una función extra para convertirla a RGB.. Sea cuál sea el método, al final se tendrá un puntero a un segmento de memoria que contiene la imagen:
unsigned char *textura;
Es importante también guardar las propiedades de la textura, en concreto
sus dimensiones de ancho y alto, así como su profundidad en bits. Si estamos trabajando en RGB, la profundidad será 24bits.
Los pasos a seguir son:
· Determinamos el tamaño
· Calculamos la memoria que será necesaria
· Reservamos memoria
· Generación de archivo TGA el cual viene en formato RGB. Si no está en este formato se deberá realizar la conversión.
Una vez tenemos la imagen cargada en memoria, los pasos a seguir son:
· Generar la referencia para la textura. [glGenTextures (1, &textura);] Con el GLuint textura referenciaremos a "esa textura". Si se quiere tener más, se debe crear un array de GLuint. El 1 significa que sólo generamos una textura.
· Referenciamos esa textura: [glBindTexture (GL_TEXTURE_2D, textura);]. Esta función dice que ahora en adelante, todas las operaciones que afecten al manejo de texturas se aplicarán sobre esa textura. En este caso es una etextura 2D
· Especificamos los filtros para esa textura:
o glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
· OpenGL puede aplicar filtros a las texturas para mejorar su visualización. La primer línea especifica el filtro a utilizar en caso de que las textura se vea más grande de lo que en realidad es (Aumento). La segunda, especifica el filtro para el caso de que la textura se vea más pequeña de lo que en realidad es. Aquí utilizamos un filtro LINEAR para el 1er caso y del segundo hablaremos más adelante. Otro valor que podríamos haber utilizado es el GL_NEAREST, que es un filtro peor pero más rápido
· Creamos la textura por medio de MIPMAPS para mejor rendimiento, en vez de filtrar las textura dinámicamente, al crear un mipmap, creamos varias texturas de diferentes tamaños (del original hacia más pequeño). OpenGL, decidirá en función de lo lejano que esté el objeto con esa textura, de qué mipmap utilizar.
· Por ultimo, sólo hace falta habilitar el empleo de texturas con:glEnable(GL_TEXTURE_2D);En la función init_gl.
TRANSFORMACIÓN DE LA TEXTURA
Para la generación de la imagen TGA en memoria. El TGA debe cumplir las siguientes características:
· Ser de 24 bits
· Canal ALPHA. (32 bits) y SIN COMPRIMIR
· El tamaño debe ser cuadrado (x=y) y 32x32 o 64x64 o 128x128 o 256x256
Si se cumple todo lo anterior, devuelve un puntero a la imagen y el tamaño de la imagen


MAPEO DE TEXTURAS
PARA TEXTURAS 1D
•Para definir la textura:
• void glTexImage1D (GLenum objetivo, GLint nivel, • GLint componentes, GLsizei ancho, GLint borde, GLenum formato, GLenum tipo, const GLvoid *pixels)
•donde:
–objetivo vale siempre GL_TEXTURE_1D
–nivel indica el nivel de detalle (0 para texturas individuales)
–componentes vale 1 (modo índice), 3 (RGB) ó 4 (RGBA)
–ancho indica el ancho en pixel del mapa de textura (debe ser potencia de 2)
–borde indica el número de pixels que forman el borde de la textura (0, 1 ó 2)
–formato indica el formato de los pixels: GL_RED, GL_RGB, GL_LUMINANCE
–tipo indica el tipo de dato de los pixels: GL_UNSIGNED_INT, GL_FLOAT
–pixels es un puntero a los pixels de la textura

MAPEO PARA TEXTURAS 2D
•Para definir la textura:
• void glTexImage2D (GLenum objetivo, GLint nivel, • GLint componentes, GLsizei ancho, GLsizei alto, • GLint borde, GLenum formato, GLenum tipo, • const GLvoid *pixels)
•donde:
–objetivo vale siempre GL_TEXTURE_2D
–nivel indica el nivel de detalle (0 para texturas individuales)
–componentes vale 1 (modo índice o luminancia), 3 (RGB) ó 4 (RGBA)
–ancho indica el ancho en pixels del mapa de textura (debe ser potencia de 2)
–alto indica el alto en pixels del mapa de textura (debe ser potencia de 2)
–borde indica el número de pixels que forman el borde de la textura (0, 1 ó 2)
–formato indica el formato de los pixels: GL_RED, GL_RGB, GL_LUMINANCE
–tipo indica el tipo de dato de los pixels: GL_UNSIGNED_INT, GL_FLOAT
–pixels es un puntero a los pixels de la textura



MAPEO DE TEXTURAS EN UNA SUPERFICIE
•Al mapear la imagen de textura sobre una superficie, los texels no se van a corresponder exactamente con los pixels
Magnificación : Si la superficie es mayor que la textura, cada pixel se corresponderá con un trozo pequeño de texel

Minificación : Si la superficie es menor que la textura, cada pixel se corresponderá con una conjunto de texels contiguos•
Texels

Pixeles

Modos de mapeo
•Para establecer el modo de mapeo:
• glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GLint valor)
• donde valor puede tomar 3 valores:
–GL_DECAL: el valor del texel se copia directamente al pixel
–GL_MODULATE: el valor del texel se escala por el color del objeto
–GL_BLEND: el valor del texel se usa para interpolar entre el color del objeto y un color constante definido para la textura, mediante la función
• glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,GLfloat color[4])


MODOS DE APLICACIÓN DE TEXTURAS

GL TEXTURE WRAP S
Establece el parámetro wrap para la coordenada de textura s a GL_CLAMP, GL_CLAMP_TO_EDGE, o GL_REPEAT. GL_CLAMP causa que las coordenadas s estén limitadas al rango [0,1] y es útil para prevenir artefactos de envoltura (compresión?) cuando se mapea una única imagen en un objeto. GL_CLAMP_TO_EDGE causa que las coordenadas s se limiten al rango [1/2n, 1-(1/2n)i], donde n es el tamaño de la textura en la dirección del límite. GL_REPEAT causa que la parte entera de s se ignore; el GL utiliza solo la parte fraccionaria, creando por lo tanto un patrón repetitivo. Los elementos de textura de borde son accesados solo si la envoltura se establece a GL_CLAMP. Inicialmente, GL_TEXTURE­_WRAP_S se establece a GL_REPEAT.

GL TEXTURE WRAP T
Establece el parámetro wrap para la coordenada de textura t a GL_CLAMP, GL_CLAMP_TO_EDGE, o GL_REPEAT (véase arriba). Inicialmente, GL_TEXTURE_WRAP_T se establece a GL_REPEAT.

1.- Investigar como crear y definir una fuente de luz con OpenGL
- Creación de la luz
- Cuantas luces se pueden definir
- Parámetros de la fuente de luz
- Tipos de luces
- Color de la luces
- Habilitación, Deshabilitación de luces.
- Luz por default y características por default

Para la iluminación de una escena se debe seguir lo siguiente:

- Definir los vectores normales para todos los vértices de los objetos
- Colocar las fuentes de luz
- Elegir el tipo de luz
- Escoger el tipo de material de cada objeto

Primero se ejecutara el comando glEnable( GL_LIGHTING ), con esto se activan los cálculos de iluminación necesarios. En la definición estándar hay 8 fuentes de luz desde LIGHT0 a LIGHT7

En OpenGL se pueden definir tres formas de luz distintas, estas son: AMBIENTE, DIFUSA y ESPECULAR

AMBIENTE.- la luz llega de todas las direcciones de forma distribuida y es reflejada de igual forma por los polígonos de la escena.

DIFUSA.- la luz llega de una fuente puntual en particular y toca la superficie con una intensidad que depende de la cara hacia la cual llega la luz, este tipo de iluminación es la que mejor define el contorno en los objetos 3D

ESPECULAR.- es la luz emitida desde el objeto de forma distribuida en todas direcciones.

La luz tiene las propiedades de color, posición y dirección. El color que las luces tendrán esta determinado por las tres componentes de color que maneja OpenGL, rojo, verde y azul. El comando utilizado para especificar todas las propiedades de la luz es glLiht(), este comando tiene tres argumentos para identificar la luz que se está utilizando, la propiedad y el valor deseado para la propiedad.

Después de definir las características de las luces se encienden con el comando glEnable(nombre de la fuente de luz a activar). También existe una función para desactivar la iluminación, que es glDisable y desactiva la luz especificada.

Las características de la luz por default para glLight son: GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_POSITION, GL_SPOT_DIRECTION, GL_SPOT_EXPONENT, GL_SPOT_CUTOFF, GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION.

GL_DIFFUSE Y GL_ESPECULAR sólo se usan con la primera fuente de luz.

GL_AMBIENT: Define los valores de la luz ambiental. Valor RGBA, su valor por defecto es (0.0,0.0,0.0,1.0)
GL_DIFFUSE: Define los valores de la luz difusa. Valor RGBA. su valor por defecto es (1.0,1.0,1.0,1.0)
GL_SPECULAR: Define los valores de la luz especular. Valor RGBA. Su valor por defecto es (1.0,1.0,1.0,1.0)
GL_POSITION: Posición de la luz, en coordenadas { x, y, z, w }, su valor por defecto es (0.0,0.0,1.0,0.0)
GL_SPOT_DIRECTION: Vector de dirección de la luz, en coordenadas { x, y, z }, su valor por defecto es (0.0,0.0,-1.0)
GL_SPOT_EXPONENT: Representa la concentración de la intensidad de la luz. Valor escalar, por defecto 0.
GL_SPOT_CUTOFF: Ángulo del cono de luz. Valor escalar, por defecto 180.
GL_CONSTANT_ATTENUATION: Atenuación constante a aplicar a la luz según la distancia. Valor escalar, por defecto 1
GL_LINEAR_ATTENUATION: Atenuación lineal a aplicar a la luz según la distancia. Valor escalar, por defecto 0
GL_QUADRATIC_ATTENUATION: Atenuación cuadrática a aplicar a la luz según la distancia. Valor escalar, por defecto 0
2.- Investigue la diferencia entre luz e iluminación (light/lighting)
- Habilitacion/Deshabilitacion de la ilumnacion (¿Cómo?)
- ¿Para que hay que habilitar y desabilitar la iluminación?

La luz es un punto focal el cual ilumina los objetos en un cierto rango, es un punto muy definido y fácil de encontrar, en cambio la iluminación da una intensidad de luz en un rango más amplio dando la sensación de que no hay un punto focal donde la luz es emitida, la iluminación es un tipo de luz la cual no incide directamente en los objetos.

Para habilitar y deshabilitar a uno de los puntos de iluminación se utilizan los comandos glEnable(nombre_iluminación) y glDisable(nombre_iluminación). La fuente de luz es creada con glLightfv (GL_LIGHT0, GL_AMBIENT, luz ambiental);


3.- Investigue la definición de propiedades de material a una superficie
- Características de los materiales (difuso, especular, brillantez, emisividad, etc)
- ¿Como se definen?
- Sobre que cara(s) de un poligono se aplican los materiales

Dependiendo de las propiedades de los materiales la luz tiene un efecto distinto sobre ellos
Estas propiedades se definen con glMaterial:
void glMaterial(GLenum cara, GLenum nombre, TYPOparam);
El argumento cara, determina la cara del objeto en la que aplicamos las propiedades, tiene los siguientes valores:
GL_FRONT,GL_BACK,GL_FRONT_AND_BACK.
El siguiente indica la propiedad que va utilizarse para dicha cara, puede ser:
GL_AMBIENT, GL_DIFFUSE, GL_AMBIENT_AND_DIFFUSE, GL_SPECULAR, GL_SHININESS, GL_EMISSION, GL_COLOR_INDEXES.
El ultimo parámetro especifica un puntero al valor o valores que el parámetro nombre tomara.
· GL_AMBIENT .- color ambiente del material, sus valores por defecto son (0.2, 0.2, 0.2, 1.0).
· GL_DIFFUSE .- color difuso del material, sus valores por defecto son (0.8, 0.8, 0.8, 1.0).
· GL_AMBIENT_AND_DIFFUSE .- color ambiente y difuso del material
· GL_SHININESS.- exponente especular, su valor por defecto es 0.
· GL_EMISSION.- el color de emisión del material, sus valores por defecto son (0.0, 0.0, 0.0, 1.0).
· GL_COLOR_INDEXES.- índice de color ambiente, difuso y especular, sus valores por defecto son (0, 1, 1).
4.- Investigar acerca del mapeo de texturas con OpenGL
- Carga, definición del bitmap
- Transformaciones de la textura
- Modos de Aplicación de una textura (repeat, wrap, etc.)
- Mapeo de la textura a una superficie

TEXTURAS
Cargando texturas en memoria
El proceso de cargar la textura en memoria, no es propio de OpenGL. Se tiene que realizar una funcion externa. Existen algunas limitaciones que la librería impone. Las dimensiones de todas las texturas que carguentienen que ser potencias de 2, como por ejemplo 64x64, 128x64, etc.
Se tiene que tener en cuenta que si sedebe estar dibujando en RGB, sin color indexado, o bien cargando texturas en formato RGB. Si se carga una imagen GIF, que tiene color indexado, se tiene que programar una función extra para convertirla a RGB.. Sea cuál sea el método, al final se tendrá un puntero a un segmento de memoria que contiene la imagen:
unsigned char *textura;
Es importante también guardar las propiedades de la textura, en
concreto sus dimensiones de ancho y alto, así como su profundidad en bits. Si estamos trabajando en RGB, la profundidad será 24bits.
Los pasos a seguir son:
· Determinamos el tamaño
· Calculamos la memoria que será necesaria
· Reservamos memoria
· Generación de archivo TGA el cual viene en formato RGB. Si no está en este formato se deberá realizar la conversión.
Una vez tenemos la imagen cargada en memoria, los pasos a seguir son:
· Generar la referencia para la textura. [glGenTextures (1, &textura);] Con el GLuint textura referenciaremos a "esa textura". Si se quiere tener más, se debe crear un array de GLuint. El 1 significa que sólo generamos una textura.
· Referenciamos esa textura: [glBindTexture (GL_TEXTURE_2D, textura);]. Esta función dice que ahora en adelante, todas las operaciones que afecten al manejo de texturas se aplicarán sobre esa textura. En este caso es una etextura 2D
· Especificamos los filtros para esa textura:
o glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
· OpenGL puede aplicar filtros a las texturas para mejorar su visualización. La primer línea especifica el filtro a utilizar en caso de que las textura se vea más grande de lo que en realidad es (Aumento). La segunda, especifica el filtro para el caso de que la textura se vea más pequeña de lo que en realidad es. Aquí utilizamos un filtro LINEAR para el 1er caso y del segundo hablaremos más adelante. Otro valor que podríamos haber utilizado es el GL_NEAREST, que es un filtro peor pero más rápido
· Creamos la textura por medio de MIPMAPS para mejor rendimiento, en vez de filtrar las textura dinámicamente, al crear un mipmap, creamos varias texturas de diferentes tamaños (del original hacia más pequeño). OpenGL, decidirá en función de lo lejano que esté el objeto con esa textura, de qué mipmap utilizar.
· Por ultimo, sólo hace falta habilitar el empleo de texturas con:glEnable(GL_TEXTURE_2D);En la función init_gl.
TRANSFORMACIÓN DE LA TEXTURA
Para la generación de la imagen TGA en memoria. El TGA debe cumplir las siguientes características:
· Ser de 24 bits
· Canal ALPHA. (32 bits) y SIN COMPRIMIR
· El tamaño debe ser cuadrado (x=y) y 32x32 o 64x64 o 128x128 o 256x256
Si se cumple todo lo anterior, devuelve un puntero a la imagen y el tamaño de la imagen


MAPEO DE TEXTURAS
PARA TEXTURAS 1D
•Para definir la textura:
• void glTexImage1D (GLenum objetivo, GLint nivel, • GLint componentes, GLsizei ancho, GLint borde, GLenum formato, GLenum tipo, const GLvoid *pixels)
•donde:
–objetivo vale siempre GL_TEXTURE_1D
–nivel indica el nivel de detalle (0 para texturas individuales)
–componentes vale 1 (modo índice), 3 (RGB) ó 4 (RGBA)
–ancho indica el ancho en pixel del mapa de textura (debe ser potencia de 2)
–borde indica el número de pixels que forman el borde de la textura (0, 1 ó 2)
–formato indica el formato de los pixels: GL_RED, GL_RGB, GL_LUMINANCE
–tipo indica el tipo de dato de los pixels: GL_UNSIGNED_INT, GL_FLOAT
–pixels es un puntero a los pixels de la textura

MAPEO PARA TEXTURAS 2D
•Para definir la textura:
• void glTexImage2D (GLenum objetivo, GLint nivel, • GLint componentes, GLsizei ancho, GLsizei alto, • GLint borde, GLenum formato, GLenum tipo, • const GLvoid *pixels)
•donde:
–objetivo vale siempre GL_TEXTURE_2D
–nivel indica el nivel de detalle (0 para texturas individuales)
–componentes vale 1 (modo índice o luminancia), 3 (RGB) ó 4 (RGBA)
–ancho indica el ancho en pixels del mapa de textura (debe ser potencia de 2)
–alto indica el alto en pixels del mapa de textura (debe ser potencia de 2)
–borde indica el número de pixels que forman el borde de la textura (0, 1 ó 2)
–formato indica el formato de los pixels: GL_RED, GL_RGB, GL_LUMINANCE
–tipo indica el tipo de dato de los pixels: GL_UNSIGNED_INT, GL_FLOAT
–pixels es un puntero a los pixels de la textura



MAPEO DE TEXTURAS EN UNA SUPERFICIE
•Al mapear la imagen de textura sobre una superficie, los texels no se van a corresponder exactamente con los pixels
Magnificación : Si la superficie es mayor que la textura, cada pixel se corresponderá con un trozo pequeño de texel

Minificación : Si la superficie es menor que la textura, cada pixel se corresponderá con una conjunto de texels contiguos•
Texels

Pixeles

Modos de mapeo
•Para establecer el modo de mapeo:
• glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GLint valor)
• donde valor puede tomar 3 valores:
–GL_DECAL: el valor del texel se copia directamente al pixel
–GL_MODULATE: el valor del texel se escala por el color del objeto
–GL_BLEND: el valor del texel se usa para interpolar entre el color del objeto y un color constante definido para la textura, mediante la función
• glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,GLfloat color[4])


MODOS DE APLICACIÓN DE TEXTURAS

GL TEXTURE WRAP S
Establece el parámetro wrap para la coordenada de textura s a GL_CLAMP, GL_CLAMP_TO_EDGE, o GL_REPEAT. GL_CLAMP causa que las coordenadas s estén limitadas al rango [0,1] y es útil para prevenir artefactos de envoltura (compresión?) cuando se mapea una única imagen en un objeto. GL_CLAMP_TO_EDGE causa que las coordenadas s se limiten al rango [1/2n, 1-(1/2n)i], donde n es el tamaño de la textura en la dirección del límite. GL_REPEAT causa que la parte entera de s se ignore; el GL utiliza solo la parte fraccionaria, creando por lo tanto un patrón repetitivo. Los elementos de textura de borde son accesados solo si la envoltura se establece a GL_CLAMP. Inicialmente, GL_TEXTURE­_WRAP_S se establece a GL_REPEAT.

GL TEXTURE WRAP T
Establece el parámetro wrap para la coordenada de textura t a GL_CLAMP, GL_CLAMP_TO_EDGE, o GL_REPEAT (véase arriba). Inicialmente, GL_TEXTURE_WRAP_T se establece a GL_REPEAT.


5.- Escriba un programa que:
Defina dos luces de características distintas
Dibuje un cubo en el que cada cara tenga distintas propiedades de material aplicadas
Dibuje otro cubo para el cual en cada cara se aplique una textura distinta. Una de ellas debe ser la foto del alumno.
Al apretar el botón izquierdo del mouse prende/apaga la primera luz
Al apretar el botón derecho del mouse prende/apaga la segunda luz
Al usar las teclas de dirección del teclado cambia la posición de la primera luz
5.- Escriba un programa que:
Defina dos luces de características distintas
Dibuje un cubo en el que cada cara tenga distintas propiedades de material aplicadas
Dibuje otro cubo para el cual en cada cara se aplique una textura distinta. Una de ellas debe ser la foto del alumno.
Al apretar el botón izquierdo del mouse prende/apaga la primera luz
Al apretar el botón derecho del mouse prende/apaga la segunda luz
Al usar las teclas de dirección del teclado cambia la posición de la primera luz



#include
#include
#include "bitmap.h"

BITMAPINFO *TexInfo; /* Texture bitmap information */
GLubyte *TexBits; /* Texture bitmap pixel bits */
static int spinx = 0;
static int spiny = 0;
static int p1 = 1;
static int p2 = 1;
static int ry,rx,rz;
/* Inicializa las prpiedaes de material, fuente de luz y el z buffer*/
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_DEPTH_TEST);
}
void display(void)
{
/*Matrices para la luz*/
GLfloat position[] = { 0.0, 0.0, 2.5, 0.0 };
GLfloat position2[] = { 0.0, 3.0, 3.0, 0.0 };
GLfloat light_ambient[]={0.4, 0.4, 0.4, 1.0};
GLfloat light_diffuse[]={0.4, 0.4, 0.4, 1.0};
GLfloat light_specular[]={0.8, 0.8, 0.8, 1.0};
/*Matrices para materiales*/
GLfloat no_mat[] = {0.0,0.0,0.0,1.0};
GLfloat mat_ambient[] = {0.7,0.7,0.7,1.0};
GLfloat mat_ambient_color[] = {0.8,0.8,0.2,1.0};
GLfloat mat_diffuse[] = {0.1,0.5,0.8,1.0};
GLfloat mat_specular[] = {1.0,1.0,1.0,1.0};
GLfloat no_shininess[] = {0.0};
GLfloat low_shininess[] = {5.0};
GLfloat high_shininess[] = {100.0};
GLfloat mat_emission[] = {0.3,0.2,0.2,1.0};
GLfloat mat_amb_diff[] = {0.1, 0.5, 0.8, 1.0};
GLfloat mat_amb_diff2[] = {1.0, 0.1, 0.1, 1.0};
GLfloat mat_emission1[] = {0.3,0.8,0.2,1.0};
glClear (GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT);
glClearColor (0.0, 0.0, 0.0, 0.0);
glLoadIdentity ();
gluLookAt (5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix ();
glTranslatef(-2,0,0);
/*luz 0*/
glPushMatrix ();
glRotated ((GLdouble) spinx, 1.0, 0.0, 0.0);
glRotated ((GLdouble) spiny, 0.0, 1.0, 0.0);
glLightfv (GL_LIGHT0, GL_POSITION, position);
glTranslated (0.0, 0.0,2.5 );
glDisable (GL_LIGHTING);
glColor3f (1.0, 1.0, 1.0);
glutWireCube (0.1);
glEnable (GL_LIGHTING);
glPopMatrix ();
/*fin luz 0*/
/*luz 1*/
glPushMatrix ();
glLightfv (GL_LIGHT1, GL_POSITION, position2);
glLightfv (GL_LIGHT1, GL_AMBIENT, light_ambient);//GL_DIFFUSE
glLightfv (GL_LIGHT1, GL_DIFFUSE, light_diffuse);
glLightfv (GL_LIGHT1, GL_SPECULAR, light_specular);
glTranslated (0.0,2.5,2.5);
glDisable (GL_LIGHTING);
glColor3f (1.0, 1.0, 1.0);
glutWireCube (0.1);
glEnable (GL_LIGHTING);
glPopMatrix ();
/*fin luz 1*/
/*cubo materiales*/
glPushMatrix ();
glScalef(1,1,1);
glRotatef(rx,1.0,0.0,0.0);
glRotatef(ry,0.0,1.0,0.0);
glRotatef(rz,0.0,0.0,1.0);
glPushMatrix ();
/*Solo con difuso*/
glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glBegin(GL_QUADS);
glNormal3f(0.0,0.0,1.0);
glVertex3f(0.5,0.5,0.5);
glVertex3f(-0.5,0.5,0.5);
glVertex3f(-0.5,-0.5,0.5);
glVertex3f(0.5,-0.5,0.5);
glEnd();
glPopMatrix ();
glPushMatrix ();
/*difusa y especular, poco brillo*/
glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glBegin(GL_QUADS);
glNormal3f(0.0,0.0,-1.0);
glVertex3f(-0.5,0.5,-0.5);
glVertex3f( 0.5,0.5,-0.5);
glVertex3f(0.5,-0.5,-0.5);
glVertex3f(-0.5,-0.5,-0.5);
glEnd();
glPopMatrix ();
glPushMatrix ();
/*difusa, con reflejo especular y alto brillo */
glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glBegin(GL_QUADS);
glNormal3f(-1.0,0.0,0.0);
glVertex3f(-0.5,0.5,0.5);
glVertex3f(-0.5,0.5,-0.5);
glVertex3f(-0.5,-0.5,-0.5);
glVertex3f(-0.5,-0.5,0.5);
glEnd();
glPopMatrix ();
glPushMatrix ();
/*ambiente , difuso y con emision*/
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glBegin(GL_QUADS);
glNormal3f(1.0,0.0,0.0);
glVertex3f(0.5,0.5,0.5);
glVertex3f(0.5,-0.5,0.5);
glVertex3f( 0.5,-0.5,-0.5);
glVertex3f(0.5,0.5,-0.5);
glEnd();
glPopMatrix ();
glPushMatrix ();
/*color de ambiente, difuso, refleccion especular y poco brillo*/
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glBegin(GL_QUADS);
glNormal3f(0.0,1.0,0.0);
glVertex3f(-0.5,0.5,-0.5);
glVertex3f(-0.5,0.5,0.5);
glVertex3f(0.5,0.5,0.5);
glVertex3f( 0.5,0.5,-0.5);
glEnd();
glPopMatrix ();
glPushMatrix ();
/*color de ambiente, difuso, refleccion especular y alto brillo*/
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glBegin(GL_QUADS);
glNormal3f(0.0,-1.0,0.0);
glVertex3f(0.5,-0.5,-0.5);
glVertex3f(-0.5,-0.5,-0.5);
glVertex3f(-0.5,-0.5,0.5);
glVertex3f(0.5,-0.5,0.5);
glEnd();
glPopMatrix ();
glPopMatrix ();
/*fin cubo de materiales*/
glPopMatrix ();
glPushMatrix();
glTranslatef(2,0,0);
glRotatef(rx,1.0,0.0,0.0);
glRotatef(ry,0.0,1.0,0.0);
glRotatef(rz,0.0,0.0,1.0);
glColor3f(1.0, 1.0, 1.0);
glTranslatef(0.0,0.0,0.0);
TexBits = LoadDIBitmap("Adrian.bmp", &TexInfo);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TexInfo->bmiHeader.biWidth,
TexInfo->bmiHeader.biHeight, 0, GL_BGR_EXT,
GL_UNSIGNED_BYTE, TexBits);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//se activa el mapeado de texturas
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glNormal3f(0.0,0.0,1.0);
glTexCoord2f(1.0,1.0); glVertex3f(0.5,0.5,0.5);
glTexCoord2f(0.0,1.0); glVertex3f(-0.5,0.5,0.5);
glTexCoord2f(0.0,0.0); glVertex3f(-0.5,-0.5,0.5);
glTexCoord2f(1.0,0.0); glVertex3f(0.5,-0.5,0.5);
glEnd();
glDisable(GL_TEXTURE_2D);

TexBits = LoadDIBitmap("avatarFMA.bmp", &TexInfo);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TexInfo->bmiHeader.biWidth,
TexInfo->bmiHeader.biHeight, 0, GL_BGR_EXT,
GL_UNSIGNED_BYTE, TexBits);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glNormal3f(0.0,0.0,-1.0);
glTexCoord2f(1.0,1.0); glVertex3f(-0.5,0.5,-0.5);
glTexCoord2f(0.0,1.0); glVertex3f( 0.5,0.5,-0.5);
glTexCoord2f(0.0,0.0); glVertex3f(0.5,-0.5,-0.5);
glTexCoord2f(1.0,0.0); glVertex3f(-0.5,-0.5,-0.5);
glEnd();
glDisable(GL_TEXTURE_2D);
TexBits = LoadDIBitmap("AdrianSouthpark2.bmp", &TexInfo);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TexInfo->bmiHeader.biWidth,
TexInfo->bmiHeader.biHeight, 0, GL_BGR_EXT,
GL_UNSIGNED_BYTE, TexBits);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glNormal3f(-1.0,0.0,0.0);
glTexCoord2f(1.0,1.0); glVertex3f(-0.5,0.5,0.5);
glTexCoord2f(0.0,1.0); glVertex3f(-0.5,0.5,-0.5);
glTexCoord2f(0.0,0.0); glVertex3f(-0.5,-0.5,-0.5);
glTexCoord2f(1.0,0.0); glVertex3f(-0.5,-0.5,0.5);
glEnd();
glDisable(GL_TEXTURE_2D);
TexBits = LoadDIBitmap("watashi.bmp", &TexInfo);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TexInfo->bmiHeader.biWidth,
TexInfo->bmiHeader.biHeight, 0, GL_BGR_EXT,
GL_UNSIGNED_BYTE, TexBits);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glNormal3f(1.0,0.0,0.0);
glTexCoord2f(0.0,1.0); glVertex3f(0.5,0.5,0.5);
glTexCoord2f(0.0,0.0); glVertex3f(0.5,-0.5,0.5);
glTexCoord2f(1.0,0.0); glVertex3f( 0.5,-0.5,-0.5);
glTexCoord2f(1.0,1.0); glVertex3f(0.5,0.5,-0.5);
glEnd();
glDisable(GL_TEXTURE_2D);
TexBits = LoadDIBitmap("robotechavatar.bmp", &TexInfo);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TexInfo->bmiHeader.biWidth,
TexInfo->bmiHeader.biHeight, 0, GL_BGR_EXT,
GL_UNSIGNED_BYTE, TexBits);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glNormal3f(0.0,1.0,0.0);
glTexCoord2f(0.0,1.0); glVertex3f(-0.5,0.5,-0.5);
glTexCoord2f(0.0,0.0); glVertex3f(-0.5,0.5,0.5);
glTexCoord2f(1.0,0.0); glVertex3f(0.5,0.5,0.5);
glTexCoord2f(1.0,1.0); glVertex3f( 0.5,0.5,-0.5);
glEnd();
glDisable(GL_TEXTURE_2D);
TexBits = LoadDIBitmap("Capitan_Harlock_arcadia_02.bmp", &TexInfo);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TexInfo->bmiHeader.biWidth,
TexInfo->bmiHeader.biHeight, 0, GL_BGR_EXT,
GL_UNSIGNED_BYTE, TexBits);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glNormal3f(0.0,-1.0,0.0);
glTexCoord2f(0.0,0.0); glVertex3f(0.5,-0.5,-0.5);
glTexCoord2f(1.0,0.0); glVertex3f(-0.5,-0.5,-0.5);
glTexCoord2f(1.0,1.0); glVertex3f(-0.5,-0.5,0.5);
glTexCoord2f(0.0,1.0); glVertex3f(0.5,-0.5,0.5);
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
glutSwapBuffers();
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/* ARGSUSED2 */
void mouse(int button, int state, int x, int y)
{
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN) {
if (p1 == 1)
{
glDisable(GL_LIGHT0);
p1 = 0;
glutPostRedisplay();
}
else
{
glEnable(GL_LIGHT0);
p1 = 1;
glutPostRedisplay();
}
}
break;
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN) {
if (p1 == 1)
{
glDisable(GL_LIGHT1);
p1 = 0;
glutPostRedisplay();
}
else
{
glEnable(GL_LIGHT1);
p1 = 1;
glutPostRedisplay();
}
}
break;
default:
break;
}
}
void special(int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_RIGHT:
spiny = (spiny + 3) % 360;
glutPostRedisplay();
break;
case GLUT_KEY_LEFT:
spiny = (spiny - 3) % 360;
glutPostRedisplay();
break;
case GLUT_KEY_UP:
spinx = (spinx - 3) % 360;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN:
spinx = (spinx + 3) % 360;
glutPostRedisplay();
break;
default:
break;
}
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
case 'a':
ry = (ry + 3)%360;
glutPostRedisplay();
break;
case 's':
rx = (rx + 3)%360;
glutPostRedisplay();
break;
case 'd':
rz = (rz + 3)%360;
glutPostRedisplay();
break;
case 'p':
spinx = 0;
spiny = 0;
rx = 0;
rz = 0;
ry = 0;
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glutPostRedisplay();
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE GLUT_RGB GLUT_DEPTH);
glutInitWindowSize (700, 700);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Texturas y luces");
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
glutMainLoop();
return 0;
}

martes, 1 de mayo de 2007

Tarea 7

Componente especular del modelo de la luz

Cuando una pelota bota en una pared y vuelve, lo hace con el mismo ángulo. Del mismo modo, la luz que se refleja en el mismo ángulo, pero opuesto, que la fuente de luz se denomina luz reflejada especularmente. Este componente especular se refleja como si se tratara de un espejo. La luz que no es reflejada especularmente sino dispersada en muchas direcciones se denomina reflectancia difusa. La suma de la reflectancia especular más la reflectancia difusa se llama reflectancia total.






Para los objetos con superficies brillantes, la luz reflejada especularmente es relativamente fuerte y la luz difusa es más débil. En superficies rugosas con bajo brillo, el componente especular es débil y la luz difusa es más fuerte.

Fuente:

http://www4.konicaminolta.eu/pcc/es/part3/02.html

martes, 17 de abril de 2007

Previo 7

#include
#include
#include
#include
#include
/*parametros para el triangulo*/
static int prueba = 1;
static int prueba2 = 1;
static int prueba4 = 1;
static int win1;
static int win2;
static int win3;
static int xzoom = 0;
static int yzoom = 0;
static float px1=-2.5;
static float py1=-2.165;
static float px2=2.5;
static float py2=-2.165;
static float px3=0;
static float py3=2.165;
static float px = 0;
static float py = 0;
static float pcx = 0;
static float pcy = 0;
static float color1 = 0;
static float color2 = 0;
/*-----------------------------------*/
/*parametros para humanoide*/
static int posicionx = 0;
static int posiciony = 0;
static int posicionz = 0;
/*cabeza*/
static int cuelloy = 0;
/*brazo derecho*/
static int hombroderx = 0;
static int hombrodery = 0;
static int hombroderz = 90;
static int cododerz = 0;
/*brazo izquierdo*/
static int hombroizqx = 0;
static int hombroizqy = 0;
static int hombroizqz = -90;
static int codoizqz = 0;
/*pierna derecha*/
static int musloderx = 0;
static int muslodery = 0;
static int musloderz = 45;
static int rodilladerx = 0;
static int piedery = 0;
/*pierna izquierda*/
static int musloizqx = 0;
static int musloizqy = 0;
static int musloizqz = -45;
static int rodillaizqx = 0;
static int pieizqy = 0;
GLUquadricObj *sphereObj;
/*-------------------------------------*/
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void sierpinski (void)
{
int i= 0;
px = rand()%20;
py = rand()%20;
px = px/10;
py = py/10;
/*puntos del triangulo*/
glBegin(GL_POINTS);
glVertex2f(px1,py1);
glEnd();
glBegin(GL_POINTS);
glVertex2f(px2,py2);
glEnd();
glBegin(GL_POINTS);
glVertex2f(px3,py3);
glEnd();
glBegin(GL_POINTS);
glVertex2f(px,py);
glEnd();
/*puntos a calcular*/
do
{
prueba = rand()%3;
if(prueba == 0)
{
px = (px1 + px)/2;
py = (py1 + py)/2;
}
if(prueba == 1)
{
px = (px2 + px)/2;
py = (py2 + py)/2;
}
if(prueba == 2)
{
px = (px3 + px)/2;
py = (py3 + py)/2;
}
/*distancia entre el punto y el centro para los colores*/
pcx = px;
pcy = py + 0.72125;
pcx = pcx*pcx;
pcy = pcy*pcy;
color1 = sqrt(pcx+pcy);
color1 = color1/2.886;
color2 = 1.1 - color1;
glColor3f (color2,color1,0.0);
/*----------------------------------------------------*/
glBegin(GL_POINTS);
glVertex2f(px,py);
glEnd();
i++;
}while (i < 500000);
}
/*Humanoide y sus funciones*/
void cuborelleno(void)
{
glBegin(GL_QUADS);
glVertex3f(0.5,0.5,0.5);//v1
glVertex3f(-0.5,0.5,0.5);//v2
glVertex3f(-0.5,-0.5,0.5);//v3
glVertex3f(0.5,-0.5,0.5);//v4
glEnd();
glBegin(GL_QUADS);
glVertex3f(-0.5,0.5,-0.5);//v5
glVertex3f( 0.5,0.5,-0.5);//v6
glVertex3f(0.5,-0.5,-0.5);//v7
glVertex3f(-0.5,-0.5,-0.5);//v8
glEnd();
glBegin(GL_QUADS);
glVertex3f(-0.5,0.5,0.5);//v2
glVertex3f(-0.5,0.5,-0.5);//v5
glVertex3f(-0.5,-0.5,-0.5);//v8
glVertex3f(-0.5,-0.5,0.5);//v3
glEnd();
glBegin(GL_QUADS);
glVertex3f(0.5,0.5,0.5);//v1
glVertex3f(0.5,-0.5,0.5);//v4
glVertex3f( 0.5,-0.5,-0.5);//v7
glVertex3f(0.5,0.5,-0.5);//v6
glEnd();
glBegin(GL_QUADS);
glVertex3f(-0.5,0.5,-0.5);//v5
glVertex3f(-0.5,0.5,0.5);//v2
glVertex3f(0.5,0.5,0.5);//v1
glVertex3f( 0.5,0.5,-0.5);//v6
glEnd();
glBegin(GL_QUADS);
glVertex3f(0.5,-0.5,-0.5);//v7
glVertex3f(-0.5,-0.5,-0.5);//v8
glVertex3f(-0.5,-0.5,0.5);//v3
glVertex3f(0.5,-0.5,0.5);//v4
glEnd();
}
void cubohueco(void)
{
glBegin(GL_LINE_LOOP);
glVertex3f(0.5,0.5,0.5);//v1
glVertex3f(-0.5,0.5,0.5);//v2
glVertex3f(-0.5,-0.5,0.5);//v3
glVertex3f(0.5,-0.5,0.5);//v4
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(-0.5,0.5,-0.5);//v5
glVertex3f( 0.5,0.5,-0.5);//v6
glVertex3f(0.5,-0.5,-0.5);//v7
glVertex3f(-0.5,-0.5,-0.5);//v8
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(-0.5,0.5,0.5);//v2
glVertex3f(-0.5,0.5,-0.5);//v5
glVertex3f(-0.5,-0.5,-0.5);//v8
glVertex3f(-0.5,-0.5,0.5);//v3
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(0.5,0.5,0.5);//v1
glVertex3f(0.5,-0.5,0.5);//v4
glVertex3f( 0.5,-0.5,-0.5);//v7
glVertex3f(0.5,0.5,-0.5);//v6
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(-0.5,0.5,-0.5);//v5
glVertex3f(-0.5,0.5,0.5);//v2
glVertex3f(0.5,0.5,0.5);//v1
glVertex3f( 0.5,0.5,-0.5);//v6
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(0.5,-0.5,-0.5);//v7
glVertex3f(-0.5,-0.5,-0.5);//v8
glVertex3f(-0.5,-0.5,0.5);//v3
glVertex3f(0.5,-0.5,0.5);//v4
glEnd();
}
void torso (int posx,int posy,int posz)
{
glTranslatef(0.0,1.5,0.0);
glScalef (0.75, 0.75, 0.75);
glRotatef(posx,1.0,0.0,0.0);
glRotatef(posy,0.0,1.0,0.0);
glRotatef(posz,0.0,0.0,1.0);
glTranslatef(0.0,0.0,0.0);
glPushMatrix();
glScalef (2.0, 3.0, 1.0);
cubohueco();
glPopMatrix();
}
void cara (int cuey)
{
glPushMatrix();
glRotatef(cuey,0.0,1.0,0.0);
glTranslatef(0.0,2.0,0.0);
//cubohueco();
gluSphere(sphereObj, 0.65, 12, 5);
glPopMatrix();
}
void muneca (void)
{
/*muñeca y palma*/
glTranslatef(0.0,0.0,0.0);
glRotatef(0,1.0,0.0,0.0);
glRotatef(0,0.0,1.0,0.0);
glRotatef(0,0.0,0.0,1.0);
glTranslatef(0.0,0.5,0.0);
glPushMatrix();
glScalef(1.0,1.0,0.33333);
cubohueco();
glPopMatrix();
}
void dedos(void)
{
/*dedo chito*/
glScalef(1.0,1.0,1.0);
glPushMatrix();
/*primera falange*/
glScalef(0.25,0.25,0.25);
glTranslatef(-1.5,2.2,0.0);
glRotatef(0,1.0,0.0,0.0);
gluSphere(sphereObj, 0.65, 12, 5);
glTranslatef(0.0,1.0,0.0);
glPushMatrix();
glScalef(1.0,1.5,1.0);
cubohueco();
glPopMatrix();
/*segunda falange*/
glTranslatef(0.0,0.90,0.0);
glRotatef(0,1.0,0.0,0.0);
gluSphere(sphereObj, 0.65, 12, 5);
glTranslatef(0.0,0.85,0.0);
glPushMatrix();
glScalef(1.0,1.0,1.0);
cubohueco();
glPopMatrix();
/*tercera falange*/
glTranslatef(0.0,0.90,0.0);
glRotatef(0,1.0,0.0,0.0);
gluSphere(sphereObj, 0.60, 12, 5);
glTranslatef(0.0,0.75,0.0);
glPushMatrix();
glScalef(1.0,1.0,1.0);
cubohueco();
glPopMatrix();
glPopMatrix();/*fin dedo chiquito*/
/*dedo anular*/
glPushMatrix();
/*primera falange*/
glScalef(0.25,0.25,0.25);
glTranslatef(-0.5,2.2,0.0);
glRotatef(0,1.0,0.0,0.0);
gluSphere(sphereObj, 0.65, 12, 5);
glTranslatef(0.0,1.0,0.0);
glPushMatrix();
glScalef(1.0,1.5,1.0);
cubohueco();
glPopMatrix();
/*segunda falange*/
glTranslatef(0.0,0.90,0.0);
glRotatef(0,1.0,0.0,0.0);
gluSphere(sphereObj, 0.65, 12, 5);
glTranslatef(0.0,1.25,0.0);
glPushMatrix();
glScalef(1.0,1.75,1.0);
cubohueco();
glPopMatrix();
/*tercera falange*/
glTranslatef(0.0,0.90,0.0);
glRotatef(0,1.0,0.0,0.0);
gluSphere(sphereObj, 0.60, 12, 5);
glTranslatef(0.0,0.75,0.0);
glPushMatrix();
glScalef(1.0,1.0,1.0);
cubohueco();
glPopMatrix();
glPopMatrix();/*fin dedo anular*/
/*dedo medio*/
glPushMatrix();
/*primera falange*/
glScalef(0.25,0.25,0.25);
glTranslatef(0.5,2.2,0.0);
glRotatef(0,1.0,0.0,0.0);
gluSphere(sphereObj, 0.65, 12, 5);
glTranslatef(0.0,1.0,0.0);
glPushMatrix();
glScalef(1.0,1.5,1.0);
cubohueco();
glPopMatrix();
/*segunda falange*/
glTranslatef(0.0,0.90,0.0);
glRotatef(0,1.0,0.0,0.0);
gluSphere(sphereObj, 0.65, 12, 5);
glTranslatef(0.0,1.5,0.0);
glPushMatrix();
glScalef(1.0,2.25,1.0);
cubohueco();
glPopMatrix();
/*tercera falange*/
glTranslatef(0.0,0.90,0.0);
glRotatef(0,1.0,0.0,0.0);
gluSphere(sphereObj, 0.60, 12, 5);
glTranslatef(0.0,0.75,0.0);
glPushMatrix();
glScalef(1.0,1.0,1.0);
cubohueco();
glPopMatrix();
glPopMatrix();/*fin dedo medio*/
/*dedo indice*/
glPushMatrix();
/*primera falange*/
glScalef(0.25,0.25,0.25);
glTranslatef(1.5,2.2,0.0);
glRotatef(0,1.0,0.0,0.0);
gluSphere(sphereObj, 0.65, 12, 5);
glTranslatef(0.0,1.0,0.0);
glPushMatrix();
glScalef(1.0,1.5,1.0);
cubohueco();
glPopMatrix();
/*segunda falange*/
glTranslatef(0.0,0.90,0.0);
glRotatef(0,1.0,0.0,0.0);
gluSphere(sphereObj, 0.65, 12, 5);
glTranslatef(0.0,1.25,0.0);
glPushMatrix();
glScalef(1.0,1.75,1.0);
cubohueco();
glPopMatrix();
/*tercera falange*/
glTranslatef(0.0,0.90,0.0);
glRotatef(0,1.0,0.0,0.0);
gluSphere(sphereObj, 0.60, 12, 5);
glTranslatef(0.0,0.75,0.0);
glPushMatrix();
glScalef(1.0,1.0,1.0);
cubohueco();
glPopMatrix();
glPopMatrix();/*fin dedo indice*/
/*dedo gordo*/
glPushMatrix();
/*primera falange*/
glScalef(0.25,0.25,0.25);
glTranslatef(2.0,-1.25,0.0);
glRotatef(0,0.0,-1.0,0.0);
glRotatef(0,0.0,0.0,1.0);
glScalef(1.3,1.3,1.0);
gluSphere(sphereObj, 0.65, 12, 5);
glTranslatef(0.75,0.0,0.0);
glPushMatrix();
glScalef(1.0,1.0,1.0);
cubohueco();
glPopMatrix();
/*segunda falange*/
glTranslatef(0.9,0.0,0.0);
glRotatef(0,0.0,0.0,1.0);
gluSphere(sphereObj, 0.65, 12, 5);
glTranslatef(0.6,0.0,0.0);
glPushMatrix();
glScalef(0.75,1.0,1.0);
cubohueco();
glPopMatrix();
/*tercera falange*/
glTranslatef(0.75,0.0,0.0);
glRotatef(0,0.0,0.0,1.0);
gluSphere(sphereObj, 0.60, 12, 5);
glTranslatef(0.5,0.0,0.0);
glPushMatrix();
glScalef(0.75,1.0,1.0);
cubohueco();
glPopMatrix();
glPopMatrix();/*fin dedo gordo*/
}
void mano(void)
{
glPushMatrix();
//glScalef(-1.0,1.0,1.0);
muneca();
dedos();
glPopMatrix();
}
void brazoderecho (int hombrodx,int hombrody,int hombrodz,int cododz)
{
/*brazo derecho*/
glPushMatrix();
glTranslatef(1.0,1.0,0.0);
glRotatef(hombrodx,1.0,0.0,0.0);
glRotatef(hombrody,0.0,1.0,0.0);
glRotatef(hombrodz,0.0,0.0,1.0);
glTranslatef(1.0,0.25,0.0);
glPushMatrix();
glScalef(2.0,0.5,1.0);
cubohueco();
glPopMatrix();
/*antebrazo derecho*/
glTranslatef(1.0,0.0,0.0);
glRotatef(cododz,0.0,0.0,1.0);
glTranslatef(1.0,0.0,0.0);
glPushMatrix();
glScalef(2.0,1.0,1.0);
cubohueco();
glPopMatrix();
/*mano derecha*/
glTranslatef(1.0,0.0,0.0);
glRotatef(-90,0.0,0.0,1.0);
gluSphere(sphereObj,0.25,12,5);
glTranslatef(0.0,0.25,0.0);
glPushMatrix();
glScalef(-0.5,0.5,1.0);
mano();
glPopMatrix();
glPopMatrix();/*brazo derecho completo*/
}
void brazoizquierdo (int hombroix,int hombroiy,int hombroiz,int codoiz)
{
/*brazo izquierdo*/
glPushMatrix();
glTranslatef(-1.0,1.0,0.0);
glRotatef(hombroix,1.0,0.0,0.0);
glRotatef(hombroiy,0.0,1.0,0.0);
glRotatef(hombroiz,0.0,0.0,1.0);
glTranslatef(-1.0,0.25,0.0);
glPushMatrix();
glScalef(2.0,0.5,1.0);
cubohueco();
glPopMatrix();
/*antebrazo izquierdo*/
glTranslatef(-1.0,0.0,0.0);
glRotatef(codoiz,0.0,0.0,1.0);
glTranslatef(-1.0,0.0,0.0);
glPushMatrix();
glScalef(2.0,1.0,1.0);
cubohueco();
glPopMatrix();
/*mano derecha*/
glTranslatef(-1.0,0.0,0.0);
glRotatef(90,0.0,0.0,1.0);
gluSphere(sphereObj,0.25,12,5);
glTranslatef(0.0,0.25,0.0);
glPushMatrix();
glScalef(0.5,0.5,1.0);
mano();
glPopMatrix();
glPopMatrix();/*brazo izquierdo completo*/
}
void piernaderecha(int muslodx,int muslody,int muslodz,int rodilladx,int piedy)
{
/*muslo derecho*/
glPushMatrix();
glTranslatef(0.665,-1.5,0.0);
glRotatef(muslodx,1.0,0.0,0.0);
glRotatef(muslody,0.0,1.0,0.0);
glRotatef(muslodz,0.0,0.0,1.0);
glTranslatef(0.0,-1.2,0.0);
glPushMatrix();
glScalef(0.68,2.4,1.0);
cubohueco();
glPopMatrix();
/*pantorrilla derecha*/
glTranslatef(0.0,-1.2,0.0);
glRotatef(rodilladx,1.0,0.0,0.0);
glTranslatef(0.0,-1.2,0.0);
glPushMatrix();
glScalef(1.0,2.4,1.0);
cubohueco();
glPopMatrix();
/*pie derecho*/
glTranslatef(0.0,0.-1.25,0.0);
glRotatef(piedy,0.0,1.0,0.0);
glTranslatef(0.25,-0.35,0.0);
glPushMatrix();
glScalef(1.5,0.75,1.0);
cubohueco();
glPopMatrix();
glPopMatrix();/*pie derecho completo*/
}
void piernaizquierda(int musloix,int musloiy,int musloiz,int rodillaix,int pieiy)
{
/*muslo izquierdo*/
glPushMatrix();
glTranslatef(-0.665,-1.5,0.0);
glRotatef(musloix,1.0,0.0,0.0);
glRotatef(musloiy,0.0,1.0,0.0);
glRotatef(musloiz,0.0,0.0,1.0);
glTranslatef(0.0,-1.2,0.0);
glPushMatrix();
glScalef(0.68,2.4,1.0);
cubohueco();
glPopMatrix();
/*pantorrilla izquierda*/
glTranslatef(0.0,-1.2,0.0);
glRotatef(rodillaix,1.0,0.0,0.0);
glTranslatef(0.0,-1.2,0.0);
glPushMatrix();
glScalef(1.0,2.4,1.0);
cubohueco();
glPopMatrix();
/*pie izquierdo*/
glTranslatef(0.0,0.-1.25,0.0);
glRotatef(pieiy,0.0,1.0,0.0);
glTranslatef(-0.25,-0.35,0.0);
glPushMatrix();
glScalef(1.5,0.75,1.0);
cubohueco();
glPopMatrix();
glPopMatrix();/*pierna izquierda completo*/
}
void humanoide (int px,int py,int pz,int cy,int hdx,int hdy,int hdz,int cdz,int hix,int hiy,int hiz,int ciz,
int mdx,int mdy,int mdz,int rdx,int pdy,int mix,int miy,int miz,int rix,int piy)
{
torso(px,py,pz);
cara(cy);
brazoderecho(hdx,hdy,hdz,cdz);
brazoizquierdo(hix,hiy,hiz,ciz);
piernaderecha(mdx,mdy,mdz,rdx,pdy);
piernaizquierda(mix,miy,miz,rix,piy);
}
/*----------------------------------------*/
void display1(void)
{
srand(time(NULL));
glColor3f (1.0, 1.0, 1.0);
glLoadIdentity ();
gluLookAt (0.0,0.0,5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT);
sierpinski();
glFlush();
}
void display2(void)
{
srand(time(NULL));
glColor3f (1.0, 1.0, 1.0);
glLoadIdentity ();
gluLookAt (0.0,0.0,15.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT);
glPushMatrix();
glScalef(4,4,1);
sierpinski();
glPopMatrix();
glFlush();
}
void display3(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glLoadIdentity ();
gluLookAt (0.0,0.0,10.0,0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix();
sphereObj = gluNewQuadric();
gluQuadricDrawStyle(sphereObj, GLU_LINE);
humanoide(posicionx,posiciony,posicionz,cuelloy,
hombroderx,hombrodery,hombroderz,cododerz,
hombroizqx,hombroizqy,hombroizqz,codoizqz,
musloderx,muslodery,musloderz,rodilladerx,piedery,
musloizqx,musloizqy,musloizqz,rodillaizqx,pieizqy);
glPopMatrix();
glFlush ();
}
void reshape1 (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode (GL_MODELVIEW);
}
void reshape2 (int w, int h)
{
glViewport (xzoom, yzoom, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode (GL_MODELVIEW);
}
void reshape3 (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode (GL_MODELVIEW);
}
void animacion(void)
{
int i,j;
for(j=0;j<45;j++)
{
display3();
hombroderz = (hombroderz +2)%95;
hombroizqz = (hombroizqz -2)%95;
musloderz = (musloderz -1)%50;
musloizqz = (musloizqz +1)%50;
for (i=0;i<3500000;i++)
{
}
}
for(j=0;j<45;j++)
{
display3();
hombroderz = (hombroderz -2)%90;
hombroizqz = (hombroizqz +2)%90;
musloderz = (musloderz +1)%50;
musloizqz = (musloizqz -1)%50;
for (i=0;i<3500000;i++)
{
}
}
}
void idle3(void)
{
animacion();
display3();
}
/* ARGSUSED1 */
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
case 'q':
glutPostRedisplay();
break;
}
}
void mouse(int button, int state, int x, int y)
{
if (state == GLUT_DOWN)
{
if ((glutGetWindow() == win1) && button == GLUT_LEFT_BUTTON)
{
xzoom = 255 - x;
yzoom = y - 255;
printf("%d, %d \n",x, y);
glutInitWindowSize (500, 500);
glutInitWindowPosition (700, 100);
win2 = glutCreateWindow ("Ventana 2");
init();
glutDisplayFunc(display2);
glutReshapeFunc(reshape2);
glutSetWindow(win2);
glutIdleFunc(NULL);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
}
else if ((glutGetWindow() == win2) && (button == GLUT_RIGHT_BUTTON)){
glutIdleFunc(NULL);
glutDestroyWindow(win2);
}
}
if (state == GLUT_UP)
{
if ((glutGetWindow() == win1) && button == GLUT_RIGHT_BUTTON)
{
printf("%d, %d \n",x, y);
glutInitWindowSize (800, 800);
glutInitWindowPosition (500, 50);
win3 = glutCreateWindow ("Ventana 3");
init();
glutDisplayFunc(display3);
glutReshapeFunc(reshape3);
glutSetWindow(win3);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutIdleFunc(idle3);
}
else if ((glutGetWindow() == win3) && (button == GLUT_RIGHT_BUTTON)){
glutIdleFunc(NULL);
glutDestroyWindow(win3);
//glutSetWindow(win1);
}
}
}
int main(int argc, char** argv)
{
//Configuracion de la primera ventana
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
win1 =glutCreateWindow ("Fractal");
glutSetWindow(win1);
init ();
glutDisplayFunc(display1);
glutReshapeFunc(reshape1);
glutIdleFunc(NULL);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}