martes, 9 de octubre de 2007

Previo 7.

1.¿Que es "shading" (sombreado) en términos de computación gráfica?
OpenGL nos permite elegir entre dos métodos de sombreado, de caras planas y suaves. Para elegir el método de sombreado, usaremos la función glShadeModel con parámetro GL_FLAT para caras planas, y GL_SMOOTH para el suave.
OpenGL, excepto cuando renderiza NURBS y otras funciones gráficas de alto nivel, no genera automáticamente normales, así que tenemos que especificárselas nosotros mismos.
Para especificar la normal actual, basta con hacer una llamada a la función glNormal3f(nx, ny, nz). A partir de ese momento, cualquier vértice que se renderice se supondrá que tiene como normal (nx, ny, nz)
Esta normal es deseable que esté normalizada.
Con el modo de sombreado suave activo, dependiendo de si definimos la misma normal para toda la carao para cada vértice, podemos obtener un sombreado de caras planas o de tipo gouraud. Para obtener un sombreado de tipo gouraud, bastan con definir a cada vértice la normal media de las caras a las que pertenece. Esto es especialmente interesante cuando queremos renderizar superficies curvas, mientras que para renderizar poliedros es más aconsejable asignar una única normal para todos los vértices de una misma cara.

2¿Qué es y cómo se declara y usa en OpenGL/GLUT
-Una fuente de luz?
-Un material?
-Una textura?

TEXTURAS
Cargando texturas en memoria
El proceso de cargar la textura en memoria, no es propio de OpenGL. Se tiene que realizar una función externa. Existen algunas limitaciones que la librería impone. Las dimensiones de todas las texturas que carguen tienen que ser potencias de 2, como por ejemplo 64x64, 128x64, etc.
Se tiene que tener en cuenta que si se debe 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.

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

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

Pixeles

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


MODOS DE APLICACIÓN DE TEXTURAS

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

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


3¿Cuales son los atributos/características que se pueden declarar en OpenGL/GLUT para manejo de:
-Luces
-Materiales
-Texturas
y con que funciones se hace esto?


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_DIFFUSE Y GL_SPECULAR sólo se usan con la primera fuente de luz.
GL_AMBIENT: Define los valores de la luz ambiental. Valor RGBA, su valor por defecto es 0.0,0.0,0.0,1.0)
GL_DIFFUSE: Define los valores de la luz difusa. Valor RGBA. su valor por defecto es (1.0,1.0,1.0,1.0)
GL_SPECULAR: Define los valores de la luz especular. Valor RGBA. Su valor por defecto es (1.0,1.0,1.0,1.0)
GL_POSITION: Posición de la luz, en coordenadas { x, y, z, w }, su valor por defecto es (0.0,0.0,1.0,0.0)
GL_SPOT_DIRECTION: Vector de dirección de la luz, en coordenadas { x, y, z }, su valor por defecto es (0.0,0.0,-1.0)
GL_SPOT_EXPONENT: Representa la concentración de la intensidad de la luz. Valor escalar, por defecto 0.
GL_SPOT_CUTOFF: Ángulo del cono de luz. Valor escalar, por defecto 180.
GL_CONSTANT_ATTENUATION: Atenuación constante a aplicar a la luz según la distancia. Valor escalar, por defecto 1
GL_LINEAR_ATTENUATION: Atenuación lineal a aplicar a la luz según la distancia. Valor escalar, por defecto 0
GL_QUADRATIC_ATTENUATION: Atenuación cuadrática a aplicar a la luz según la distancia. Valor escalar, por defecto 0

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);

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).