martes, 29 de mayo de 2007

Previo Práctica 10 Laboratorio

1. Investigación acerca de la 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.

Un modelo 3d está compuesto por cientos o miles de polígonos de distintas formas y tamaños que unidos entre sí forman la figura deseada. Esta técnica ha sido la más efectiva hasta el momento y se ha usado constantemente durante los últimos años. El problema llega cuando, cuando queremos mover un brazo o la cabeza o una parte de la figura. La "malla" de polígonos que lo forma ha de modificarse de modo que los polígonos que daban forma a su hombro se tienen que extender o contraer.

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.


El único problema que representa la creación de modelos 3d a partir del un esqueleto se encuentra en la unión de los distintos huesos. Entre un hueso y otro existe un espacio que, siguiendo el símil con el cuerpo de los vertebrados reales, llamaremos articulación. Esta articulación se contrae, se estira y de deforma de distintas formas dependiendo del movimiento que hagan los dos huesos que une. En el siguiente gráfico podemos ver de lo que hablamos...

La grieta que se crea entre ambos huesos es algo que no se puede mostrar en la imagen final. Para esconderla se utiliza la técnica "Skinning" que, como su nombre indica, se encarga de recubir de piel estas imperfecciones.



Mediante esta piel flexible, que une cada uno de los vértices de un hueso con el correspondiente en el otro, se da continuidad al objeto y se acerca mucho al movimiento totalmente natural que podemos observar en cualquier ser vivo. Un problema que genera esta "piel" radica en la textura que recubre esta piel así piues el problema radica en cómo unir los distintos huesos de modo que la apariencia final sea realista.





2. Archivos FBX

FBX es un formato binario que soporta toda clase de información 3D, 2D, video y audio, por lo que facilita enormemente la comunicación entre distintas aplicaciones (como Cinema4D, Lightwave, 3D Studio).


Los archivos de formato FBX presenta nuevas características, tales como capacidad para animación con múltiples cámaras ó compatibilidad para la integración trabajos 3D de formato FBX de Kaydara. Igualmente los usuarios podrán importar y manipular directamente modelos 3D generados por el software 3ds max de Discreet y por las aplicaciones 3D más populares del mercado, entre las que se pueden nombrar SoftimageXSI, Softimage3D y Lightwave. Es decir, esto hace posible importar modelos 3D e informaciones como texturas, animaciones por cuadro, luz y otras especificaciones de cámara, atributos que antiguamente se tenían que reconstruir manualmente en una inversión de largas horas de trabajo.

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.


Ficheros .X son archivos que nos permiten " almacenar los objetos" y "racionarlos entre si". Esto es común a la mayoría de los formatos de almacenamiento de objetos 3D. Asi es como lo resuelve el formato .X:

- Tipos de datos definidos por el usuario:

Los ficheros .X estan compuestos de plantillas, que pueden ser definidas por el usuario. Una plantilla es una "definición de como quiere el usuario que se almacene la información".

Existen unas plantillas por defecto que se encuentran en rmxftmpl.h (d3dfile.cpp ) y rmxftmpl.x en c:\mssdk\include. Las firmas de identificación en rmxfgguid.h (tambien incluido en 3d3file.cpp, uno de los Common files)

- Relaciones jerarquicas:

Los tipos de datos consentidos por un plantilla se llaman "miembros opcionales". Estos miembros opcionales se almacenan como hijos del objeto. Los hijos pueden ser a su vez objetos, referencias a un objeto anterior, o datos binarios.


La herramienta que nos permitre crear ficheros ‘name.x’ viene en el SDK de DirextX "Optimized Mesh Example"

lunes, 21 de mayo de 2007

Previo Práctica 9 Laboratorio

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

Se definen así a los dibujos que son esenciales para definir puntos de inicio y de fin de cualquier transición que se considere suave. Se les llama “frames” (marcos) porque su posición en el tiempo se mide en marcos en un fragmento de filme. Una secuencia de key frames define cuál movimiento verá el espectador, mientras que la posición de los key frames en el filme, video o animación definen el tiempo del movimiento.

Como sólo dos o tres key frames sobre la extensión de un segundo no crea la ilusión de movimiento, los frames restantes son llenados con más dibujos, llamados “inbetweens” (intermedios).


FORWARD KINEMATICS

Se le llama así al método de animación en tres dimensiones que anima modelos a partir de que las posiciones de partes particulares del modelo en un momento especificado son calculadas desde la posición y la orientación del objeto, junto con cualquier información sobre las articulaciones de un modelo con tal atributo.

Por ejemplo, si el objeto a ser animado es un brazo con un hombro que debe permanecer en una posición fija, la localización de la punta del pulgar sería calculada desde los ángulos de las articulaciones del hombro, codo, muñeca, pulgar y de los nudillos. Tres de dichas articulaciones (el hombro, la muñeca y la base del pulgar) tienen más de un grado de libertad y deben de ser tomados en cuenta. Si el modelo fuera una figura humana entera, entonces la localización del hombro también tendría que ser calculada desde otras propiedades del modelo.

INVERSE KINEMATICS

Consiste básicamente en determinar los parámetros de un objeto articulado y flexible (una cadena cinemática) con tal de lograr una posición deseada. La cinemática inversa también es relevante para la programación de videojuegos y la animación 3D, donde un uso común es asegurarse de que los personajes del juego se conecten al mundo físicamente, tal como lo que es aterrizar los pies firmemente sobre terreno, alinear las manos con perillas, etc.

Se define una figura articulada como un conjunto de segmentos rígidos conectados por articulaciones. El variar los ángulos de las articulaciones provee un número infinito de configuraciones. La solución al problema de animación por cinemática directa, dados estos ángulos, es la pose de la figura. La solución más complicada al problema de la cinemática inversa es hallar los ángulos de articulación dada la configuración deseada de una figura. En los casos generales, no hay una solución analítica para el problema de cinemática inversa. Sin embargo, la cinemática inversa puede ser solucionada a partir de técnicas de programación no lineales. Ciertas cadenas cinemáticas especiales – aquellas con una muñeca esférica – permiten una separación cinemática.

MOTION CAPTURE

Técnica para grabar digitalmente movimientos, que inició 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.

Consiste básicamente en un actor que 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. Un programa 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.


Movimiento mecánico: 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 incluidas 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: Control total de la animación a realizar
Desventajas: No es óptimo para ambientes dinámicos muy grandes ya que no permite establecer interacciones realistas.

Se utiliza sobre todo en animaciones con Flash y el desarrollo de caricaturas por ordenador.


Cinemática Directa

Ventajas: El modelo y su movimiento se definen claramente por el programador, no se emplean gravedad ni colisiones, las cuales afectan al modelo.
Desventajas: El programado del movimiento de cada uno de los componentes debe ser realizado con mucha precisión ya que se pueden comerter errores importantes.

El campo de aplicaciones más amplio es en a robótica y las animaciones por ordenador en dos y tres dimensiones.

Cinemática Inversa

Ventajas: Para determinar el flujo de la animación sólo son necesarios la posición inicial y la final de un miembro.
Desventajas: Se deben definir razgos comunes para el personaje a animar, esto es, que la animación sea coherente.

Se utiliza principalmente en robótica y animaciones por computadora en dos y tres dimensiones.

Captura de Movimiento

Ventajas: La captura y despliegue de movimiento se realizan de una manera rápida y el trabajo no se multiplica si se utilizan modelos o animaciones muy grandes.Se desarrollan modelos físicos que permiten la interacción de la animación con el medio
Desventajas: El procesamiento y despliegue de la información se realizan con Hardware y Software específico, aumentando considerablemente su costo.El movimiento que no siga las leyes de la física generalmente no puede ser representado.

En la actualidad se utiliza en películas como Space Jam y en videojuegos donde se obtiene la captura de los modelos humanos (Ghost Recon)


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

Se emplea un sistema que permite hasta cuatro influencias de hueso en un vértice y la utilización de esqueletos complejos. Maneja además un soporte completo para mallas y huesos de LOD.

Emplea paquetería muy específica para el modelado de la animación por organización. Tal es el caso de AnimSet Viewerlo que permite la inclusión de notificaciones en animaciones específicas. Permite colocar "Sockets" graficos en los huesos para permitir la unión de objetos con ese esqueleto. Permiten ver mallas revestidas basadas en el mismo esqueleto como armaduras.

Se utiliza un árbol de animación o AnimTree el cual permite la utilización de Controles Mezclados y Controles manejados por Datos, lo cual permite la encapsulación de captura de movimiento, Controles de Física, etc. Esto permite la respuesta física a impulsos

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.

Entre las herramientas para el cargado de modelos se tienen las de 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 entre sí.

Esto se utiliza principalmente 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 de Referencia:
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
Un agradecimiento especial a Rafael Mesa.

lunes, 14 de mayo de 2007

Tarea #8 Teoría

Pseudocódigo para relleno de polígonos por barrido.

El llenado de polígonos por línea de barrido es un método relativamente fácil para rellenar un polígono.

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, 480)

Determinar las intersecciones de la línea de barrido con las aristas del polígono, variando x desde 0 hasta XMAX(640).

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 :

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)

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)



Fuente de Consulta para la tarea:
http://www.inf.unitru.edu.pe/~vncc/documentos/clases/cg1-u31.pdf

domingo, 13 de mayo de 2007

Tarea #7 Teoría, Reposicion de la 6

Refracción especular o Componente Especular de la Luz


Es la que procede de una dirección concreta y se refleja en una
única dirección, de manera que produce brillos intensos en ciertas zonas.
Es el caso, por ejemplo, de los objetos metálicos.

Cada foco de luz que incluyamos en la escena tiene tres componentes: luz ambiental, luz difusa y luz especular. La proporción de cada componente determina el tipo de luz. Por ejemplo, un láser esta casi totalmente formado por luz especular. Su fomulación matemática se representa bajo las Leyes de refracción especular:


El rayo refractado se encuentra localizado en el mismo plano que el incidente (-L) y la normal (N), tomando la ley de Snell para el ángulo del rayo transmitido:

ni sen α=nt sen β

donde,
ni , nt : son los índices de refracción en medios de rayo incidente y transmitido
α β: son los ángulos de rayo incidente y rayo transmitido con la normal

Rayo transmitido:



que es el índice de refracción relativo y calculando el factor de incidencia




La intensidad aproximada se calcula con :



donde,
krs : es el coeficiente de refractividad especular
k : es el exponente de rugosidad (coarsiness): aproxima transparencia imperfecta

También se pueden considerar efectos de distancia, como en la reflexión
Hay un valor de Its , Ip y krs para cada componente de color (RGB)
Existencia de filtros:



que es el rayo transmitido en dirección a ojo
Se debe considerar a la normal tal que:
; este tipo de rayo de luz puede ir hacia dentro de objeto en el caso de estudiar refracción de salida del objeto, cosa que se ve en la asignatura de Optica.

sábado, 5 de mayo de 2007

Previo Práctica 8 Laboratorio

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 0GL_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).Es importante aclarar que el efecto óptico desarrollado por la luz sobre el material depende en gran forma de las características del mismo. Se complementan mutuamente dando así el efecto deseado.

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

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
• 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


//Programa que genera cubos de materiales y de imagenes bitmap
//Antonio Davalos de los Rios
#include
#include
#include "bitmap.h"

static int spinx = 0;
static int spiny = 0;
static int p1 = 1;
static int p2 = 1;
static int ry,rx,rz;
BITMAPINFO *TexInfo; /* Texture bitmap information */
GLubyte *TexBits; /* Texture bitmap pixel bits */
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);
glPushMatrix ();
//gluLookAt (6.0, 6.0, 8.0, 2.0, 3.0, 0.0, 0.0, 1.0, 0.0);
gluLookAt (-7.0, 7.0, 7.0, 2.0, 0.0, 0.0, 0.0, 1.0, 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(2,2,2);
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 ();
// Primer lado del cubo de materiales
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 ();
//Segunda cara del cubo
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 ();
//Tercera cara del cubo
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 ();
//Cuarta cara del cubo de materiales
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 ();
//Quinta cara
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 ();
//Sexta cara
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*/

//Despliegue del cubo con imagenes

glPushMatrix();

glTranslated (-2.0, 3.5,3.5 );
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);

//se activa el mapeado de texturas
glEnable(GL_TEXTURE_2D);
//Despliegue de primer textura
TexBits = LoadDIBitmap("abe.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);
//Fin despliegue primer textura
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);
glEnable(GL_TEXTURE_2D);
//Despliegue de segunda textura
TexBits = LoadDIBitmap("galleta.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);
//Fin despliegue segunda textura
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);
glEnable(GL_TEXTURE_2D);
//Despliegue de tercera textura
TexBits = LoadDIBitmap("sirenoman.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);
//Fin despliegue tercera textura
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);
glEnable(GL_TEXTURE_2D);
//Despliegue de cuarta textura
TexBits = LoadDIBitmap("carlito.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);
//Fin despliegue cuarta textura
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);
glEnable(GL_TEXTURE_2D);
//Despliegue de quinta textura
TexBits = LoadDIBitmap("towelie.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);
//Fin despliegue quinta textura
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);
glEnable(GL_TEXTURE_2D);
//Despliegue de sexta textura
TexBits = LoadDIBitmap("Dr_Abe.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);
//Fin despliegue sexta textura
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);
glutSwapBuffers() ;
glPopMatrix();
//Fin del despliegue del cubo con imagenes

glPopMatrix ();
glFlush ();
}

void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.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_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (600, 600);
glutInitWindowPosition (200, 100);
glutCreateWindow ("Las flechas mueven las luces, A S y D rotan el cubo" );
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
glutMainLoop();
return 0;
}

martes, 1 de mayo de 2007

Tarea #7 Teoría

Componente Especular de la Luz

Es la que procede de una dirección concreta y se refleja en una
única dirección, de manera que produce brillos intensos en ciertas zonas.
Es el caso, por ejemplo, de los objetos metálicos.

Cada foco de luz que incluyamos en la escena tiene tres componentes: luz ambiental, luz difusa y luz especular. La proporción de cada componente determina el tipo de luz. Por ejemplo, un láser esta casi totalmente formado por luz especular.



Las componentes difusa y ambiental son mínimas y se deben a la presencia de polvo en el
ambiente. Un foco, sin embargo, tiene una parte importante de luz ambiental y difusa, y una
parte mínima de luz especular.

Cuando se define un foco de luz, no sólo es necesario definir las tres componentes de la luz, sino también el color de cada componente.

Fuente de Consulta
www.cs.buap.mx/~asanchez/iluminacion2.pdf

domingo, 15 de abril de 2007

Previo Práctica 7 Laboratorio

Este es el codigo del previo de la practica 7, el despliegue del humanoide se muestra con la instruccion humanoide.

//Fractal de alguien cuyo nombre no se escribir --> Sarpinski
#include GL/glut.h
#include stdlib.h
#include stdio.h
#include time.h

static int valor_prueba = 1;
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 pz = 0;
static int ventana2, ventana1, ventana3;
static float movX = 0;
static float movY = 0;
void humanoide(void);

void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void display(void)
{
int i= 0;
srand(time(NULL));
glClear (GL_COLOR_BUFFER_BIT);
px = rand()%20;
py = rand()%20;
pz = rand()%20;
pz = pz/10;
px = px/10;
py = py/10;
glColor3f (0.7, 0.7, 0.7);
glLoadIdentity ();
gluLookAt (0.0,0.0,5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

//Despliegue de los puntos iniciales de los triangulos
//Al desplegar los puntos se cambia de color haciendo
//un efecto de coloreado
glBegin(GL_POINTS);
glVertex2f(px1,py1);
glEnd();
glColor3f (pz, px, py);
glBegin(GL_POINTS);
glVertex2f(px2,py2);
glEnd();
glBegin(GL_POINTS);
glVertex2f(px3,py3);
glEnd();
glColor3f (px, py, pz);
glBegin(GL_POINTS);
glVertex2f(px,py);

glEnd();
//calculo de los puntos medios
do
{
valor_prueba = rand()%3;
if(valor_prueba == 0)
{
px = (px1 + px)/2;
py = (py1 + py)/2;
}
if(valor_prueba == 1)
{
px = (px2 + px)/2;
py = (py2 + py)/2;
}
if(valor_prueba == 2)
{
px = (px3 + px)/2;
py = (py3 + py)/2;
}
glBegin(GL_POINTS);
glVertex2f(px,py);
glEnd();
i++;
}while (i < 77777);
glFlush ();
}

//Esta funcion es igual a display pero se hace un "zoom" al fractal, que es un escalamiento
void display2(void)
{
int i= 0;
srand(time(NULL));
glClear (GL_COLOR_BUFFER_BIT);
px = rand()%20;
py = rand()%20;
pz = rand()%20;
pz = pz/10;
px = px/10;
py = py/10;
glColor3f (0.7, 0.7, 0.7);
glLoadIdentity ();
gluLookAt (0.0,0.0,5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

//Despliegue de los puntos iniciales de los triangulos
//Al desplegar los puntos se cambia de color haciendo
//un efecto de coloreado
glBegin(GL_POINTS);
glVertex2f(px1,py1);
glEnd();
glColor3f (pz, px, py);
glScalef(4,4,1);
glBegin(GL_POINTS);
glVertex2f(px2,py2);
glEnd();
glBegin(GL_POINTS);
glVertex2f(px3,py3);
glEnd();
glColor3f (px, py, pz);
glBegin(GL_POINTS);
glVertex2f(px,py);

glEnd();
//calculo de los puntos medios
do
{
valor_prueba = rand()%3;
if(valor_prueba == 0)
{
px = (px1 + px)/2;
py = (py1 + py)/2;
}
if(valor_prueba == 1)
{
px = (px2 + px)/2;
py = (py2 + py)/2;
}
if(valor_prueba == 2)
{
px = (px3 + px)/2;
py = (py3 + py)/2;
}
glBegin(GL_POINTS);
glVertex2f(px,py);
glEnd();
i++;
}while (i < 77777);
glFlush ();
}

void reshape (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 (movX, movY, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode (GL_MODELVIEW);
}

//Funcion del teclado, al apretar ESC se cierra el programa
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
case 'q':
glutPostRedisplay();
break;
}
}

//Funcion mouse para mandar a imprimir la coordenada
void mouse(int button, int state, int x, int y)
{
if (state == GLUT_DOWN)
{ //Despliegue para la ventana del punto del fractal
if ((button == GLUT_LEFT_BUTTON) && (glutGetWindow() == ventana1))
{
printf("Hiciste click en la posicion: %d, %d \n", x,y);
movX = 400 - x;
movY = y - 300;

glutInitWindowSize (800,600);
glutInitWindowPosition (400, 100);
ventana2 = glutCreateWindow ("Centrado del Fractal");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape2);
glutSetWindow(ventana2);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);

}
//Condicion para el cierre de la ventana con el click derecho
else if ((glutGetWindow() == ventana2) && (button == GLUT_RIGHT_BUTTON))
{
glutDestroyWindow(ventana2);
glutSetWindow(ventana1);
printf("Se ha cerrado la ventana nueva\n");
}
//Despliegue para la ventana del humanoide
else if ((button == GLUT_RIGHT_BUTTON) && (glutGetWindow() == ventana1))
{
printf("Hiciste click en la posicion: %d, %d \n", x,y);
glutInitWindowSize (300,300);
glutInitWindowPosition (200, 100);
ventana3 = glutCreateWindow ("Animacion del Humanoide");
//Aqui se tiene que desplegar al humanoide bailando
init();
humanoide();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutSetWindow(ventana3);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);


}
//Condicion para cerrar la ventana con el click derecho
else if ((glutGetWindow() == ventana3) && (button == GLUT_RIGHT_BUTTON))
{
glutDestroyWindow(ventana3);
glutSetWindow(ventana1);
printf("Se ha cerrado la ventana nueva\n");
}
}
}
int main(int argc, char** argv)
{
//Configuracion de la primera ventana
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (800, 600);
glutInitWindowPosition (50, 50);
ventana1 = glutCreateWindow ("Click Izquierdo: Da coordenada y nueva ventana - Click Derecho: Ventana con humanoide - ESC: Cierra");
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);

glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}

Reporte Práctica 6 Laboratorio

El Desarrollo de la práctica 6 fue enviado por correo electrónico el dia martes.

Reporte de la práctica 6.

// Antonio Dávalos de los Ríos
// Programa que despliega figuras aleatorias, al dar click izquierdo del mouse cambian de forma
//con el click derecho regresan ColorR su estado anterior

#include
#include
//Estas variables nos indican el color de la linea a desplegar,
//Se harán aleatorias para q cada vez que se cambie la linea cambie el color
static float ColorR=1;
static float ColorG=1;
static float ColorB=1;
static float x;
static float y;
static float base;
static float altura;
int seleccion=0;
int i;
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT);
glShadeModel (GL_FLAT);
}

void display(void)
{
//Generación de los colores para el despliegue
//Son valores aleeatorios
ColorR=rand()%10;
ColorR=ColorR/10;
ColorB=rand()%10;
ColorB=ColorB/10;
ColorG=rand()%10;
ColorG=ColorG/10;
glColor3f (ColorR, ColorB, ColorG);
glLoadIdentity ();

gluLookAt (2.0,0.0,6.0,2.0,0.0, 0.0, 0.0, 5, 0.0);
glPushMatrix();
glTranslatef(-0.5,-2.3,0.0);
//este switch es el que hace que se desplieguen lineas, triangulos o cuadrilateros
switch(seleccion)
{
case 0:
//Generacion de las rectas
glBegin(GL_LINE_LOOP);
for (i=0;i<2;i++) i="0;i<3;i++)" x="rand()%6;" y="rand()%6;" base="rand()%6;" altura="rand()%6;" button ="="" state ="="" seleccion="="3)" seleccion="0;" j="0;j<30000000;j++){}" j="0;j<30000000;j++){}">

sábado, 14 de abril de 2007

Tarea #6 Teoría

Nonuniform rational B-spline

Extracto de Texto traducido del original en Inglés
http://en.wikipedia.org/wiki/NURBS
Texto de apoyo:
http://en.wikipedia.org/wiki/Numerically_stable

Una curva NURB se define por su orden que es un conjunto de puntos de control, y de un vector nudo. Este tipo de curvas y superficies son una generalización de las curvas de Bézier y de las B-Splines. La diferencia primordial radica en que el "peso" de los puntos de control que hacen a las curvas NURBS racionales. Aqui las curvas NURB evolucionan hacia una sola dirección paramétrica, lammada comunmente S o U. Las superficies evolucionan en dos direcciones paramétricas llamadas S y T ó U y V.


Al evaluar una curva de este tipo en varios valores del parámetro, se puede representar la curva en un espacio cartesiano de dos o tres dimensiones. De esta forma, al evaluar una superficie NURB con diferentes valores de los dos parámteros, la superficie se puede representar en el espacio cartesiano

Estas rectas y superficies son útiles por diversas razones:

  • Son invariantes ante transformaciones de perspectiva y afines.
  • Ofrecen una forma matemática común para las formas analíticas y para las formas libres.
  • Proveen flexibilidad para el diseño de una gran variedad de formas.
  • Reducen el consumo de memoria cuando se almacenan figuras.
  • Pueden ser evaluadas razonablemente rápido por estabilidad numérica y algoritmos eficaces.
  • Son generalizaciones de B-Splines no racionales y curvas Bézier de los dos tipos.

El vector nudo es una secuencia de valores de parámetros que determinan donde y cómo se afecta el control de una curva NURB. El número de nudos siempre es igual al número de puntos de controlmás el grado de la curva más uno. Necesarios para cálculos internos, los nudos no son generalmente útiles para los usuarios de software de modelado. Por lo tanto, muchas aplicaciones no hacen a los nudos editables o siquiera visibles.

Versiones recientes de software basado en NURBS como el Autodesk Maya y Rhinoceros 3D, permiten la maniulación interactiva de la posición de los nudos, pero esto es significativamente menos intuitivo que la edición de los puntos de control.

martes, 10 de abril de 2007

Tarea #5 Teoría

Hola,

Este es el algoritmo de Bresenham desarrollado en pseudocódigo para la recta, notese que ha sido modificado para las pendientes especificadas. Se deben considerar además del traslado hacia el este y noreste, el traslado hacia el norte.

Fuente de Consulta http://en.wikipedia.org/wiki/Bresenham

Void rectaBresenham(int x0, y0, x1,y1)
{
//Declaracion de Variables a utilizar
int dx= x1 – x0;
int dy= y1 – y0;
int x=x0 ;
int y= y0;
//definicion del error inicial
int d0=2*dy-dx;
//definicion del error al moverse hacia el este
int de= 2* dy;
//definicion del error al moverse hcia el noreste
int dne = 2*(dy –dx);
int d=d0 ;
int m=(dy/dx)+1 ;

//ciclo de análisis para la locación de la recta
while(x!=x1)
{
if (d<=0){
if (m<-1){
punto(x,y);
x=x-m;
d= d + de;
else{
punto(x,y);
x=x+m;
d= d + de;
}

else{

if (m<-1){
punto(x,y);
x=x-m;
y=y+m;
d= d + dne;
}
else
{
punto(x,y);
x=x+m;
y=y+m;
d= d + dne;
}
}

Previo Práctica 6 Laboratorio parte 2

Códigos para los programas de cronómetro, despliegue de nombre con stroke y con bitmap.

//Antonio Dávalos de los Ríos
//Este programa despliega mi nombre utilizando bitmap

#include
#include

//Aqui se define la fuente a utilizar, en un arreglo se definen las otras fuentes
void *font = GLUT_BITMAP_HELVETICA_18;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};
//Este es el mensaje por default, es en caso de mandar sólo a desplegar el contenido del apuntador
char defaultMessage[] = "Dr. Abe";
char *message = defaultMessage;


//Funcion que despliega cada caracter
void
output(int x, int y, char *string)
{
int len, i;

glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}

void
display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 1.0);
//Aqui cambio el color de la fuente
output(250, 270, "Antonio Davalos de los Rios");
glutSwapBuffers();
}

//Funcion que realiza los cambios con el mouse
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
{
font = GLUT_BITMAP_TIMES_ROMAN_10;
glutPostRedisplay();
}
else if (button == GLUT_RIGHT_BUTTON)
{
font = GLUT_BITMAP_TIMES_ROMAN_24;
glutPostRedisplay();
}
}

void
reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}

int
main(int argc, char **argv)
{
int i, msg_submenu, color_submenu;

glutInit(&argc, argv);
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-mono")) {
font = GLUT_BITMAP_9_BY_15;
}
}
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutInitWindowPosition (50, 100);
glutCreateWindow("Despliega mi nombre con BitMap");
glClearColor(0.0, 0.0, 0.0, 1.0);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}

//Antonio Dávalos de los Ríos
//Programa que despliega un cronómetro y puede controlarse con clicks del mouse
#include
#include
#include
#include

//Variables globales para el programa


static int inicio_cuenta=1; n;
static char label[8];
static float inc=0.2;
//Estas variables son las que contienen las horas minutos y segundos
static int hor_cd=0;
static int hor_ci=0;
static int min_cd=0;
static int min_ci=0;
static int seg_cd=0;
static int seg_ci=0;

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

//Funcion para el despliegue de texto utilizando stroke
void strokeText(char *s)
{
unsigned int i;
for (i=0; iglutStrokeCharacter(GLUT_STROKE_ROMAN,s[i]);
}
//Funcion que calcula el tiempo para desplegar los caracteres, cuenta con una serie de if anidados
void timer(int id)
{
if (inicio_cuenta==1)
{
if(seg_cd<=n)
{//Despliegue para los segundos y su cambio al llegar a 9
n=9;
seg_cd++;

if(seg_cd>n)
{//Despliegue de los dígitos de decenas en los segundos
seg_cd=0;
seg_ci++;

if(seg_ci>5)
{//Despliegue para los minutos al llegar a 59 segundos
seg_ci=0;
min_cd++;


}
}
}
}
}//Fin de las funciones if anidadas
glutTimerFunc(1000,timer,0);
glutPostRedisplay();
}
void entradaMouse(int boton, int situacion) {
if(situacion == GLUT_DOWN)
{
if(boton == GLUT_LEFT_BUTTON)
{
inicio_cuenta=1;
}
else{
if(boton == GLUT_RIGHT_BUTTON)
{
inicio_cuenta=0;
}
else
{
inicio_cuenta=1;
hor_cd=0;
hor_ci=0;
min_cd=0;
min_ci=0;
seg_cd=-1;//Se hace -1 para q se despliegue cero
seg_ci=0;
}
}
}
}
void display(void)
{
//COnversión de los caracteres para el correcto despliegue en la ventana
char sd=(char)(seg_cd+48);
char si=(char)(seg_ci+48);
char md=(char)(min_cd+48);
char mi=(char)(min_ci+48);
char hd=(char)(hor_cd+48);
char hi=(char)(hor_ci+48);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_MODELVIEW_MATRIX );
glLoadIdentity();
glColor3f(0.0, 0.0, 1.0);
glPushMatrix();
glTranslatef(200,200,0);
glScalef(inc,inc,inc);
//Diseño de los caracteres para el despliegue
sprintf(label,"%c%c:%c%c:%c%c",hi,hd,mi,md,si,sd);
strokeText(label);
glPopMatrix();
glFlush();
}

void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D(0, w, 0, h);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (600, 400);
glutInitWindowPosition (50, 50);
glutCreateWindow ("Click Izquierdo: Inicia - Click Derecho: Detiene");
init();
glutMouseFunc(entradaMouse);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutTimerFunc(1000,timer,1);
glutMainLoop();
return 0;


//Antonio Dávalos de los Ríos
//Programa que despliega mi nom_stroke utilizando comando stroke
//Utiliza al ratón para aumentar y disminuir el tamaño

#include
#include
#include
#include
static float escala_stroke = 0.0015;

//Funcion que sirve para desplegar el texto

void texto_stroke(GLfloat x, GLfloat y, char *nom_stroke)
{
//Funciones para el manejo de stroke
va_list args;
char nom_strokebuff[200], *apuntanom_stroke;
va_start(args, nom_stroke);
vsprintf(nom_strokebuff, nom_stroke, args);
va_end(args);
glPushMatrix();
//Los valores de la escala son para poder modificar cuando se da click derecho o izquierdo
glTranslatef(x, y, 0);
glScalef((GLfloat)escala_stroke, (GLfloat)(escala_stroke*3), (GLfloat)escala_stroke);
//Impresión de los caracteres del nombre
for (apuntanom_stroke = nom_strokebuff; *apuntanom_stroke; apuntanom_stroke++)
{
glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN , *apuntanom_stroke);
}
glPopMatrix();
}

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPerspective(40.0, 1.0, 0.1, 20.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
gluLookAt(0.0, 0.0, 9.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.);
glPushMatrix();
texto_stroke(-3.0, 0, "Antonio Davalos de los Rios");
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glFlush();
}
//Funcion para la utilizacion del mouse
void mouse(int button, int state, int x, int y)
{
if (state == GLUT_DOWN)
{
if (button == GLUT_LEFT_BUTTON)
{
escala_stroke = escala_stroke - 0.00005;
glutPostRedisplay();
}
else if (button == GLUT_RIGHT_BUTTON)
{
escala_stroke = escala_stroke + 0.00005;
glutPostRedisplay();
}
}
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, 0, h);
glScalef(1, -1, 1);
glTranslatef(0, -h, 0);
glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutInitWindowPosition (50, 50);
glutCreateWindow("Click Derecho: Disminuye - Click Izquierdo: Aumenta");
glClearColor(0.0, 0.0, 0.0, 1.0);
//Defino el color azul para desplegar
glColor3f(0, 0, 1);
//Defino el ancho de la linea del texto
glLineWidth(3.0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}

viernes, 6 de abril de 2007

Tarea #4 Teoría

Nota: Para evitar el posible plagio de la INVESTIGACIÓN DE LOS COMANDOS DE GLUT, el previo de laboratorio se subirá hasta antes de la clase.

El código utilizado es libre para su uso y modificación, de todos modos se registra la hora en que se sube al blog. La investigación de los comandos de GLUT no es libre ya que fue un trabajo exhaustivo de investigación y traducción.

Investigación acerca del algoritmo de Bresenham para rectas.

  1. El objetivo es minimizar el error usando aritmética entera
  2. Recta de (x1, y1) a (xN, yN) , coordenadas enteras
  3. Supongamos x1 < xN y que 0 <= m <= 1


  4. Cálculo de y2:
    Búsqueda de alternativa de menor error


  5. Como m es un número en coma flotante, se usa como parámetro de decisión:
  6. Cálculo de yi+1:



  7. Fórmula iterativa para pi:

  8. Algoritmo:
    1. Si , intercambiar los papeles de y y de x ()
    2. Si , intercambiar los puntos ()
    3. Si , decrementar la y () y tomar como positivo en el algoritmo
    4. Bucle hasta llegar a (xN, yN):
      1. xi+1=xi+1
      2. Si
      3. Si
  9. Nota
    1. La x del algoritmo es la coordenada de barrido (que puede ser la y por el punto 1.).
    2. La y del algoritmo es la coordenada calculada (que puede ser la x por el punto 1.).
    3. y son siempre positivos en el algoritmo y se corresponden con los incrementos de las coordenadas de barrido y calculada, respectivamente.
  10. Precálculo de constantes

Previo Práctica 6 Laboratorio parte 1

Comandos de GLUT

Aqui están los comandos que se encontraron, fue un trbajo compicado y cansado.

glutInit

El comando glutInit inicializa la librería de GLUT y negocia una sesión con el sistema de ventana. También procesa opciones de la línea de comando. Se utiliza de la siguiente manera:

void glutInit(int *argcp, char **argv)

Donde argcp es un apuntador a la variable sin modificar argc. Como regreso de esta función el valor al que apunta argcp es actualizado.

El parámetro argv es para la variable sin modificar de main argv. Como el parámetro anterior, actualiza el valor de argv.

glutInitWindowPosition y glutInitWindowSize

Estas funciones fijan los parámetros para la posición inicial y el tamaño de la ventana que se crea. Se utilizan de la siguiente manera:

void glutInitWindowSize(int width, int height);
void glutInitWindowPosition(int x, int y);

Donde width es el ancho de la ventana y height la altura en píxeles.

X y Y responden a las coordenadas de la ventana cuando se crea.

glutInitDisplayMode

Esta función fija el modo despliegue inicial. Este modo es para la creación de ventanas de alto nivel, subventanas y capas para determinar el display de OpenGL para la ventana que se va a crear. Se utiliza de la siguiente manera:

void glutInitDisplayMode(unsigned int mode);

Donde mode es la opción de máscara de bit deseada (la descripción de éstas se pueden encontrar en la fuente de referencia)

Las máscaras son:

GLUT_RGBA

GLUT_RGB

GLUT_INDEX

GLUT_SINGLE

GLUT_DOUBLE

GLUT_ACCUM

GLUT_ALPHA

GLUT_DEPTH

GLUT_STENCIL

GLUT_MULTISAMPLE

GLUT_STEREO

GLUT_LUMINANCE

glutMainLoop

Entra al loop de proceso de eventos. Esta rutina debe ser llamada al menos una vez en un programa de GLUT. Una vez llamada, esta rutina nunca va a retornar, sólo va a llamar todas las callbacks o llamadas de retorno que se hayan registrado. Se utiliza:

void glutMainLoop(void);

glutCreateWindow

Crea una ventana de alto nivel. Se utiliza de la siguiente manera:

 
int glutCreateWindow(char *name);

El nombre de la ventana es dado por la variable name. El estado de despliegue o display de una ventana es mostrada por la ventana inicialmente, pero el estado de despliegue no actúa hasta que se entra al ciclo generado por la función glutMainLoop. Esto quiere decir que no se puede renderizar efectivamente a esta ventana hasta que se haya entrado al ciclo.

glutCreateSubWindow

Crea una sub ventana a partir de los parámetros que obtiene. Se utiliza como:

int glutCreateSubWindow(int win, int x, int y, int width, int height);

Donde se tiene que especificar el nombre de la ventana a la cual se le quiera agregar la subventana (parámetro win). Los parámetros X y Y responden a la ubicación de la subventana dentro de la ventana original. Widht y Heigth especifican respectivamente el ancho y alto de esta subventana.

El estado de despliegue o display de la subventana es mostrada inicialmente, pero el estado de despliegue no actúa hasta que se entra al ciclo generado por la función glutMainLoop. Es similar a la utilización de la función glutCreateWindow.

glutSetWindow y glutGetWindow

glutSetWindow fija la ventana actual, glutGetWindow regresa el identificador de la ventana actual. Si no existen ventanas o la ventana actual fue destruida, glutGetWindow regresa el valor de 0. glutSetWindow no modifica la capa en uso para la ventana, esto se realiza mediane la función glutUseLayer. Se utilizan

void glutSetWindow(int win);
int glutGetWindow(void);
 

Donde win es el identificador de la ventana.

glutDestroyWindow

void glutDestroyWindow(int win);

Destruye a la ventana determinada por el parámetro win. Destruye también el contexto asociado por OpenGL, el mapa de colores lógico y las capas y estados relacionados. Cualquier subventana de la ventana destruida son tambien destruidas. SI la ventana a destruir es la actual, glutGetWindow regresa el valor de 0.

glutPostRedisplay

Marca el plano normal de la ventana actual según se necesite ser re desplegado. En la próxima iteración a través de glutMainLoop se llamará la llamada de retorno o callback para re desplegar el plano normal de la ventana

glutSwapBuffers

void glutSwapBuffers(void);

Realiza un intercambio de buffer en la capa en uso para la ventana actual. Específicamente, hace que el contenido del buffer trasero de la capa en uso se convierta en contenido del buffer frontal. En este paso el contenido del buffer trasero se considera cono undefined o indefinido. La actualización usualmente se realiza durante el re-trazado vertical del monitor, en vez de ser realizado inmediatamente después de llamar a la función glutSwapBuffers. Antes de retornar, esta función realiza un glFlush. Los comandos subsecuentes de OpenGL pueden ser ordenados inmediatamente después de llamar a la función, pero no son ejecutados hasta que el intercambio de buffers se complete.

glutPositionWindow

void glutPositionWindow(int x, int y);

Solicita un cambio en la posición de la ventana actual. Para ventanas de alto nivel los parámetros de X y Y son offsets de píxeles del origen de la pantalla. Para subventanas, la X y la Y son offsets de píxel de la ventana padre. Las solicitudes hechas por glutPositionWindow no son procesadas inmediatamente, son ejecutadas después de regresar al loop de evento principal. Para el caso de ventanas de alto nivel, esta función es considerada sólo como una petición para posicionar la ventana. El sistema de ventanas es libre de aplicar sus propias políticas para la colocación de ventanas de alto nivel; la intención es que estas ventanas puedan ser re-posicionadas de acuerdo a los parámetros de glutPositionWindow.

glutReshapeWindow

void glutReshapeWindow(int width, int height);

Donde width es el ancho nuevo de la ventana y height la nueva altura.

Realiza una petición de cambio de tamaño en la ventana actual. Los parámetros width y height son dados en píxeles y deben ser valores positivos.

Al igual que la función anterior, las solicitudes no son procesadas inmediatamente y para ventanas de alto nivel se considera como una petición de modificar la ventana.

glutFullScreen

void glutFullScreen(void);

Solicita que la ventana actual se haga de tamaño de la pantalla completa. El concepto de ventana completa varía de sistema dependiendo del sistema de ventana. La idea es hacer la ventana tan larga como sea posible y deshabilitar cualquier decoración o borde de ventana añadidos al sistema de ventanas. El largo y ancho de la ventana no se garantiza que sean los mismos que los de la pantalla, pero esa es la intención de hacer la ventana de tamaño completo.

Esta función está definida sólo para ventanas de alto nivel. Al igual que las dos instrucciones anteriores, no se procesa inmediatamente.

glutPopWindow y glutPushWindow

void glutPopWindow(void);
void glutPushWindow(void);

Estos comandos funcionan para los dos niveles de ventanas, principales y subventanas. El efecto de hacer un push y pop en las ventanas no se realiza inmediatamente. En vez de eso, se salva la ejecución hasta regresar al ciclo de evento de GLUT. Subsecuentemente, estas instrucciones solicitan un reemplazo de la petición anteriormente guardada para esa ventana. El efecto de hacer pop y push en ventanas de alto nivel es a consideración de la política del sistema de ventanas para apilar las mismas.

glutShowWindow, glutHideWindow, glutIconifyWindow

void glutShowWindow(void);

void glutHideWindow(void);

void glutIconifyWindow(void);

glutShowWindow muestra la ventana actual.

glutHideWindow oculta la ventana actual.

glutIconifyWindow minimiza la ventana actual.

glutSetWindowTitle, glutSetIconTitle

void glutSetWindowTitle(char *name);

void glutSetIconTitle(char *name);

name: deberá conformarse por una cadena de caracteres ASCII.

glutSetWindowTitle pone la barra de título en la ventana

glutSetIconTitle pone la barra de título en la ventana minimizada

glutSetCursor

void glutSetCursor(int cursor);

cursor

Nombre de la imagen del cursor a cambiar.

GLUT_CURSOR_RIGHT_ARROW

Flecha que señala encima y a la derecha.

GLUT_CURSOR_LEFT_ARROW

Flecha que señala encima y a la izquierda.

GLUT_CURSOR_INFO

Señalador de mano.

GLUT_CURSOR_DESTROY

Cráneo y huesos encrusijados.

GLUT_CURSOR_HELP

Marca de pregunta.

GLUT_CURSOR_CYCLE

Flecha que está rotando en un círculo.

GLUT_CURSOR_SPRAY

Lata de aerosol.

GLUT_CURSOR_WAIT

Reloj.

GLUT_CURSOR_TEXT

Cursor para apuntar a la insercion de texto.

GLUT_CURSOR_CROSSHAIR

Cortador.

GLUT_CURSOR_UP_DOWN

Puntero bidireccional arriba y abajo.

GLUT_CURSOR_LEFT_RIGHT

Puntero bidireccional izquierda y derecha

GLUT_CURSOR_TOP_SIDE

Flecha que upunta a un lado superior.

GLUT_CURSOR_BOTTOM_SIDE

Flecha que apunta a un lado inferior.

GLUT_CURSOR_LEFT_SIDE

Flecha que apunta a un lado izquierdo.

GLUT_CURSOR_RIGHT_SIDE

Flecha que apunta a un lado derecho.

GLUT_CURSOR_TOP_LEFT_CORNER

Flecha que apunta a la esquina superior izquierda.

GLUT_CURSOR_TOP_RIGHT_CORNER

Flecha que apunta a la esquina superior derecha.

GLUT_CURSOR_BOTTOM_RIGHT_CORNER

Flecha que apunta a la esquina inferior izquierda.

GLUT_CURSOR_BOTTOM_LEFT_CORNER

Flecha que apunta a la esquina inferior derecha.

GLUT_CURSOR_FULL_CROSSHAIR

Cursor de pantalla completa del cortador.

GLUT_CURSOR_NONE

Cursor invisible.

GLUT_CURSOR_INHERIT

Uso del cursor padre.

glutSetCursor cambia la imagen del cursor de la ventana actual.

glutEstablishOverlay

void glutEstablishOverlay(void);

glutEstablishOverlay: establece un recubrimiento (si es posible) para la ventana actual. El modo de despliegue solicitado para el recubrimiento es determinado por el modo inicial de despliegue.

glutLayerGet(GLUT_OVERLAY_POSSIBLE): puede ser llamado para determinar si un recubrimiento es posible en la ventana actual con el modo inicial de despliegue actual. No intente establecer un recubrimiento cuando no es posible, ya que GLUT terminará el programa.

Si glutEstablishOverlay es llamado cuando un recubrimiento ya existe, el recubrimiento existente es removido primero, y entonces un nuevo recubrimiento es establecido.

glutUseLayer

void glutUseLayer(GLenum layer);

layer

Cualquier GLUT_NORMAL o GLUT_OVERLAY, selecciona el plano normal o el recubrimiento respectivamente.

glutUseLayer: cambia la capa en uso por ventana para la ventana actual, seleccionando cualquier plano normal o recubrimiento. El recubrimiento debe sólo ser especificado si es que existe, sin embargo una ventana sin recubrimiento puede todavía llamar a glutUseLayer(GLUT_NORMAL). Los comandos OpenGL para ventanas están dirigidos a la actual capa en uso.

Para saber la capa en uso en un ventana puede llamar a glutLayerGet(GLUT_LAYER_IN_USE).

glutRemoveOverlay

void glutRemoveOverlay(void);

glutRemoveOverlay remueve el recubrimiento (si es que existe). Es seguro llamar a glutRemoveOverlay incluso si no hay un recubrimiento establecido actualmente, no hará nada en ese caso. Implícitamente, la capa en uso de la ventana cambia al plano norma inmediatamente un vez que haya sido eliminado el recubrimiento.

Si el programa intenta reestablecer el recubrimiento mas tarde, es típicamente mas rápido y hacienda uso de menos recursos utilizar glutHideOverlay and glutShowOverlay que simplemente cambia el estado de despliegue del recubrimiento.

glutPostOverlayRedisplay

void glutPostOverlayRedisplay(void);

Marca el recubrimiento de la ventana actual como necesitando ser re-desplegado. La siguiente iteración a través de glutMainLoop, el recubrimiento de la ventana desplegará el callback (o simplemente el despliegue del callback si no hay un recubrimiento registrado en el despliegue del callback) será llamad a re-desplegar el plano del recubrimiento de la ventana. Llamadas múltiples con glutPostOverlayRedisplay antes de dar oportunidad al siguiente despliegue del callback(o la oportunidad al despliegue del callback con el recubrimiento si es que se registra alguno) se genera olamente un único re-despliegue. glutPostOverlayRedisplay podrá ser llamado dentro despliegue del callback o recubrimiento de la ventana y así remarcar esa ventana para su re-despliegue.

Lógicamente, Una notificación de daños de un recubrimiento para una ventana se trabaja con glutPostOverlayRedisplay sobre la ventana dañada. Diferente al daño reportado por sistema de la ventana, glutPostOverlayRedisplay no fijará el verdadero estado de daño del recubrimiento (retornado por glutLayerGet(GLUT_OVERLAY_DAMAGED)).

glutShowOverlay, glutHideOverlay

void glutShowOverlay(void);

void glutHideOverlay(void);

glutShowOverlay muestra el recubrimiento de la ventana actual; glutHideOverlay oculta el recubrimiento. El efecto de mostrar u ocultar un recubrimiento tiene lugar inmediatamente. Note que glutShowOverlay no mostrará realmente el recubrimiento a menos de que la ventana también sea mostrada (e incluso una ventana mostrada podrá ser ocultada por otras ventanas, a tal grado ocultando el recubrimiento). Es típico, más rápido y hacienda uso de menos recursos del sistema utilizar estas rutinas para controlar el estado despliegue de un recubrimiento a quitar y reestablecer el recubrimiento.

glutCreateMenu

int glutCreateMenu(void (*func)(int value));

func

La función callback para el menú es llamada cuando una entrada del menú se selecciona. El valor pasado al callback es determinado por el valor de la selección de la entrada del menú.

glutCreateMenu crea un nuevo menú pop-up y retorna un único identificador entro pequeño. El rango asignación a los identificadores inicia en uno. El rango identificador de menú es independiente de el rango identificador de ventana. Implícitamente, el menú actual es fijado a es menú creado nuevamente. Este identificador de menú puede ser usado llamando a glutSetMenu.

Cuando el menú callback es llamado porque una entrada es seleccionada para el menú, el menú actual será implícitamente fijado a el menú con la entrada seleccionada antes el callback es hecho.

glutSetMenu, glutGetMenu

void glutSetMenu(int menu);

int glutGetMenu(void);

menu

El identificador del menú para hacer el menú actual.

glutSetMenu fija el menú actual; glutGetMenu devuelve el identificador del menú actual. Si no existen menús o el menú anterior fue eliminado, glutGetMenu devuelva cero.

glutDestroyMenu

void glutDestroyMenu(int menu);

menu

El identificador del menú a destruir.

glutDestroyMenu destruye el menú especificado por el argumento menú. Si el argumento menú fuera el del menú actual, el menú actual se convierte en inválido y glutGetMenu devolverá cero.

glutAddMenuEntry

void glutAddMenuEntry(char *name, int value);

name

Cadena de caracteres ASCII a desplegar en la entrada del menu.

value

Valor a devolver a la función callback del menú si la entrada del menú es seleccionada.

glutAddMenuEntry agrega una entrada de menú en la ultima parte del menú actual. La cadena name se desplegará para la entrada agregada nuevamente. Si la entrada de menú es seleccionada por el usuario, el callback del menú será llamado pasando value como parámetro de callback.

glutAddSubMenu

void glutAddSubMenu(char *name, int menu);

name

Cadena de caracteres ASCII a desplegar en el objeto menu del cual se deriva el sub-menu.

menu

Identificador de el menú del que se va a derivar este sub-menú.

glutAddSubMenu agrega un sub-menu activador en el fondo del menu actual. La cadena name sera desplegada para el sub-menu activador agregado nuevamente. Si el sub-menu activador es incorporado, el sub-menú será numerado por el argumento menu y será colocado en cascada, permitiendo así que los objetos del sub-menú sean seleccionados.

glutChangeToMenuEntry

void glutChangeToMenuEntry(int entry, char *name, int value);

entry

Índice de los artículos de menú en el menú actual (1 es el nivel más alto en un articulo de menú).

name

Cadena de caracteres ASCII a desplegar en la entrada del menú.

value

Valor a devolver a la función callback del menú si la entrada del menú es seleccionada.

glutChangeToMenuEntry cambia la entrada de menú especificada en el menú actual. El parámetro entry determina cual artículo del menú debe ser cambiado, con uno siendo el de más alto nivel. entry necesita estar entre 1 y glutGet(GLUT_MENU_NUM_ITEMS) inclusive. El elemento del menú a cambiar no tiene que ser ya una entrada del menú. La cadena name será desplegada para la entrada de menú cambiada nuevamente. El valor value será devuelto al callback del menú si esta entrada del menú es seleccionada.

glutChangeToSubMenu

void glutChangeToSubMenu(int entry, char *name, int menu);

entry

Índice de los artículos de menú en el menú actual (1 es el nivel más alto en un articulo de menú).

name

Cadena de caracteres ASCII a desplegar en la entrada del menú.

value

Valor a devolver a la función callback del menú si la entrada del menú es seleccionada.

glutChangeToSubMenu cambia el elemento del menú especificado en el menú actual dentro de un sub-menú activador. El parámetro entry determina cual elemento del menú debe ser cambiado, con un elemente estando en el nivel mas alto. entry necesita estar entre 1 y glutGet(GLUT_MENU_NUM_ITEMS) incluso. El elemento del menú a cambiar no tiene ya que ser un sub-menú activador. La cadena name será desplegada para el sub-menú activador cambiado nuevamente. El parámetro menú es el identificador por nombre del sub-menú colocado en cascada nuevamente.

glutRemoveMenuItem

void glutRemoveMenuItem(int entry);

entry

Índice de los artículos de menú en el menú actual (1 es el nivel más alto en un articulo de menú).

glutRemoveMenuItem elimina el elemento de la entrada del menú sin importar que sea una entrada de menu o un activador de sub-menú. entry necesita estar entre 1 y glutGet(GLUT_MENU_NUM_ITEMS) incluso. Los elementos del menú debajo del elemento del menú eliminado son renumerados.

 

glutAttachMenu, glutDetachMenu

void glutAttachMenu(int botón);
void glutDetachMenu(int botón);

botón .- el botón a adjuntar o quitar el menú.

glutAttachMenu adjunta un boton del mouse a la ventana actual, con el identificador del menú activo; glutDetachMenu quita el botón adjuntado del mouse a la ventana activa. Al adjuntar un menú identificador hacia un botón, el menú nombrado saldrá cuando el usuario presione el botón especificado. El valor botón debe ser uno de los siguientes: GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, and GLUT_RIGHT_BUTTON. Note que el menú esta adjuntado al botón mediante un identificador y no mediante una referencia.

glutDisplayFunc

void glutDisplayFunc(void (*func)(void));

func .- la nueva función de display

glutDisplayFunc dispone la función de display para la ventana actual. Cuando GLUT determina que el plano normal para la ventana necesita ser refrescada, el display callback de la ventana será llamado. Antes de la llamada, la ventana actual será dispuesta a la ventana que necesita ser refrescada y (si ninguna función de overlay display callback es registrada) la capa en uso es colocada en el plano normal. La función display callback es llamada sin ningún parámetro. Toda la región del plano normal deberá ser refrescada en respuesta a la llamada

GLUT determina cuando la función display callback deberá ser activada, basándose en el estado de refresco de la ventana. El estado de refresco para la ventana puede ser o explicitito llamando la función glutPostRedisplay o implícito como resultado de un reporte de daños de ventana, llamado por el sistema de ventanas.

glutOverlayDisplayFunc

void glutOverlayDisplayFunc(void (*func)(void));

func.- la nueva función overlay display callback.

glutDisplayFunc dispone la función overlay display callback para la ventana actual. La función overlay display callback es funconalmente la misma que display callback excepto que la función overlay display callback es usada para refrescar el overlay de la ventana.

GLUT determina cuando la función overlay display callback deberá ser activada, basándose en el estado de refresco de la ventana. El estado de refresco para la ventana puede ser o explicitito llamando la función glutPostOverlayRedisplay o implícito como resultado de un reporte de daños de ventana, llamado por el sistema de ventanas.

glutReshapeFunc

void glutReshapeFunc(void (*func)(int largo, int alto));

func.- la nueva función redimensionamiento

glutReshapeFunc dispone la función de redimensionamiento para la ventana actual. La función de redimensionamiento es activada cuando una ventana es redimensionada. Esta también es llamada inmediatamente antes de la primera función display callback dela ventana, después de que la venta es creada o en cualquier momento que un overlay para la ventana es establecido. El largo y la altura son parámetros de la función y especifican el tamaño de la nueva ventana en píxeles.

glutKeyboardFunc

void glutKeyboardFunc(void (*func)(unsigned char tecla,
                                   int x, int y));

func.- la nueva función de teclado

glutKeyboardFunc dispone la función de telado para la ventan actual. Cuando el usuario teclea en la ventana, cada tecla presionada genera un carácter ASCII el cual generará un una función de teclado. El parámetro tecla es el carácter ASCII generado. El estado de teclas modificadoras como Shift no pueden ser determinadas directamente; su único efecto será al regresar un dato ASCII los parámetros x y y indican la posición de mouse en coordenadas relativas dentro de la ventana cuando la tecla fue presionada. Cuando una nueva ventana es creada, no hay ninguna función de teclado asignada, y todos los caracteres ASCII creados en la ventana serán ignorados.

glutMouseFunc

void glutMouseFunc(void (*func)(int botón, int estado,
                                int x, int y));

func.- la nueva función del mouse

glutMouseFunc dispone la función del mouse para la ventana actual. Cuando un usuario presiona y suelta un botón del mouse dentro de la ventana, cada presionada y cada soltada generan una función del mouse. El parámetro botón es uno de los siguientes GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, or GLUT_RIGHT_BUTTON. Para sistemas con mouse de solo 2 botones, no será posible generar el estado GLUT_MIDDLE_BUTTON. Y para los sistemas con un solo botón de mouse, solo podra utilizar el parámetro GLUT_LEFT_BUTTON. El parámetro estado es GLUT_UP o GLUT_DOWN indicando que fue generado debido al presionar o soltar el botón respectivamente, los parámetros x y y indican la posición de mouse en coordenadas relativas dentro de la ventana cuando el botón del mouse fue presionado.

glutMotionFunc, glutPassiveMotionFunc

void glutMotionFunc(void (*func)(int x, int y));
void glutPassiveMotionFunc(void (*func)(int x, int y));

func.- la nueva función de movimiento o movimiento pasivo

glutMotionFunc and glutPassiveMotionFunc dispone la función de movimiento o movimiento pasivo dentro de la ventana activa. La función de movimiento es accionada cuando mouse se mueve dentro de la ventana mientras uno o mas botones son presionados. La función de movimiento pasivo es llamada cuando el mouse se mueve dentro de la ventana mientras que no hay botones presionados. Los parámetros x y y indican la posición del mouse en la ventana en coordenadas relativas.

glutVisibilityFunc

void glutVisibilityFunc(void (*func)(int estado));

func.- la nueva función de visibilidad

glutVisibilityFunc dispone la función de visibilidad dentro de la ventana actual. Esta función es llamada cuando la visibilidad en una ventana ha cambiado. El parámetro estado puede ser GLUT_NOT_VISIBLE o GLUT_VISIBLE dependiendo en la la visibilidad actual de la ventana. GLUT_VISIBLE no distingue entre una ventana totalmente visible a una parcialmente visible. GLUT_NOT_VISIBLE significa que ninguna parte de la ventana es visible. GLUT considera a una ventana visible si cualquier píxel de la ventana es visible o cualquier píxel de cualquier ventada descendiente es visible en la pantalla.

glutEntryFunc

void glutEntryFunc(void (*func)(int estado));

func.- la nueva función de entrada

glutEntryFunc dispone la función de entrada/salida del mouse para la ventana actual. El parámetro estado es uno de los siguientes: GLUT_LEFT o GLUT_ENTERED , dependiendo si el puntero del mouse se ha ido o a entrado a la ventana. Algunos sistemas no generaran correctas llamadas a funciones de entrada y salida del mouse.

glutSpecialFunc

void glutSpecialFunc(void (*func)(int tecla, int x, int y));

func .- la nueva función de entrada

glutSpecialFunc dispone la función para teclas especiales dentro de la ventana actual. Esta función es activada cuando las teclas de funciones o teclas de dirección son presionadas en el teclado. El parámetro tecla es una constante GLUT_KEY_* para la tecla especial presionada. Los parámetros x y y indican la posición de mouse en coordenadas relativas dentro de la ventana cuando la tecla fue presionada. Las teclas especiales son:

GLUT_KEY_F1

Tecla F1

GLUT_KEY_F2

Tecla F2

GLUT_KEY_F3

Tecla F3

GLUT_KEY_F4

Tecla F4

GLUT_KEY_F5

Tecla F5

GLUT_KEY_F6

Tecla F6

GLUT_KEY_F7

Tecla F7

GLUT_KEY_F8

Tecla F8

GLUT_KEY_F9

Tecla F9

GLUT_KEY_F10

Tecla F10

GLUT_KEY_F11

Tecla F11

GLUT_KEY_F12

Tecla F12.

GLUT_KEY_LEFT

Tecla de dirección izquierda

GLUT_KEY_UP

Tecla de dirección arriba

GLUT_KEY_RIGHT

Tecla de dirección derecha

GLUT_KEY_DOWN

Tecla de dirección abajo

GLUT_KEY_PAGE_UP

Tacla de avance de página.

GLUT_KEY_PAGE_DOWN

Tacla de retroceso de página

GLUT_KEY_HOME

Tecla de inicio

GLUT_KEY_END

Tecla de fin

GLUT_KEY_INSERT

Tecla de imsertar

Note que las teclas de escape, suprimir y borrar generan un código ASCII , por lo tanto no son teclas especiales

glutSpaceballMotionFunc

void glutSpaceballMotionFunc(void (*func)(int x, int y, int z));

func .- la nueva entrada para la función

glutSpaceballMotionFunc dispone la función dentro de la ventana actual para el Spaceball. Esta función es activada cuando la ventana tiene un foco de entrada del Spaceball (normalmente cuando el mouse esta dentro de la ventana) y el usuario genera una traslación del Spaceball. Los parámetros x, y y z indican la traslación en los ejes X, Y y Z respectivamente. Los parámetros se normalizan para estar dentro del rango de -1000 a 1000.

Nota: el Spaceball es un dispositivo de entrada con 6 grados de libertad

glutSpaceballRotateFunc

void glutSpaceballRotateFunc(void (*func)(int x, int y, int z));

func.- la nueva entrada para la función

glutSpaceballRotateFunc dispone la función de rotación para el Spaceball dentro de la ventana actual. Esta Función es llamada cuando el foco de entrada del Spaceball (normalmente cuando el mouse esta dentro de la ventana) y el usuario genera una rotación en el spaceball. Los parámetros x, y y z indican la rotación dentro de los ejes X, Y y Z. los parámetros son normalizados para estar dentro del rango de –1800 a 1800.

Nota: el Spaceball es un dispositivo de entrada con 6 grados de libertad

glutSpaceballButtonFunc

void glutSpaceballButtonFunc(void (*func)(int botón, int estado));

func.- la nueva entrada para la función

glutSpaceballButtonFunc dispone la función para los botones del Spaceball. Esta función es llamada cuando el foco de entrada del Spaceball (normalmente cuando el mouse esta dentro de la ventana) y el usuario presiona algún botón del Spaceball. El parámetro botón será el número del botón (empezando en uno). El número de botones disponibles puede ser determinado con glutDeviceGet(GLUT_NUM_SPACEBALL_BUTTO NS). El estado es GLUT_UP o GLUT_DOWN indicando si el botón esta siendo liberado o presionado respectivamente.

Nota: el Spaceball es un dispositivo de entrada con 6 grados de libertad

 
 
 
glutButtonBoxFunc
 
void glutButtonBoxFunc(void (*func)(int button, int state));
 
glutButtonBoxFunc coloca el callback de botón de caja de marcado y botón para la ventana actual. El callback de botón de caja de marcado y botón para una ventana es llamado cuando la ventana tiene una entrada de caja de marcado y botón (normalmente, cuando el Mouse se encuentra dentro de la ventana) y el usuario genera entradas de presión de botón de caja de marcado y botón. El parámetro de botón será el número de botón (comenzando con uno). El número de botón de marcado y botón puede ser dterminado con glutDeviceGet (GLUT_NUM_BUTTON_BOX_BUTTONS). El estado es GLUT_UP o GLUT_DOWN, lo cual indica si el callback se debió a una presión o a una falta de tal, respectivamente. Func se refiere a la función callback a ejecutarse.
 
glutDialsFunc
 
void glutDialsFunc(void (*func)(int dial, int value));
 
glutDialsFunc coloca el callback de la caja de marcado de botón y marcado para la ventana actual. El callback de la caja de marcado de botón y marcado para una ventana generalmente se efectúa cuando la ventana tiene una caja de marcado y botón con una entrada enfocada (normalmente, cuando el Mouse se encuentra dentro de la ventana) y el usuario genera cambios de caja de marcado de marcado y botón. El parámetro de marcado será el del número marcado (empezando por uno). El número de marcados de la caja de botón y marcado disponible puede ser determinado con glutDeviceGet (GLUT_NUM_DIALS). El valor mide la rotación absoluta en grados. Los valores de marcado no giran con cada rotación completa, mas continúan acumulando grados (hasta que haya un desbordamiento de int dial value). Func se refiere a la función callback a ejecutarse.
 
glutTabletMotionFunc
 
void glutTabletMotionFunc(void (*func)(int x, int y));
 
glutTabletMotionFunc coloca el callback de moción de tableta para la ventana actual. El callback para la moción de tableta para una ventana se ejecuta cuando la ventana tiene un enfoque de entrada por tableta (cuando el Mouse está dentro de la ventana) y el usuario genera la moción de tableta. Los parámetros callback de x y y indican la posición absoluta del “puck” de la tableta en la tableta. Los parámetros de callback se normalizan en el rango de 0 a 2000 inclusivos. Func se refiere a la función callback a ejecutarse.
 
glutTabletButtonFunc
 
void glutTabletButtonFunc(void (*func)(int button, int state, int x, int y));
 
glutTabletButtonFunc coloca el callback de botón de tableta para la ventana actual. El callback de botón de tableta es llamado cuando la ventana tiene un enfoque de entrada de tableta y el usuario genera entradas por presión de botón de tableta. El parámetro de botón será el número de botón (comenzando con uno). El número disponible de botones de tabletas puede ser determinado con glutDeviceGet (GLUT_NUM_TABLET_BUTTONS). El estado será GLUT_UP o GLUT_DOWN, indicando si el callback ocurre debido a una liberación o a una presión, respectivamente. Los parámetros de callback x y y indican las coordenadas relativas de la ventana cuando el botón de tableta es cambiado. Func se refiere a la función callback a ejecutarse.
 
glutMenuStatusFunc
 
void glutMenuStatusFunc(void (*func)(int status, int x, int y));               ó
void glutMenuStateFunc(void (*func)(int status));
 
glutMenuStatusFunc coloca el callback del estado del menú global para que un programa GLUT pueda determinar cuando un menú está en uso o no. Cuando el callback del estado de un menú es registrado, será llamado con el valor de GLUT_MENU_IN_USE por su parámetro de valor cuando los menús pop-up estén siendo usados por el usuario; y el callback entonces será llamado con el valor GLUT_MENU_NOT_IN_USE por su parámetro de estado cuando los menús pop-up no estén siendo usados. Los parámetros x y y indican la localización en coordenadas de ventana de la presión de botón que causó que el menú estuviera en uso o la localización donde el menú fue liberado (puede ser fuera de la ventana). El parámetro fun. Nombra la función callback. Otros callbacks continúan operando (excepto por los callbacks de movimiento del Mouse) cuando los menús pop-up están en uso para que los callback de estado de menú permitan a un programa suspender su animación u otras tareas cuando los menús están en uso. Los menús de unmapping o de cascada de un menú pop-up inicial no generan llamadas al estado de menú. Hay un solo callback de estado de menú para GLUT.
glutMenuStateFunc es una función simplificada de la anterior: esta no recibe parámetros de coordenadas x y y.
 
glutIdleFunc
 
void glutIdleFunc(void (*func)(void));
 
glutIdleFunc coloca el callback de inactividad global para ser func para que así un programa GLUT pueda realizar procesos continuos de animación cuando el los eventos de sistema de ventana no estén siendo recibidos. Si se habilita, el callback de inactividad se llama continuamente cuando no haya eventos recibidos. La rutina de callback no tiene parámetros. La ventana actual y el menú actual no serán cambiados antes del callback de inactividad. Los programas con ventanas o menús múltiples deben colocar explícitamente la ventana y/o el menú actual y no deberán confiar en su configuración actual.
 
glutTimerFunc
 
void glutTimerFunc(unsigned int msecs, void (*func)(int value), value)
 
glutTimerFunc registra la func de callback de tiempo para que sea ejecutada en al menos msecs milisegundos. El parámetro value para el callback de tiempo será el valor del parámetro value para glutTimerFunc. Callbacks múltiples de tiempo al mismo tiempo o en diferentes tiempos pueden ser registradas simultáneamente.
8.1. glutSetColor
 
void glutSetColor(int cell, GLfloat red, GLfloat green, GLfloat blue);
 
Coloca el mapa de colores del índice de color de cell para el mapa de color lógico para la ventana actual para la capa en uso con el color especificado por red, green y blue (rojo, verde y azul, cuyos rangos varían desde 0.0 hasta 1.0). La capa en uso para la ventana actual debe ser una ventana de índice de color. Cell debe ser cero o más grande y menos del número total de entradas de mapa de color para la ventana. Si el mapa de color de la capa en uso fue copiado por una referencia, una llamada a glutSetColor forzará la duplicación del mapa de colores.
 
glutGetColor
 
GLfloat glutGetColor(int cell, int component);
 
glutGetColor obtiene los components rojo, verde o azul para una entrada de mapa de colores de índice de colores dada para el color de mapa lógico de la ventana. La ventana actual debe ser una ventana de índice de color. Cell debe ser cero o mayor y menor del número de total de entradas de mapa de color para la ventana. Para índices de color válidos, el valor regresado es un valor de punto flotante entre 0.0 y 1.0. glutGetColor devolverá .0 si el índice de color especificado es un índice transparente de overlay, menos de cero o mayor o igual al valor devuelto por glutGet (GLUT_WINDOW_COLORMAP_SIZE), esto es si el índice de color es transparente o está fuera del rango de los índices de color válidos.
 
glutCopyColormap
 
void glutCopyColormap(int win);
 
glutCopyColormap copia (lentamente de ser posible, para promover el compartir archivos) el mapa de color lógico de una ventana especificada a la capa en uso de la ventana. La copia será del plano normal al plano normal; o del overlay al overlay (nunca a través de capas distintas). Una vez que el mapa de color haya sido copiado, evite colocar cells en el mapa de color con glutSetColor, ya que eso forzará una copia actual del mapa de colores si fue copiada previamente por referencia. glutCopyColormap solamente debería ser empleada cuando ambas la ventana actual y la ventana win sean ventanas de índice de color.
 
glutGet
 
int glutGet(GLenum state);
 
glutGet obtiene un estado simple de GLUT representado por enteros. El parámetro state determina qué tipo de estado regresará. El estado de capacidad de la ventana se regresa para la capa en uso. Nombres de estado de GLUT comenzando por GLUT_WINDOW_ devuelven el estado para la ventana actual. Nombres de estado de GLUT comenzando por GLUT_MENU_ devuelven el estado para el menú actual. Otros nombres de estado de GLUT devuelven un estado global. El pedir un estado para un nombre de estado inválido de GLUT devuelve un uno negativo.
 
glutLayerGet
 
int glutLayerGet(GLenum info);
 
glutLayerGet obtiene la información de la capa GLUT para la ventana actual representada por enteros. El parámetro info determina qué tipo de información de capa hay que devolver.
 
glutDeviceGet
 
int glutDeviceGet(GLenum info);
 
glutDeviceGet obtiene información de dispositivos GLUT representados por enteros. El parámetro info determina qué tipo de información de dispositivo hay que devolver. El pedir la información de dispositivo para una información de dispositivo GLUT inválida devuelve un uno negativo.
 
glutGetModifiers
 
int glutGetModifiers(void);
 
glutGetModifiers devuelve el estado de las teclas modificadoras al momento en el cual un evento de entrada para el teclado, especial o Mouse se genera. Esta rutina sólo puede ser llamada mientras se maneja el teclado, especial o el Mouse. Al sistema de ventana le es permitido interceptar teclas modificadoras definidas para el sistema de ventana o botones de Mouse, en cuyo caso, no se generará ningún callback GLUT. Esta intercepción es independiente al uso de glutGetModifiers.
 
glutExtensionSupported
 
int glutExtensionSupported(char *extension);
 
glutExtensionSupported ayuda a determinar fácilmente si una extensión de OpenGL dada está soportada o no. El parámetro extensión da nombre al query de extensión. Las extensiones soportadas tambien pueden ser determinadas con glGetString (GL_EXTENSIONS), pero glutExtensionSupported reconoce el parking correcto de la cadena devuelta.
glutExtensionSupported devuelve un no-cero si la extensión es soportada y cero si no lo es.
Debe haber una ventana actual válida para llamar a glutExtensionSupported.
glutExtensionSupported sólo devuelve información de extensiones soportadas por OpenGLO. Esto significa que los sistemas de ventana dependientes de extensiones (por ejemplo, extensiones GLX) no se reportan en glutExtensionSupported. 

glutBitmapCharacter

Renderiza un caracter usando OpenGL. Permite mostrar en la pantalla un caracter con algún tipo de fuente que se le asigne.

·                void glutBitmapCharacter(void *font, int character);

font

Tipo de Fuente para el caracter que se va a utilizar

character

Caracter a renderizar.

Las Fuentes disponibles para glutBitmapCharacter son:

  • GLUT_BITMAP_8_BY_13

-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1

  • GLUT_BITMAP_9_BY_15

-misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1

  • GLUT_BITMAP_TIMES_ROMAN_10

-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1

  • GLUT_BITMAP_TIMES_ROMAN_24
  • -adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1
  • GLUT_BITMAP_HELVETICA_10

-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1

  • GLUT_BITMAP_HELVETICA_12

-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1

  • GLUT_BITMAP_HELVETICA_18

-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1

La representación de un caracter que no existe no tiene ningún efecto.

glutBitmapWidth

Devuelve el valor del ancho de un caracter en píxeles.

·                int glutBitmapWidth(GLUTbitmapFont font, int character)

font

Tipo de Fuente para el caracter que se va a utilizar

caracter

Caracter a devolver el ancho.

Mientras que el ancho de los caracteres en una fuente puede variar, las características de la altura máxima de una fuente en particular son fijas.

glutStrokeCharacter

Renderiza un Stroke Caracter(Caracter de tipo a mano alzada)

·                void glutStrokeCharacter(void *font, int character);

font

Fuente a utilizar

character

Caracter a renderizar.

Las Fuentes disponibles para esta función son las siguientes:

GLUT_STROKE_ROMAN

Roman Simple Espaciada Proporcionadamente. El máximo alto de los caracteres en esta fuente es de 119.05 unidades.

GLUT_STROKE_MONO_ROMAN

Roman Simple monoespaciada. El máximo alto de los caracteres en esta fuente es de 119.05 unidades. Cada caracter es de 104.76 unidades de ancho.

glutStrokeWidth

Devuelve el valor de el ancho de un Stroke caracter en píxeles.

·                int glutStrokeWidth(GLUTstrokeFont font, int character)

font

Fuente a utilizar

character

Caracter a devolver el ancho.

Mientras que el ancho de los caracteres en una fuente puede variar, las características de la altura máxima de una fuente en particular son fijas.

glutSolidSphere, glutWireSphere

Renderiza una esfera sólida o de tipo de conexiones de líneas respectivamente.

·                void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);
·                void glutWireSphere(GLdouble radius, GLint slices, GLint stacks);

radius

Radio de la esfera

slices

Numero de subdivisions alrededor del eje Z(similar a líneas de longitud)

stacks

Numero de subdivisions a lo largo del eje Z(similar a líneas de latitud)

glutSolidCube, glutWireCube

Renderiza un cubo sólido (glutSolidCube) o de tipo de conexiones de líneas (glutWireCube) respectivamente.

·                void glutSolidCube(GLdouble size);
·                void glutWireCube(GLdouble size);

El cubo es centrado el origen de los coordenadas del modelado con los lados del tamaño de la longitud.

glutSolidCone, glutWireCone

Renderiza un cono sólido (glutSolidCone) o de tipo de conexiones de líneas(glutWireCone) respectivamente.

·                void glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
·                void glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
 

base

El radio de la base del cono

height

El alto del cono

slices

Número de subdivisiones alrededor del eje Z

stacks

Número de subdivisions a lo largo del eje Z

glutSolidTorus, glutWireTorus

Renderiza una dona sólida (glutSolidTorus) o de tipo de conexiones de líneas (glutWireTorus) respectivamente.

 
·                void glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius,
                                              GLint nsides, GLint rings);
·                void glutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
                                        GLint nsides, GLint rings);

innerRadius

Radio interno de la dona.

outerRadius

Radio Externo de la dona

insides

Numero de lados por cada sección radial

rings

Número de divisiones radiales para la dona

La dona es centrada el origen de los coordenadas del modelado cuyos ejes son alineados con el eje Z.

glutSolidDodecahedron, glutWireDodecahedron

Renderiza un dodecaedro(doce lados) sólido ( glutSolidDodecahedron) o de tipo de conexiones de líneas (glutWireDodecahedron) respectivamente.

·                void glutSolidDodecahedron(void);
·                void glutWireDodecahedron(void);

La imagen es centrada en el origen de las coordenadas del modelo con un radio de .

glutSolidOctahedron, glutWireOctahedron

Renderiza un octaedro(ocho lados) sólido ( glutSolidOctahedron) o de tipo de conexiones de líneas (glutWireDoOctahedron) respectivamente.

·                void glutSolidOctahedron(void);
·                void glutWireOctahedron(void);

La imagen es centrada en el origen de las coordenadas del modelo con un radio de 1.

glutSolidTetrahedron, glutWireTetrahedron

Renderiza un tetraedro(cuatro lados) sólido ( glutSolidTetrahedron) o de tipo de conexiones de líneas (glutWireTetrahedron) respectivamente.

·                void glutSolidTetrahedron(void);
·                void glutWireTetrahedron(void);

La imagen es centrada en el origen de las coordenadas del modelo con un radio de .

glutSolidIcosahedron, glutWireIcosahedron

Renderiza un icosaedro(veinte lados) sólido ( glutSolidIcosahedron) o de tipo de conexiones de líneas (glutWireDoIcosahedron) respectivamente.

·                void glutSolidIcosahedron(void);
·                void glutWireIcosahedron(void);

La imagen es centrada en el origen de las coordenadas del modelo con un radio de 1.

glutSolidTeapot, glutWireTeapot

Renderiza una figura en forma de tetera ya sea sólida (glutSolidTeapot) o de tipo de conexiones de líneas(glutWireTeapot.

 
·                void glutSolidTeapot(GLdouble size);
·                void glutWireTeapot(GLdouble size);

size

Tamaño relativo de la Tetera

Tanto las coordenadas de la superficie normal como la textura son generadas. La tetera se genera con los evaluadores de OpenGL.