graficaciÓn unidad iv › ~hilario_sm › slide › graficacion › ...las texturas 1d y 2d que...

216
GRAFICACI GRAFICACI Ó Ó N N Unidad IV Unidad IV Profr Profr . Hilario Salazar Mart . Hilario Salazar Mart í í nez nez OBJETIVO ESPECIFICO: El alumno aprenderá los conceptos básicos de sombreado, textura e iluminación

Upload: others

Post on 07-Jul-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

GRAFICACIGRAFICACIÓÓNNUnidad IVUnidad IV

ProfrProfr. Hilario Salazar Mart. Hilario Salazar Martííneznez

OBJETIVO ESPECIFICO:El alumno aprenderá los conceptos básicos de sombreado, textura e iluminación

• Sombreado• Textura• Iluminación• Transparencia

Creación de un objeto con textura en 3D

Acceso directo a Acceso directo a SphereWorldSphereWorld

Mapeado de objetos lineales

Acceso directo a Acceso directo a TexGenTexGen

4 Tipos de texturas4.1 Textura 1DUna textura 1D es una imagen con anchura pero sin altura, o viceversa; las texturas 1D tienenun solo píxel de alto o ancho. Podríamos pensar que las texturas 1D no son muy útiles, pero de hechopueden sustituir a técnicas de sombreado más convencionales y acelerar el proceso de generación. LaFigura 4 muestra una textura “RNA-V-AIV” (Rojo, Naranja, Amarillo, Verde, Azul, Indigo, Violeta)que genera el arco iris. La imagen de textura es una línea de pixeles (valores de color) que cubren elespectro de color visto en el arco iris. La escena equivalente sin texturas podría contener siete veces elnúmero de polígonos de la que sí que tiene texturas y requerir mucho más tiempo de generación.

4.2 Textura 2DUna textura 2D es una imagen con más de un píxel de alto

o ancho y se abre generalmente conun fichero .BMP (o .JPG). Las texturas bidimensionales se

usan comúnmente para reemplazarcomplejas geometrías de superficie (muchos polígonos) en

edificios, árboles y demás. Estas texturas2D también pueden usarse para añadir detalles realistas al

fondo, como las nubes del cielo en la Figura 5.

Las texturas 1D y 2D que hemos visto hasta ahora se componen de valores de color RGB. Lastexturas también pueden estar compuestas de índices de color o niveles de luminiscencia (grises), ypueden incluir valores alfa (transparencia). Lo último resulta útil para definir objetos naturales comoárboles, porque el valor alfa se puede emplear para hacer visible el árbol dejando que el fondo se vea através suyo.Naturalmente, como ya vimos, deberemos de definir una imagen para la textura antes de quepodamos dibujar polígonos texturados en OpenGL. Las texturas siguen las mismas reglas dealmacenamiento que los mapas de bits.

4.3 Textura 3DAlgún hardware también soporta texturas 3D (con volumen) en OpenGL. Las texturas convolumen se usan para ver CAT, MRI y otras “exploraciones” 3D. Por desgracia, incluso una textura de256x256x256 niveles de grises necesita casi 16 Mbytes de memoria. Durante años han sido unaextensión de OpenGL hasta la especificación 1.2 de OpenGL que ya se permite trabajar con texturas3D.Las texturas 3D además de cubrir un espacio horizontal o plano, también tienen unaprofundidad. Por ejemplo, un muro puede tener varias capas. La primera unos dibujos pintados en lapared, luego otra con escayola, después otra con la cara exterior de los ladrillos... Las texturas 3Dtienen por tanto grandes posibilidades, por ejemplo, en la Figura 6 se muestra una cabeza con textura 3D. Su utilización puede ser perfecta tanto para los juegos, como para la educación, como para lamedicina.

Definición de texturas 1D

..

Acceso directo a Acceso directo a TunnelTunnel

EFECTOS VISUALESEFECTOS VISUALES

MEZCLAS, NIEBLAS Y MEZCLAS, NIEBLAS Y ANTIESCALONADOANTIESCALONADO

Introducción

Hasta ahora en los capítulos anteriores hemos visto cómo realizarobjetos, transformarlos, colorearlos, jugar con las luces, produciranimaciones, sombras... pero ¿no es todo esto demasiado limpio? Las escenas producidas parecen demasiado perfectas, los objetosdemasiado nítidos. Con las luces y las sombras realizamos la ambientación de la escena, pero no podemos crear efectos de transparencias, nieblas,... nuestros objetos son sólidos y de tan perfectos, irreales.

¿Quien se imagina la escena de una mesa con copas de cristal que seantotalmente opacas, o la visión de un bosque en la que se diferencien tan bien los pinos cercanos como los abetos mas lejanos?

A alguien se le podría ocurrir la idea de mapear o texturizar todos losobjetos con texturas ligeramente sucias, con ciertas irregularidades paradar un mayor realismos. Así, lograríamos que las superficies de losobjetos, y mediante estos, los objetos en si, no fueran tan perfectos, peroaún seguiríamos sin lograr un mayor realismo. Bien, pues esto se soluciona mediante la inclusión de efectos visuales dentro de nuestraescena.

Los efectos visuales que se trataran en este capitulo son las mezclas, el antiescalonado y el uso de las nieblas. Estos efectos son la base para darun mayor realismo a nuestras escenas, aunque si deseáramos unosefectos mucho más notorios tendríamos que utilizarlos junto a sistemas de partículas y cosas parecidas y de orden superior, para así, poder simularpor ejemplo nubes. Pero como esto se sale ya fuera de orden nosceñiremos a las primitivas que incorpora OpenGL. El objetivo es explicarlos conceptos del uso de las mezclas, nieblas y el antiescalonado para darun mayor realismo a nuestras escenas realizadas, para darlas un toque final.

Mediante el Blending o mezclas podemos realizar efectos desdetransparencias y fundidos de objetos que se superponen en la escena, a crear el efecto de un lápiz que pasara sobre una hoja de papel. Todoesto controlando "simplemente" cual el es método para aplicar al color de origen sobre un color destino.

Gracias al antiescalonado podremos suavizar los puntos que aparecenen la escena cuando por ejemplo, queremos representar una líneaoblícua y nos encontramos con una serie de puntos desmadejados quese sitúan por donde se supone que iría la línea, y todo esto debido a que"gracias" a la resolución de la pantalla podemos percibir como la líneaoblícua no encaja a la perfección con los píxeles reales de la pantalla.

Con el uso de nieblas podemos dar el efecto de profundidad a unaescena en la que tengamos perspectiva para mejorarla, simular que nosencontramos ante un montón de nubes cruzando el cielo, o emular el efecto de una sala de fumadores.

Mezclas - Blending

¿Que ocurre cuando hace sol y nos ponemos unas gafas de sol de color verde? Pues bien, lo que vemos tendrá su color original, modificado porlos efectos de las luces y, lo más importante tendrán también parte del color verde de nuestras gafas de sol. Esto es debido a que aunquenuestras gafas sean transparentes, modifican las tonalidades de loscolores que estamos viendo. Si nuestras gafas fueran totalmentetransparentes esto no ocurriría pero al tener una tonalidad, esta se traslada a los objetos que se encuentras ante nosotros. La complicaciónaparece en cuánto verde tomarán los objetos que estemos viendo (gradode transparencia de las gafas), y si a su vez estos objetos se encuentrasafectados por otros efectos similares como el color del cristal de un escaparate...

Aplicar mezclas

A la hora de especificar el color podemos hacerlo para el modo RGB (glColor3f) o para el modo RGBA (glColor4f). Al definir el color mediante la función glColor4f() si no nos preocupamos por el significadodel último valor, alfa, nuestros objetos son sólidos si el valor de alfa lo mantenemos a 1.0, mientras el resto RGB es lo que nos permite decidir el color de los objetos. Pues bien, esta componente, cuando tenemos el efecto blending activo, se combina con el valor del color almacenado en el frame buffer para generar el nuevo color. Para verlo de una forma másclara podemos pensar en la componenete alfa como en el grado de "opacidad" y las demás, RGB, el color en sí. Siendo glColor4f(R,G,B,1.0f) color completamente opaco y glColor4f(R,G,B,0.0f) completamentetransparente.

En la practica se usa el valor alfa (valor de material difuso) del códigoRGBA, y permite combinar el color del fragmento que se procesa con el del píxel que ya está en el buffer. Por ejemplo al dibujar una ventanatransparente de color azul claro enfrente de una caja roja. El Alpha blending permite simular la transparencia de la ventana, de manera quela caja vista a través del cristal aparezca con un tono magenta.

Lo que se realiza es la aplicación según el tipo de mezcla sobre la información ya contenida en el buffer RGBA y el color actual con el queestamos trabajando para poner cada píxel en función del valor de alfa. Para entendernos: sobre el contenido del buffer de color actual aplicamosel color de cada punto en proporción al valor de alfa de ese punto del objeto que queremos dibujar y este pasa a ser el nuevo punto de color actual. Según las características que hayamos dado a la mezclapodremos producir efectos de adición, sustracción, saturación, ....

Las operaciones de mezcla no pueden emplearse en el modo indexadode color y están desactivadas en las ventanas de color indexado, lasmezclas pueden conllevar ligerísimos cambios de color que en modoindexado no serían apreciados o peor aún, nos saldríamos del efectodeseado por lo cual están desactivadas en color indexado.

Para poder utilizar este efecto en nuestro programa, lo primero quedebemos de hacer es activarlas. Activar las mezclas en ventanas RGBA es muy fácil, tan solo tendremos que invocar las siguientes primitivasque nos permitirán la activación o desactivación de los efectos de mezclas:

glEnabled(GL_BLEND) Habilita el uso de mezclas

glDisabled(GL_BLEND) Deshabilita las mezclas

Luego tendremos que indicar cómo se debe comportar la mezcla, esto es, cómo son combinados los componentesdel píxel origen con los del píxel destino, según la funciónque nosotros especifiquemos.

Para ello tendremos que seleccionar qué tipo de funciónvamos a usar para mezclar los colores de origen y de destino de la mezcla, mediante la función glBlendFuncque constará de los dos parámetros correspondientes al origen de la mezcla y al destino de esta.

Factores fuente y destino de la mezcla

La realización del proceso de mezcla tiene dos partes:

•Primero la extracción de cada uno de los cuatripletesque componen cada color del píxel o fragmento queestamos tratando como origen y como destino.

•Posteriormente se realiza la aplicación matemáticade correspondencia de los factores del origen al destino; para entendernos, cómo afecta el origen de la mezcla al destino de la mezcla.

La especificación de la función de mezcla del origen al destinose realiza con:

void glBlendFunc (GLenum origen, GLenum destino);

Controla qué valores de color del fuente son combinados con los que estánalmacenados en el frame buffer (destino). El argumento origen indica cómousar el factor blending del fuente y el argumento destino nos indica lo mismopero para el destino.

NOTA:El factor de blending se supone comprendido entre [0..1]

Los posibles argumentos son los siguientes:

(1,1,1,1)-(As,As,As,As)El color de origen se multiplica por (1, valor alfa de origen).

GL_ONE_MINUS_SRC_ALPHA

(As,As,As,As)El color de origen se multiplica por el valor alfa de de origen.

GL_SRC_ALPHA

(1,1,1,1)-(Rd,Gd,Bd,Ad)El color de origen se multiplica por (1,1,1,1; color de destino).

GL_ONE_MINUS_DST_COLOR

(Rd,Gd,Bd,Ad)El color de origen se multiplica por el color del píxel de destino.

GL_DST_COLOR

(1,1,1,1)GL_ONE

(0,0,0,0)GL_ZERO

Factor blendingConstante

(f,f,f,1); f=min(As,1-Ad)El color de origen se multiplica por el mínimo de los valores alfa de origen y (1, valor de destino).No admitida por Microsoft OpengGL

GL_SRC_ALPHA_SATURATE

(1,1,1,1)-(Ad,Ad,Ad,Ad)El color de origen se multiplica por (1, valor alfa de destino).No admitida por Microsoft OpengGL

GL_ONE_MINUS_DST_ALPHA

(Ad,Ad,Ad,Ad)El color de origen se multiplica por el valor alfa de destino. No admitida por Microsoft OpengGL

GL_DST_ALPHA

Factores de origen de mezclas

(1,1,1,1)-(As,As,As,As)El color de destino se multiplica por (1, valor alfa de origen).

GL_ONE_MINUS_SRC_ALPHA

(As,As,As,As)El color de destino se multiplica por el valor alfa de de origen.

GL_SRC_ALPHA

(1,1,1,1)-(Rs,Gs,Bs,As)El color de destino se multiplica por (1,1,1,1; color de origen).

GL_ONE_MINUS_SRC_COLOR

(1,1,1,1)GL_ONE

(0,0,0,0)GL_ZERO

Factor blendingConstante

(1,1,1,1)-(Ad,Ad,Ad,Ad)El color de destino se multiplica por (1, valor alfa de destino).

No admitida por Microsoft OpengGL

GL_ONE_MINUS_DST_ALPHA

(Ad,Ad,Ad,Ad)El color de destino se multiplica por el valor alfa de destino.

No admitida por Microsoft OpengGL

GL_DST_ALPHA

Factores de destino de mezclas

Dos ejemplos:

1) glBlendFunc(GL_ONE, GL_ZERO);2) glBlendFunc(GL_SRC_ALPHA, GL_ONE);

En el primer caso se está dando una importancia de 1 (máxima) al canal alfa de la fuente y de 0 (nula) al canal alfa del destino. Eso equivale a decir que el color final se compone de un 100% del de la fuente y de un 0% del color destino porlo cual el pixel acaba siendo del color de la fuente. Estos son los valores pordefecto para esta función, que es igual que inhabilitar el uso de mezclasmediante la primitiva glDisable(GL_BLEND).

En el segundo caso se le dice a OpenGL que multiplique a la fuente por suvalor de alfa y sume el resultado al color destino. En este caso y asumiendo un valor de alfa igual a 0.75 para la fuente, se puede decir que:

Color Resultante = (Color de la fuente x 0.75) + Color del Destino

O sea un color que tiene un 75% del color fuente y un 100% del color destino.

Uso de las mezclasNo todas las combinaciones de fuentes y destino son utilizables. En la mayoría de ocasiones se utilizan un numerorestringido de combinaciones. A esto hay que añadir que la implementación de OpenGL Microsoft no soporta planos de color alfa.

-Trasparencias: La transpariencia es quizás el uso más típicode las mezclas, empleada a menudo en ventanas, botellas y otros objetos 3D a través de los cuales podemos ver. Esta esla función de mezcla para estas aplicaciones:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Esta combinación toma el color de origen y lo escalabasándose en la componente alfa, para sumarle luego el color de destino escalado en 1 menos el valor alfa. Dicho de otra manera, el color del punto será una proporción del color actual del punto y el punto que estemossobreponiendo. Esta proporción será precisamente el valor de alfa. La componente alfa del color puede valer de 0 (totalmente transparente) a 1 (totalmente opaco), comosigue:

Rd = Rs * As + Rd * (1 - As)Gd = Gs * As + Gd * (1 - As)Bd = Bs * As + Bd * (1 - As)

Imagen sacada del ejemplo Ej3.C, de la sección de Ejemplos.

La escena está formada por tres esferas transparentes y un cubo sólido detrás de ellas. Las esferas tienen distinto grado de transparencia siendo la azul la menos transparente.

Imágenes sacadas del ejemplo Ej1.C, de la sección de Ejemplos.

Cubo antes de aplicar el Blending Cubo después de aplicar el Blendingen todas sus caras.

-Antiescalonado: Podremos hacer que nuestro sistema tengaantiescalonado como si lo tuviéramos por hardware mediante el uso de mezclas y las primitivas de suavizado comoGL_LINE_SMOOTH.

La escena que tiene puntos, líneas y polígonos con antiescalonado puede mejorarse usando las dos mismasdirectivas que con la transpariencia GL_SRC_ALPHA y GL_ONE_MINUS_ALPHA. En sistemas que tenganantiescalonado asistido por hardware y mezclas, la mezclaproducirá un resultado similar a la de las escenas con antiescalonado a pantalla completa generadas con el buffer de acumulación. Al mismo tiempo, la mezcla es varias vecesmás rápida que la acumulación dado que sólo hay quedibujar la escena una vez.

Para dibujar una escena usando las primitivas de antiescalonado, debemos llamar a las siguientes funciones:

glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glEnable(GL_LINE_SMOOTH);glEnable(GL_POINT_SMOOTH);glEnable(GL_POLYGON_SMOOTH);

El antiescalonado se tratará en la siguiente sección.

-Ocultar: Si con los mismos factores de mezcla de una trasparencianormal ponemos un valor de alfa 0 en el color de algún objeto, haremosque dicho objeto desaparezca de la escena.

-Componer: Si deseamos hacer el efecto de que un objeto se componea partir de varias partes lo conseguiremos poniendo un valor de alfaigual a 1/(nº partes) y los factores de la mezcla en origen seránGL_SRC_ALPHA y en destino GL_ONE.

-Filtros de color: Si queremos hacer un filtrado fotográfico de coloresbastará con utilizar los factores GL_DST_COLOR o GL_ONE_MINUS_DST_COLOR en el origen y GL_SRC_COLOR o GL_ONE_MINUS_SRC_COLOR en el destino para potenciar omultiplicar las componentes RGB que tengamos.

-Simular pinceles: Supongamos que queremos hacer un programa de dibujoque conste de varias brochas suaves. Para ello haremos que el valor de alfa sea el indicador del calado de la brocha y los colores RGB estén vacíos. La forma del pincel podríamos realizarla mediante una textura, y finalmente, lo importante, en lugar de utilizar GL_SRC_ALPHA para el origen que utilizábamos cuandoqueríamos hacer transparencias, lo que utilizaremos será GL_SCR_COLOR queen lugar del valor de alfa, utiliza el valor de color actual, en nuestro caso sería el color que hayamos dado a la textura del pincel. Luego habrá que tener cuidadode no perder el dibujo, mandando el resultado a un buffer de memoria parapoder volcarlo a disco o recuperarlo si se realiza un repintado de la pantalla.

-Billboarding: ¿Quién no ha visto un juego con arbolitos de fondo?. Podemoslograr que imágenes raster tengan un aspecto ligeramente tridimensional y de profundidad si aplicamos los efectos de transparencias parciales sobre las partesque componen la imagen. Este efecto mejora más aún si realizamos variascapas de la misma imagen.

Por ejemplo, se puede dibujar un polígono que contenga la forma de un árbol y después aplicar la textura del árbol. En las partes del polígono queno están cubiertas por la textura del árbol se aplica transparencia con valor alfa 0 (transparencia total ) y donde está la textura del árbolrecubriendo el polígono se aplica un alfa igual a 1, es decir opacidad total. Así pues al mirar a través del polígono se ve la forma del árbol, estemétodo es mucho más rápido que dibujar mediante triángulos la complejasilueta del árbol.

Una última mejora de la técina billboarding o "valla publicitaria" es hacerque el polígono siempre esté encarado hacia el observador, cuando se usa un solo polígono. Con esto se consigue que nunca se descubra el "truco" porque el usuario nunca verá el polígono de perfil.

- O de otra manera: (también usando el buffer de profundidad) Activamosel Z-Buffer pero cuando estemos dibujando los polígonos transparenteslo ponemos como solo lectura. De esta manera cuando se compare un polígono transparente con uno opaco, si el primero está delante se dibujará pero no borrará al anterior porque para eso hemos deshabilitadola escritura, y si está detras pues simplemente no se dibuja. Para estopodemos hacer uso del comando glDepthMask():

void glDepthMask (GLboolean flag);

Activa o desactiva la escritura en el buffer de profundidad (Z-Buffer). Siflag es GL_FALSE (0), el Z-Buffer está en modo solo lectura. Si flag esGL_TRUE (1) se activa la escritura en el Z-Buffer.

NOTA: El comando glDepthMask funciona en todas las tarjetas. Por esoquizás es mejor la segunda opción.

Imágenes sacadas del ejemplo Ej2.C, de la sección de Ejemplos. Aquí sólo se aplica la transparencia a una cara del cubo por lo que hay que tener cuidadocon la profundidad de las caras opacas y de las transparentes:

Además de la profundidad entre los objetos también tendremos que tener en cuenta que los objetos 3D trasparentes tienen cuatro capas no solo tenemos la parte delantera antes de la trasera sino que además tenemos las capasocultas es estas capas, así tenemos que por orden de profundidad las capasdeberían representarse para un objeto:1. Capa delantera visible. El primer plano.2. Capa delantera parte posterior. En el interior.3. Capa trasera parte anterior. En el interior.4. Capa trasera parte posterior.

Existen tarjetas de video con capacidad para almacenas variosZ-Buffers de tal manera que el resultado final quede con unamayor grado de realismo.La habilitación / deshabilitación del dibujado de las capasocultas se emplea mediante la directiva GL_CULL_FACE y lasfunciones glEnable / glDisable().

Si queremos no tener problemas de profundidad y mezclas esconveniente:

•Pintar primero los objetos sólidos•Pintar de atrás hacia delante

Como esto no siempre se puede hacer, por lo menos tener el cuidado de haber activado la comprobación de profundidad.

Ejemplo 1

Algunas capturas del ejemplo 1

En este primer ejemplo (Ej1.zip) se cargará un cubo. Podremos moverlo con los cursores y con las teclas +/- acercarnos o alejarnos de él. La característica principal es la posibilidadde aplicar el efecto de transparencia al objeto que hemos cargado. Para ello hay que pulsar la tecla B y para desactivarlo volver a pulsarla. También se puede aumentar el valor de alfacon la tecla N y disminurlo con la tecla M, siempre dentro de los límites [0,1]. Esto harávariar el grado de opacidad del cubo. También se pueden alterar los valores RGB de la función glColor4f. Las teclas V y F alteran el valor del rojo (auméntadolo o disminuyéndoloen 0.05f por cada pulsación). Las teclas C y D se encargan del verde y por último las teclasX y S modifican el azul.

Dentro del código cabe resaltar:En el archivo PRINCIPAL. En la función Inicializa() se especifica qué función de blending va a ser usada, así como se establece el color actual del objeto. La función quedaría:

bool Inicializa() {// ... Aspectos relativos a la creación de la

ventana// Función de blending basada en el alpha de la

imagen de origenglBlendFunc(GL_SRC_ALPHA,GL_ONE); glColor4f(1.0f,1.0f,1.0f,0.5f);

}

Con estas líneas lo que se hace es especificar que la transparencia se basará en el valor alfa de la imagen de origen, a la vez se especifica el color actual como brillo total (RGB=111) y 50% de opacidad (Alfa=0.5).

Ahora vamos a controlar la entrada por teclado para ver cuándo se ha pulsado una tecla y según sea el caso, activaremos o desactivaremos el efecto blending, modificaremos el valor de alfa o el color. Para ellomodificaremos la función Control_Entrada quedando:void Control_Entrada(){

if (bTeclas[VK_LEFT]) fRoty-=0.5f; if (bTeclas[VK_RIGHT]) fRoty+=0.5f;

/* A partir de aqui hasta el final de la funciónrelacionado con las mezclas - blending */

if (bTeclas['B']&& !bBPulsada) {

bBPulsada=true; bBlend=!bBlend; if (bBlend) {

glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST);

} else {

glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST);

} }

/* Aumento alpha */ if (bTeclas['N']){

if(alpha_blend<=1){

alpha_blend = alpha_blend + 0.005f;

glColor4f(micolor1,micolor2,micolor3,alpha_blend);}

} /* Cambio colores */ if (bTeclas['V']) {

if(alpha_blend<=1){

if(micolor1<=1){

micolor1 = micolor1 + 0.05f;}

glColor4f(micolor1,micolor2,micolor3,alpha_blend);}

}

Ejemplo 2

Algunas capturas del ejemplo 2

En este segundo ejemplo (Ej2.zip) se cargará un cubo como el del ejemplo anterior, peroahora sólo una de las caras del cubo tendrá aplicado el efecto de transparencia mediantemezclas, el resto de las caras serán sólidas, por lo tanto ahora hay que tener en cuenta la profundidad de los puntos del cubo para que el resultado sea el deseado. El cubo puede rotarse con los cursores y con las teclas +/- acercarnos o alejarnos a él.

En este ejemplo, vamos a cargar nuestro formato del cubo desde un fichero donde se indicasi una cara va a usar blending o no. Esto se realiza mediante un campo, así, si este campo es igual a 0 no usará y si es igual a 1 sí usará el efecto de transparencia.

Modificaciones en el archivo PRINCIPAL.CPP

Dentro del módulo principal incluiremos las dos siguientes líneas, al igual que en el ejemplo anterior, dentro de la función Inicializa():

glBlendFunc(GL_SRC_ALPHA,GL_ONE); glColor4f(1.0f,1.0f,1.0f,0.5f);

A continuación debemos modificar la función Renderiza() para que controle cuándo se debe activar el efecto

int Renderiza(GLvoid){// Comprobamos si el triángulo actual tiene asignada la característica Blending

if (Objeto3D->m_cTriangulos[j].m_bBlend) {

glEnable(GL_BLEND); } else{

glDisable(GL_BLEND); }

Ejecutar ejemplo

Ejemplo 3En este tercer ejemplo (Ej3.zip) se cargará una escena formada por tres esferastransparentes, con diferentes grados de transparencia y detrás de ellas un cuboopaco. Inicialmente el cubo está detrás de las esferas, pero puede ponersedelante de las mismas mediante las flechas arriba y abajo. Inicialmente tambiénno está habilitado el condicionamiento por profundidad por lo que al mover el cubo delante de las esferas se obtienen resultados incorrectos.

En la siguiente captura el cubo opaco está situado delante de las esferastransparentes y éste es el resultado, debido a que no está habilitado el condicionamiento por profundidad :

Ahora para ver la diferencia se habilita el condicionamientopor profundidad pulsando la barra espaciadora y éste esresultado correcto:

Esto se hace en la función mejorar del archivo Ej3.c

//Habilitación de las mejoras

void CALLBACKmejorar(void){

if (enableMejoras){

glEnable(GL_DEPTH_TEST);glShadeModel(GL_SMOOTH);glEnable(GL_CULL_FACE);

}else{

glDisable(GL_DEPTH_TEST);glShadeModel(GL_FLAT);glDisable(GL_CULL_FACE);

}enableMejoras=!enableMejoras;

}

Esta función es llamadacuando se pulsa la barraespaciadora. Est funciónalterna entre la habilitación y la deshabilitación de GL_DEPTH_TEST entreotras mejoras.

Ejecutar ejemplo

Ejemplo 4En este cuarto ejemplo (Ej4.zip) se usan las bibliotecas GLUT. Esteejemplo consta de una escena formada por dos icosaedros, uno rojo y otroverde, que rotan sobre sí mismos. El valor alfa de transaparencia de losdos icosaedros varía sinuosidalmente y un poco fuera de fase entreambos.

Ejecutar ejemplo

Antiescalonado - Antialiasing

El escalonamiento o aliasing es el efecto producido en las pantallas de ordenador y otros dispositivos de imagen basados en píxels donde laslíneas diagonales y curvadas muestran una serie de pequeños zig-zags o dientes de sierra formados por líneas o puntos horizontales y verticales.

Esto es debido a que al ser la pantalla de una determinada resolución, sise quiere mostrar una línea oblícua o curvada, habrá puntos que seaniluminados y otros que no. También nos podemos encontrar líneas con pendiente distinta, aunque aproximada, que debido al escalonamientoactiven los mismos punto y parezcan iguales. Este efecto reduce la calidad de una imagen ya sea en dos o tres dimensiones.

Esquema de dos rectas que aúnteniendo distinto ángulo tienen unarepresentación similar debido a la discretización de los puntos que deben activarse.

El antiescalonado o antialiasinges el nombre de las técnicas queintentan reducir o eliminar esteefecto anteriormente descritosombreando los píxels en losbordes de los elementos gráficos.

Para paliar esto mediante el efecto antialiasing los píxels del borde se dibujan en diferentes tonalidades cercanas al color del objeto original, se consigue así engañar al ojo y hacerle creer que la línea es más recta y suave.

El ordenador ilumina los píxels de la pantalla que considera que pertenecen a la figura. Entonces la pendiente oblícua se transforma en una especie de escalera o dientes de sierra, aparece el efecto aliasing.

Para ver cómo funciona el antialiasing, se pretende dibujar una figura con una pendiente diagonal sobre una matriz de píxels, como muestra la figura de forma ideal.

El color añade una nueva problemática al antiescalonado. Si el color no estuviera involucrado el problema sería mucho más simple de solucionar, sólo con una escala de grises formada por 16 tipos de grises se podríanconseguir notables incrementos en imágenes en blanco y negro. Los esquemas de color deben manejar un rango de tonalidades más ampliodonde además del objeto con aliasing interviene el fondo de la imagen.

La palabra "Some" en azul tiene el efecto antialiasing activo, mientras que la palabra "text" lo tiene desactivado.

Se puede ver a simple vista cómo en los bordes de la segunda palabra aparecen ciertas irregularidades. Mientras que la primera palabra tiene un aspecto más suave.

En esta ampliación de la imagen anterior se puede ver cómo actúa el antiescalonado. Los bordes del texto azul están compuestos por píxels de diferentes tonalidades de azul.

Mientras que en el texto morado esto no ocurre, pudiéndose ver perfectamente los dientes de sierra sobre todo en la letra equis.

Al dibujar cualquier línea en la pantalla la manera de calcular si un punto debe o no encenderse depende del valor de cobertura quetenga dicho punto. El valor de cobertura indica cuánto de ese punto estácubierto por la línea. Normalmente si es cubierto un 50% o más el puntose activará.

El método de cálculo del índice de cobertura depende de la implementación de OpenGL que usemos.

Uso del antiescalonado en puntos y líneas

Si deseamos utilizar el antiescalonado deberemos habilitarlomediante la primitiva correspondiente:

glEnable(GL_POINT_SMOOTH) // Para puntos

glEnable(GL_LINE_SMOOTH) // Para líneas

También podremos indicar la orientación del método de cálculodel antiescalonado con la función glHint(), siempre y cuandonos lo permita la implementación de OpenGL.

GL_FASTEST Forma rápidaGL_NICEST Alta calidadGL_DONT_CARE Da igual el método empleado

Hay que tener en cuenta que el paso de GL_FASTEST a GL_NICEST puedeconllevar un aumento demasiado elevado del tiempo de cálculo, como paraser factible su utilización.

Los objetivos de la función glHint() pueden ser:

GL_POINT_SMOOTH_HINTGL_LINE_SMOOTH_HINTGL_POLYGON_SMOOTH_HINT

Especifica la calidad del dibujado en líneas y polígonos.

GL_FOG_HINT Especifica si el cálculo de las nieblas se realizaran porpíxel o por vértice.

GL_PERPECTIVE_CORRECTION_HINTEspecifica la calidad del cálculo interpolado de lascoordenadas en perspectiva y texturas.

glHint (GLenum Objetivo, GLenum metodo);

El tipo de método puede ser:

Salidas del Ej3 de la sección de ejemplos:

El ejemplo está formado por dos esferas renderizadas, la esfera azul tiene el antialiasing de líneas activado y la amarilla no.Se puede observar cómo la esfera azul presenta unas líneas más suavizadasque la amarilla.

Antiescalonado en modo RGBA

El antiescalonado en RGBA depende se consigue con lasmezclas GL_BLEND. Normalmente el método de mezclaserá al igual que en las trasparencias, GL_SCR_ALPHA para el origen y GL_ONE_MINUS_ALPHA para el destino.

Habrá que tener también cuidado con el control de la profundidad mediante la activación del control de la profundidad GL_DEPTH_TEST

Antiescalonado en color indexado

Al no estar habilitadas, en el modo de color indexado, lasmezclas tendremos que construir rampas de color paraproducir el ligero degradado que corresponde al antiescalonado. Normalmente se suele realizar en tonos de grises, pero es posible cualquier otro color si tenemos cuidadode hacer la rampa de color del color de la figura degradadohacia el fondo.

Rampa de color negro

En el ejemplo Ej4 podemos encontrar el modo de realizar la rampa de color para el antiescalonado:

Antiescalonado en modo indexado.

Podemos ver un toroide con antiescalonado.

Antiescalonado en polígonos

Lo tendremos que realizar al igual que el líneas y puntos con la salvedad de que tenemos que realizar correcciones puestoque los lados de los polígonos pueden quedarsuperpuestos y necesitaremos controlar la saturaciónresultante de la sobreexposición de las aristas.

Ejemplo 1Algunos de los ejemplos de esta sección utilizarán las biblioteclas GLUT.

En este primer ejemplo (Ej1.zip) se muestran dos líneas de texto, unacon antialiasing y otra no. Las líneas están escritas con un ángulo de 25 grados para observar mejor el efecto

Dentro del código cabe resaltar:

En el archivo Ej1.c

En la función display() se escribe la primera línea de texto con GL_LINE_SMOOTH activo, mientras para la segunda se desactiva el antiescalonado de línea:

/* Rotar el texto para mostrar mejor los dientes de sierra. */glRotatef(25, 0.0, 0.0, 1.0);output(250, 425, "Texto con antiescalonado."); /* Al escribir este texto el antialiasing ya está activo */

glDisable(GL_LINE_SMOOTH); /* Ahora se desactiva el antialising para la segunda línea */

glDisable(GL_BLEND);output(200, 250, "Texto sin antiescalonado.");

Ejemplo 2

En este segundo ejemplo (Ej2.zip) se cargará un dodecaedro que inicialmente tiene el efectoantialiasing inactivo. El dodecaedro puede manejarse con las teclas:

'a' o 'A' : Para activar/desactivar el antiescalonado de línea y punto.

'l' : Para hacer que las líneas que forman la figura sean más gruesas, hasta un cierto límitedespués del cuál se vuelve a empezar.

'x' , 'y' y 'z' : Para centrar la figura respecto a uno de los ejes X, Y o Z.'e' o 'E': Para finalizar la ejecución.los cursores: Para rotar la figura.avance página, retroceder página : Para acercar o alejar la figura.inicio: Para centrar la figura en su posición original.fin: Para finalizar la ejecución.

Explicaciones de interés en el archivo Ej2.c

En la función void keyboard(unsigned char key, int x, int y ) se manejan las pulsaciones del teclado y es aquí donde se activa/desactiva el efecto antialiasing al pulsar 'a' o 'A'.

case 'a': case 'A':antialiasFlag = ! antialiasFlag;

if (antialiasFlag == GL_TRUE) { glEnable ( GL_POINT_SMOOTH ); /* Antialiasing de punto y

línea activado */ glEnable ( GL_LINE_SMOOTH );}

else { glDisable ( GL_POINT_SMOOTH ); /* Antialiasing de punto y

línea desactivado */ glDisable ( GL_LINE_SMOOTH );

}

Ejemplo 3En este tercer ejemplo (Ej3.zip) se cargará una escenaformada por dos esferas en modo línea (wire). La esferaazul tiene el antiescalonado de línea activado, mientras quela amarilla lo tiene desactivado y estos son los resultados:

La esferas pueden moverse con los cursores y acercarse o alejarsecon las teclas 'a' y 'z'.La función más interesante del ejemplo es display():

void CALLBACK display(void){

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix(); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); //La esfera azul

está suavizadaglTranslatef(-0.9f, 0.0f, zZoom); glColor4f(0.0, 1.0, 1.0, 1.0); glEnable(GL_LINE_SMOOTH); auxWireSphere(0.7); //La esfera amarilla no está

suavizadaglTranslatef(1.8f, 0.0f, 0.0f); glDisable(GL_LINE_SMOOTH); glColor4f(1.0, 1.0, 0.0, 1.0); auxWireSphere(0.7); glPopMatrix(); glFlush();

}

Ejemplo 4En este cuarto ejemplo (Ej4.zip) se emplea antiescalonado en modo indexadoen un toroide. Para ello es necesario crear una rampa de color, debido a que en el modo indexado de color no se pueden utilizar las mezclas para conseguir el antiescalonado. El toroide puede ser manejado con los cursores y las teclas 'a' y 'z' para acercarlo y alejarlo.

El código relacionado con la rampa de color es lo más significativo del ejemplo:

#define RAMPSIZE 16#define RAMPSTART 32

void myinit(void) {

int i; // Se construye la rampafor(i = 0; i < RAMPSIZE; i++) {

GLfloat shade; shade = (GLfloat) i/(GLfloat) RAMPSIZE; auxSetOneColor(RAMPSTART+(GLint)i, shade, shade, shade);

} // Antiescalonado de líneaglEnable(GL_LINE_SMOOTH); // El método de cálculo de antiescalonado en líneas es "no importa" glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE);

}void CALLBACK display(void){

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Establezco el índice de color actual

glIndexi(RAMPSTART); glPushMatrix(); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); glTranslatef(0.0f, 0.0f, zZoom); auxWireTorus(0.5,1.0); glPopMatrix(); glFlush();

}

Ejemplo 5

En este quinto ejemplo (Ej5.zip) se muestra un avión F-15 renderizadomediante líneas. El avión se puede mover con el botón izquierdo del ratón y con el botón derecho se pueder acerar la imagen (hay quemantener el botón pulsado y a la vez mover el ratón para obtener el mejor efecto). El avión inicialmente se muestra con el antialiasing de línea desactivado, pero se puede activar mediante la tecla 'a' o 'A'.

Por último decir que todas la líneas que componen la figura son cargadas desde el fichero /data/f15.data. Por lo que el código no esdemasiado complejo, sólo se ha de leer el fichero con los datos de la líneas, dibujar las mismas y capturar las pulsaciones de ratón o tecladocorrespondientes.

Ejecutar ejemplo

NieblasLas imágenes generadas por ordenador en ocasiones puedenparecer demasiado perfectas. Para añadir un aspecto más natural a las mismas pueden incluirse efectos atmosféricos como la niebla, el humo, la polución, etc. Así pues, la niebla es un efecto que podemosusar para añadir realismo a nuestras escenas.

El efecto de las nieblas en OpenGL no es más que la simulación de la limitación de la visibilidad que se produce al atravesar la luz la masa de aire.

La utilización típica de las nieblas es para la simulación de efectosatmosféricos como las nieblas y nubes, pero también podremosemplearlas para producir indicios de profundidad como veremosmás adelante.

Utilización de las nieblasLa utilización de nieblas es muy sencilla, bastará con habilitar la directiva GL_FOG para que aparezca el efectode las nieblas. Esto se consigue con:

glEnable(GL_FOG)Tras la activación de las nieblas tendremos quedeterminar el método de cálculo de las nieblas, tal y comose explicó en la sección de antiescalonado, para elloutilizaremos la función glHint(). Hay que tener en cuentaque esto puede afectar al rendimiento:

glHint(GL_FOG_HINT,GL_FASTEST) Por rendimiento

glHint(GL_FOG_HINT,GL_NICEST) Por calidad

glHint(GL_FOG_HINT,GL_DON'T_CARE) Da igual el método

Cuando se calcula la niebla de forma rápida aplicando los cálculos sobrelos vértices obtenemos un rendimiento bastante bueno, depende de la implementación de OpenGL utilizada, que será con una cantidad de cálculos dos órdenes mas bajo que si lo realizamos mediante calidad, pues la niebla se calculara para cada píxel y esto requiere realizarmuchísimos más cálculos en general.

Hay que tener en cuenta que las actuales tarjetas de video en 3D suelenvenir con funciones específicas para la implementación por hardware de la niebla, pero estas extensiones no están todavía incluidas dentro de la norma 1.0 de OpenGL.

Después del método de implementación tendremos que indicar cuálesson las factores que influyen en la niebla como el color de la niebla, la densidad y la ecuación utilizada para el cálculo. Todo esto lo veremos en los siguientes puntos.

Ecuaciones de nieblasNo es lo mismo el efecto producido en una calle cuando hay una neblina que cuando la niebla es mucho mas espesa. Para hacer estas distinciones en la escala de aplicación de la niebla se utilizan las ecuaciones de nieblas. Con las distintasecuaciones indicamos cómo debe progresar el efecto de niebla en función de la profundidad de los objetos queestemos observando en la escena.

Las ecuaciones de niebla predefinidas son GL_EXP, GL_EXP2 y GL_LINEAR. Mediante ellas podremos indicar el efecto que tendrá la niebla según la profundidad en la escena, teniendo en cuenta a su vez la densidad de dichaniebla.

GL_LINEAR

GL_EXP2

GL_EXP(Valor por defecto)

Para indicar qué ecuación vamos a usar lo haremosmediante la función glFogi:

glFogi(GL_FOG_MODE, ecuacion)En el caso en que el tipo de ecuación es GL_LINEAR, además deberemos especificar los valores iniciales y finales de aplicación de la niebla mediante las primitivasde niebla GL_FOG_START y GL_FOG_END

En este ejemplo la nieblatiene una ecuación lineal.

La densidad de la niebla será un valor en el intervalo [0,1] que nosindica el espesor de la niebla. Los valores normales suelen ser bastante bajos como 0.025, puesto que con valores altos la escenaqueda casi completamente oculta:

Representación de las ecuaciones de niebla.

Para indicar la densidad utilizaremos:

glFogf(GL_FOG_DENSITY, densidad)

Finalmente para establecer el color de la niebla hay queusar:

glFogf(GL_FOG_COLOR, color)

Ejemplos de nieblas con distinstas densidades y colores

Cuando estamos en modo RGBA el factor f de niebla esutilizado para cuantificar cuánto color de niebla será aplicadosobre el color actual. La función del cálculo del color resultanteserá:

C=fC^i +(1-f)Cf

En el caso de encontrarnos en modo indexado de colortendremos que realizar las rampas de color, degradaciones, precisas para que aparezca un suavizado de los colores haciael fondo como ya vimos en el antiescalonado en modoindexado. El índice del color elegido en cada caso dependeráde:

I=Ii+(1-f)If

Niebla con rampas de color

Es muy sencillo añadir niebla a nuestras escenas en OpengGL, sólo hace falta un trozo de código como el quesigue:

GLfloat densidad=0.35f; //Mucha nieblaGLfloat fogColor[4] = {0.5f, 0.5f, 0.5f, 1.0f}; //Niebla grisGlint fogMode=GL_EXP //Ecuación de niebla exponencial

glEnable(GL_FOG); //Activar las nieblasglFogi (GL_FOG_MODE, fogMode); //Ecuación de nieblasglFogfv (GL_FOG_COLOR, fogColor); //Color de la nieblaglFogf (GL_FOG_DENSITY, densidad); //Densidad de la nieblaglHint (GL_FOG_HINT, GL_DONT_CARE); //Cálculo de nieblas "no

importa"

Usos de las nieblas

Los principales usos de las nieblas son la simulación de nubes y producir indicios de profundidad en las escenas:

-Simular nubes y nieblas: utilizaremos colores de nieblas del blanco al grisáceo y ecuaciones lineales con poca densidad en el caso de neblinas. Para crear nubes espesas con poca visibilidadusaremos valores altos de densidad y funciones GL_EXP o GL_EXP2 que permitan ver claro las cosas lejanas y una aplicaciónmas acusada de la niebla en zonas lejanas.

-Indicios de profundidad: Se puede producir la ilusión de distancia pintando aquello lejano de un color más ténue quelo cercano. Esta idea es ya muy antigua y se aplicaba en losprimeros sistemas graficos, aquellos que sólo pintaban líneasy además en un sólo color. Disminuían la intensidad del color de la línea a medida que ésta se alejaba del punto de vista dando una clara sensación de profundidad aún sin tener Z-Buffer, ... esto se le llama Depth Cueing.

Escena sin nieblasEscena demasiado "limpia", sólo se ha realizadola perspectiva para dar profundidad a la escena.

No se han utilizado nieblas.

Escena con niebla GL_EXPSe puede observar la progresión del fundido conel fondo. Si situásemos objetos más lejanos aúnpodríamos observar cómo desaparecen estos.

En las capturas del ejemplo se puede ver cómo afectan los distintos tiposde niebla a una escena. Podemos observar el efecto de progresión suave de la niebla en el caso de ecuaciones GL_LINEAR y el corte brusco de losobjetos fundiéndose con el fondo en el caso de utilizar GL_EXP2. Los valores de color de niebla son iguales a los del fondo para que aparezca el efecto de fundido con el fondo. A su vez el valor de la densidad es bastantebajo en torno a 0,03 y los objetos están separados entre sí para apreciarmejor los efectos.

Escena con niebla GL_EXP2Se aprecia el corte más brusco de los objetos

situados en el fondo de la escena.

Escena con niebla GL_LINEARProgresión suave del fundido.

Ejemplo 1

En este primer ejemplo (Ej1.zip) se cargará una imagen formada por una hilerade esferas. Inicialmente la niebla estará activada, con la ecuación GL_LINEAR, pero se podrá cambiar el tipo de niebla con el cursor izquierdo. También se puede hacer variar la densidad de la niebla con las flechas arriba y abajo. Porúltimo se puede variar el color de la niebla. Las teclas V y F alteran el valor de alfa (auméntadolo o disminuyéndolo en 0.025 por cada pulsación). Las teclas C y D se encargan del azul, X y S modifican el verde y A y Z del rojo.

Dentro del código cabe resaltar:En el archivo Ej1.cEn la función inicializa() se especifica las condiciones iniciales de niebla

void inicializa(void){

float mat_ambient[] = { 0.1745, 0.01175, 0.01175};float mat_diffuse[] = { 0.61424, 0.04136, 0.04136};float mat_specular[] = { 0.727811, 0.626959, 0.626959};

// Luces, materiales,...

/* Referente a las nieblas */ glFogi(GL_FOG_MODE, fogMode); // Inicialmente niebla lineal glFogfv(GL_FOG_COLOR, fog_color); /* Valores de inicio y fin de la niebla lineal */ glFogf(GL_FOG_START, 0.0); glFogf(GL_FOG_END, final); glFogf(GL_FOG_DENSITY, densidad);

glClearColor(0.5, 0.5, 0.5, 1.0); glEnable(GL_FOG); // Se activa el uso de nieblas

}

En la función cambiaModo se cambia la ecuación de niebla.

void cambiaModo(void){

if (fogMode == GL_LINEAR){

fogMode = GL_EXP;glFogf(GL_FOG_DENSITY, densidad); printf("\nNiebla

GL_EXP\n");}else if (fogMode == GL_EXP){

fogMode = GL_EXP2;glFogf(GL_FOG_DENSITY, densidad);

}else if (fogMode == GL_EXP2){

fogMode = GL_LINEAR;glFogf(GL_FOG_START, 0.0);glFogf(GL_FOG_END, final);

}glFogi(GL_FOG_MODE, fogMode);

}

Ejemplo 2

En este segundo ejemplo (Ej2.zip) se cargará una escena formada porun círculo de esferas y un cubo enmedio. La escena puede rotarsehorizoltamente con los cursores izquierda y derecha y verticalmente con arriba y abajo.

Mediante las teclas [1],[2] y [3] se elige el tipo de niebla. Con [4] y [5] se aumenta o disminuye la densidad. Con [0] se elige activar/desactivarnieblas.

En la función inicializar se dan los valores iniciales de la niebla.

void CALLBACKinicializar(void){

glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); // Calculo de profundidad glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); // Trasparencias que añaden

// color a original glEnable(GL_LIGHTING); // Activar luces

//Especificación de las lucesglLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambientLight);glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);glLightfv(GL_LIGHT0,GL_SPECULAR,specular);

//No dibujar caras ocultas.glEnable(GL_CULL_FACE);// Color del fondo :: BackgroundglClearColor(0.5f, 0.5f, 0.5f, 1.0f );

//Establecer nieblaglFogi (GL_FOG_MODE, fogMode);glFogfv (GL_FOG_COLOR, fogColor);glFogf (GL_FOG_DENSITY, fogDensidad);glHint (GL_FOG_HINT, GL_DONT_CARE); //Da igual el método para calcular la

// niebla }

Ejemplo 3

En este tercer ejemplo (Ej3.zip) se cargará una escena quepresenta nieblas con rampas de color, en modo de color indexado.

En la función myinit() se crea la rampa de color que formará la niebla en el modo de color indexado.

#define NUMCOLORS 32 // Número de tonos de la rampa#define RAMPSTART 16 // Inicio de la rampa

void myinit(void){

int i;glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LEQUAL);

// Creación de la rampafor (i = 0; i < NUMCOLORS; i++){

GLfloat shade;shade = (GLfloat) (NUMCOLORS-i)/(GLfloat) NUMCOLORS;

auxSetOneColor (16 + i, shade, shade, shade);}glEnable(GL_FOG);glFogi (GL_FOG_MODE, GL_LINEAR);glFogi (GL_FOG_INDEX, NUMCOLORS);glFogf (GL_FOG_START, 0.0);glFogf (GL_FOG_END, 4.0);glHint (GL_FOG_HINT, GL_NICEST);glClearIndex((GLfloat) (NUMCOLORS+RAMPSTART-1));

}

Ejemplo 4Este cuarto ejemplo (Ej4.zip) es muy didáctico para vercómo funcionan las nieblas en OpenGL.

En este ejemplo se muestran todas las funciones que intervienen en la formación de la niebla, color, ecuación y densidad. Los parámetros de estasfunciones se pueden alterar con el ratón, pulsando sobre el parámetro (en color verde) y moviendo a la vez el rató arriba o abajo. Se puede ver el resultado de las modificaciones en la imagen del cuadro superior derecho. Además con el botón derecho del ratón se puede cambiar la ecuación de nieblas y la imagen a mostrar.

Ejecutarejemplo