Lecc 11

  • Uploaded by: maria
  • 0
  • 0
  • December 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Lecc 11 as PDF for free.

More details

  • Words: 5,331
  • Pages: 36
TEMA 12 EFECTOS VISUALES: FUSIONES Y NIEBLA

Juan Carlos Hernández González - 52415268Q David Álvarez Oquina - 71024082J Juan Manuel Sánchez Manzano - 52414006L Informática Gráfica Ingeniería Informática – Universidad de Salamanca

Departamento de Informática y Automática Universidad de Salamanca

Índice: Introducción........................................................................................................ 4 1.- Fusiones (Mezclas) ....................................................................................... 5 1.1 – Combinación de colores ........................................................................ 5 1.2 – Cambio de la ecuación de fusión ........................................................... 9 1.3 – Uso de fusiones ................................................................................... 10 1.3.2 – Desvanecimiento........................................................................... 11 1.3.2 – Composición ................................................................................. 11 1.3.3 – Filtros de color............................................................................... 12 1.3.4 – Simulación de brochas y pinceles ................................................. 12 1.3.4 – Antiescalonado (Antialiasing o Suavizado) ................................... 13 1.3.5 – Billboarding ................................................................................... 13 1.4 – Manejo de la profundidad .................................................................... 14 1.5 – Capas ocultas de los objetos ............................................................... 16 2 – Antiescalonado (Antialiasing o Suavizado)................................................. 18 2.1 – Suavizado en color indexado............................................................... 22 2.2 – Muestreo múltiple................................................................................. 23 3 – La niebla..................................................................................................... 24 4 – Búfer de acumulación................................................................................. 28 5 – Otras operaciones de color ........................................................................ 31 5.1 – Máscaras de color................................................................................ 31 5.2 – Operaciones de color lógicas............................................................... 31 5.3 – Prueba Alpha ....................................................................................... 32 5.4 – Tramado .............................................................................................. 33 Conclusiones.................................................................................................... 35 Bibliografía ....................................................................................................... 36

2

Índice de Tablas y Figuras: Tabla 1 – Combinación de colores (glBlendFunc).............................................. 7 Figura 1 – Ejemplo de reflejos............................................................................ 8 Tabla 2 – Código fuente de ejemplo de reflejos ................................................. 9 Tabla 3 – Cambio de la ecuación de fusión (glBlendEquation) .......................... 9 Figura 2 – Ejemplo de transparencias.............................................................. 11 Figuras 3 y 4 – Ejemplo de composición .......................................................... 12 Figuras 5 y 6 – Aplicación de suavizado .......................................................... 13 Figura 7 – Árbol con billboarding...................................................................... 14 Tabla 4 – Manejo de la profundidad (glDepthFunc) ......................................... 16 Figura 8 – Ejemplo de bordes dentados........................................................... 18 Tabla 5 –Objetivos ........................................................................................... 19 Tabla 6 – Metodos............................................................................................ 20 Figura 9 – Puntos sin suavizado ...................................................................... 20 Figura 10 – Ejemplo de suavizado en puntos................................................... 21 Figura 11 – Ejemplo de suavizado en lineas .................................................... 21 Tabla 7 – Ecuaciones de niebla ....................................................................... 24 Figura 12 – Comportamiento de ecuaciones de niebla .................................... 25 Figura 13 – Sin niebla ...................................................................................... 26 Figura 14 – Niebla generada con la ecuación GL_LINEAR ............................. 26 Figura 15 – Niebla generada con la ecuación GL_EXP ................................... 26 Figura 16 – Niebla generada con la ecuación GL_EXP2 ................................. 26 Tabla 8 – Fragménto de código fuente de niebla ............................................. 27 Tabla 9 – Operaciones del búfer de acumulación. ........................................... 28 Figura 17 – Vista antes la acumulación............................................................ 29 Figura 18 – Vista tras el volcado del búfer (Depth of Field).............................. 29 Figura 19 – Vista tras el volcado del búfer (Motion Blur).................................. 30 Tabla 10 – Operaciones de color lógicas (glLogicOp)...................................... 32 Tabla 11 – Prueba Alpha (glAlphaFunc) .......................................................... 33

3

Introducción Para conseguir una mayor realidad en las figuras representadas con OpenGL, se puede recurrir a colores, luces y texturas entre otras opciones. No obstante se necesitan otros “efectos” para conseguir la disminución de nitidez o claridad de visión, esto se consigue mediante las fusiones, mezclas, el antiescalonado y las nieblas. Con ello se consiguen la fusión y el solapamiento de colores, suavizar bordes dentados para un mayor ajuste a la figura real y efectos atmosféricos y limitaciones de visibilidad.

4

1.- Fusiones (Mezclas) OpenGL coloca el valor del color en el búfer de colores en circunstancias normales. Los valores de profundidad para cada fragmento se sitúan en el búfer de profundidad. Cuando se desactiva la prueba de profundidad, los valores del nuevo color sobrescriben cualquier valor ya presente en el búfer de colores. Cuando la prueba de profundidad se activa, los fragmentos del nuevo color reemplazan los fragmentos existentes sólo si se parecen al plano de recorte cercano más que los valores que ya se encontraban ahí. Todo esto sucede en condiciones normales, pero estas reglas dejan de aplicarse en el momento en que activamos las fusiones de OpenGL: glEnable(GL_BLEND); para habilitar las mezclas. glDisable(GL_BLEND); para deshabilitar las mezclas.

Cuando la fusión se ha activado, el color entrante se combina con el valor del color presente en le búfer de colores. La forma en que se combinan nos proporciona una alta gama de efectos especiales.

1.1 – Combinación de colores El valor que ya se encuentra almacenado en el búfer de colores se denomina color de destino. Este valor de color tiene tres componentes individuales (rojo, verde y azul) y, opcionalmente, un valor alpha.

Un valor de color que entra como resultado de más comandos de interpretación que puedan interactuar o no con el color destino se denomina color de origen. El color de origen también tiene los componentes rojo, verde y azul y, opcionalmente, el valor alpha.

5

La forma en que se combinan los colores de origen y destino cuando se ha activado la fusión se controla a través de una ecuación de fusión. La ecuación predeterminada es: Cf = (Cs*S)+(Cd*D) Cf = Color Cs = Color Cd = Color S = Factor D = Factor

final computado. de origen. de destino. de fusión de origen. de fusión de destino.

Los factores de fusión S y D se establecen con la siguiente función: glBlendFunc(GLenum S, GLenum D);

S y D no son valores físicos que podamos especificar directamente, sino que son una enumeración de valores.

En la tabla siguiente se muestran los posibles valores para la función de fusión. Los subíndices

s,

d

y

c

se refieren

al origen, destino y color

respectivamente. R, G, B y A se refieren al rojo, verde, azul y alpha respectivamente.

Función

Factores de

Factor de

fusión RGB

fusión Alpha

GL_ZERO

(0,0,0)

0

GL_ONE

(1,1,1)

1

GL_SRC_COLOR

(Rs,Gs,Bs)

As

GL_ONE_MINUS_SRC_COLOR

(1,1,1)-(Rs,Gs,Bs)

1-As

GL_DST_COLOR

(Rd,Gd,Bd)

Ad

GL_ONE_MINUS_DST_COLOR

(1,1,1)-(Rd,Gd,Bd)

1-Ad

GL_SRC_ALPHA

(As,As,As)

As

GL_ONE_MINUS_SRC_ALPHA

(1,1,1)-(As,As,As)

1-As

GL_DST_ALPHA

(Ad,Ad,Ad)

Ad

GL_ONE_MINUS_DST_ALPHA

(1,1,1)-(Ad,Ad,Ad)

1-Ad

GL_CONSTANT_COLOR

(Rc,Gc,Bc)

Ac

GL_ONE_MINUS_CONSTANT_COLOR

(1,1,1)-(Rc,Gc,Bc)

1-Ac

6

GL_CONSTANT_ALPHA

(Ac,Ac,Ac)

Ac

GL_ONE_MINUS_CONSTANT_ALPHA

(1,1,1)-(Ac,Ac,Ac)

1-Ac

GL_SRC_ALPHA_SATURATE

(f,f,f)*

1

Tabla 1 – Combinación de colores (glBlendFunc)

*f = min(As, 1-As).

Los colores se representan mediante números de punto flotante. Por tanto, sumarlos, restarlos e incluso multiplicarlos son operaciones perfectamente válidas.

La tabla anterior puede ser algo confusa, por lo que se va a ver un ejemplo a continuación: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Esta función le indica a OpenGL que recoja el color de origen (entrante) y multiplique el color (valores RGB) por el valor alpha, que sume este resultado al resultado de multiplicar el color destino por uno menos el valor de alpha del origen. Por ejemplo, se supone que está el color Rojo (1.0f, 0.0f, 0.0f, 0.0f) preparado ya en el búfer de colores. Éste sería el color destino Cd. Si se dibuja sobre éste con el color Azul y un valor alpha de 0.5 (0.0f, 0.0f, 1.0f, 0.5f), se podrían computar los colores finales de la siguiente manera: Cd = color de destino = (1.0f, 0.0f, 0.0f, 0.0f) Cs = color de origen = (0.0f, 0.0f, 1.0f, 0.5f) S = alpha de origen = 0.5 D = uno menos alpha de origen = 1.0 – 0.5 = 0.5

La ecuación Cf=(Cs*S)+(Cd*D) se calcula así: Cf=(Azul*0.5)+(Rojo*0.5)

El color final es una combinación escalada del valor del rojo original con el valor del azul entrante. Cuando mayor sea el valor alpha entrante, se añadirá más del color entrante y se retendrá menos del color original.

7

Esta función de fusión se suele usar para conseguir el efecto de dibujar un objeto transparente delante de un objeto opaco. Sin embargo, esta técnica requiere que dibujemos primero el objeto u objetos del fondo y a continuación, el objeto transparente fusionado delante. Este efecto puede ser especular:

Figura 1 – Ejemplo de reflejos

En este ejemplo, se utiliza la fusión para crear un falso efecto reflectante. Se usa una función que hemos llamado DrawWorld() para generar los dos toros, la esfera y los movimientos que realizan. Para generar el suelo se ha codificado otra función llamada DrawGround(). En la función RenderScene() se dibuja en primer lugar la escena escalando por -1 para invertir el eje “y”, los giros y colocar la luz debajo. De este modo se obtiene la imagen reflejada. Después se dibuja el suelo y se utiliza la función de fusión para hacerlo transparente y crear así el efecto de reflejo. Y para terminar, se dibuja la escena normal: void RenderScene(void) { //Borrar la ventana con el color de borrado actual glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); //Mover la luz de debajo del suelo a la luz del mundo reflejado glLightfv(GL_LIGHT0, GL_POSITION, fLightPosMirror); if(reflejo) { glPushMatrix(); glFrontFace(GL_CW); //La geometría se refleja, //intercambiar la orientación

8

glScalef(1.0f, -1.0f, 1.0f); DrawWorld(); //Dibujar el mundo reflejado glFrontFace(GL_CCW); glPopMatrix(); } //Dibujar el suelo transparente sobre el reflejo glDisable(GL_LIGHTING); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); DrawGround(); glDisable(GL_BLEND); glEnable(GL_LIGHTING); //Restablecer la iluminación y dibujar el mundo correctamente glLightfv(GL_LIGHT0, GL_POSITION, fLightPos); DrawWorld(); //Dibujar el mundo normal glPopMatrix(); //Realizar el intercambio del búfer glutSwapBuffers(); } Tabla 2 – Código fuente de ejemplo de reflejos

1.2 – Cambio de la ecuación de fusión La ecuación de fusión vista en el apartado anterior es la ecuación predeterminada, pero se puede elegir entre cinco ecuaciones diferentes y seleccionarlas con la siguiente función: void glBlendEquation(GLenum modo);

Modo

Función

GL_FUNC_ADD (predeterminado)

Cf=(Cs*S)+(Cd*D)

GL_FUNC_SUBSTRACT

Cf=(Cs*S)-(Cd*D)

GL_FUNC_REVERSE_SUBSTRACT

Cf=(Cd*D)-(Cs*S)

GL_MIN

Cf=min(Cs,Cd)

GL_MAX

Cf=max(Cs,Cd)

Tabla 3 – Cambio de la ecuación de fusión (glBlendEquation)

Además de glBlendFunc

(vista en el apartado anterior), hay más

flexibilidad con la siguiente función: void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);

9

Mientras que glBlendFunc especifica las funciones de fusión para los valores RGBA de origen y destino, glBlendFuncSeparate permite especificar funciones de fusión para los componentes RGB y alpha por separado.

Todos

los

valores

GL_CONSTANT_COLOR,

GL_ONE_MINUS_CONSTANT_COLOR

y

GL_CONSTANT_ALPHA,

GL_ONE_MINUS_CONSTANT_ALPHA

permiten que se introduzca un color de fusión constante en la ecuación de fusión. Este color de fusión constante es inicialmente Negro (0.0f, 0.0f, 0.0f, 0.0f), pero puede cambiarse con la siguiente función: void glBlendColor(GLclampf rojo, GLclampf verde, GLclampf azul, GLclampf alpha);

1.3 – Uso de fusiones Las funciones vistas en los apartados anteriores se pueden utilizar para crear distintos tipos de efectos. A continuación se verán los más comúnmente utilizados.

1.3.1 – Transparencias

Es el uso más habitual de las mezclas. Si se desea dibujar una imagen compuesta por varios elementos translúcidos, se dibujará primero el fondo con los valores por defecto de los factores origen y destino. A continuación se modifican esos factores asignando al origen GL_SRC_ALPHA y al destino GL_ONE_MINUS_SRC_ALPHA, como se pudo ver en el primer apartado a cerca de las fusiones, dibujando las figuras partiendo de la más alejada hasta la más próxima (que será la última en ser dibujada).

10

Figura 2 – Ejemplo de transparencias

1.3.2 – Desvanecimiento

Partiendo de los factores usados al realizar las transparencias es muy sencillo hacer que un objeto desaparezca de la escena. Basta con indicar un valor alpha 0.0f a la figura, que asignará a la misma una transparencia total.

1.3.2 – Composición

Se puede representar una imagen compuesta a partir de otras dos en dos pasos. Primero se aplica el valor GL_ONE al factor origen, GL_ZERO al destino y se dibuja la imagen. Después se asigna GL_SRC_ALPHA al origen y GL_ONE_MINUS_SRC_ALPHA al destino y se dibuja la imagen con un factor alpha de 0.5f.

11

Figuras 3 y 4 – Ejemplo de composición

1.3.3 – Filtros de color

Para modular cada componente de color de forma individual potenciando o reduciendo

las

componentes

GL_ONE_MINUS_DST_COLOR

RGB

para

el

se

utilizan

origen

y

GL_DST_COLOR

o

GL_SRC_COLOR

o

GL_ONE_MINUS_SRC_COLOR para el destino. Este proceso se utiliza para el filtrado fotográfico de colores.

1.3.4 – Simulación de brochas y pinceles

Las fusiones se pueden utilizar para simular brochas que cubren una superficie con un determinado color de forma gradual. Se puede hacer que, por ejemplo, cada pincelada añada un 10% de color sobre un 90% del color original de la superficie donde se pinta, es decir, que cada pincelada añadiría un cierto valor de mezcla.

Para hacerlo, se utilizar el factor GL_SRC_COLOR sobre el origen. Modificando los valores de alpha a través de la imagen de la brocha se puede

12

simular el efecto de añadir más color en el centro que en los extremos, con los que se obtiene la forma de un pincel antiescalonado.

De la misma forma se puede hacer un borrador, asignando los valores de color del fondo.

1.3.4 – Antiescalonado (Antialiasing o Suavizado)

Un efecto muy importante para el que se emplean las fusiones es el de suavizado (o antiescalonado), que se utiliza, como su propio nombre indica, para suavizar los bordes de las figuras representadas. Debido

a su

importancia, posteriormente se verá este tipo de efecto en profundidad.

Figuras 5 y 6 – Aplicación de suavizado

1.3.5 – Billboarding

Se puede conseguir que imágenes raster (trama) tengan un aspecto ligeramente tridimensional y de profundidad asignando diferentes valores alpha a los fragmentos individuales que componen la imagen. Este efecto mejora aplicando varias capas o cruces de la misma imagen.

Este método se puede utilizar, por ejemplo para dibujar árboles. Se puede dibujar un polígono con la forma de la copa del árbol y aplicarle una textura que represente las hojas del árbol. Después utilizando esta técnica se puede

13

conseguir que parezca una imagen tridimensional. De esta forma se puede crear un árbol mucho más rápidamente que haciendo un modelo tridimensional completo.

Figura 7 – Árbol con billboarding

1.4 – Manejo de la profundidad El orden en que se dibujan las cosas afecta al resultado final de las fusiones. Cuando se representan objetos traslúcidos en tres dimensiones se obtienen resultados diferentes en función del orden en que se dibujen los elementos.

Para solucionar este problema se dispone del búfer de profundidad (ZBuffer). Este búfer supervisa la distancia entre el punto de vista y la parte del objeto que ocupa un determinado píxel en una ventana de la pantalla. Cuando se asigna un color a dicho píxel sólo se dibuja si el objeto está más cerca del punto de vista, almacenando el valor de profundidad en el búfer. Utilizando este búfer se asegura no representar innecesariamente las partes ocultas de las superficies, y por tanto, no se utilizan en las fusiones.

Es muy importante el uso de este búfer en las escenas que muestran tanto objetos traslúcidos como opacos para eliminar las superficies ocultas tras los elementos opacos. Si una figura opaca oculta a otros objetos, el búfer de

14

profundidad se encarga de eliminar la figura más lejana. En cambio, si es una figura traslúcida la que está delante de otros objetos, habrá que realizar la fusión de la figura con los que haya detrás.

Es sencillo establecer el orden correcto en que se dibujan los objetos si es una escena estática, pero si el punto de vista o los objetos se mueven, puede suponer un problema. Por ello es conveniente usar el búfer de profundidad para evitar estos problemas.

La técnica de comprobación de la profundidad se maneja con las siguientes funciones: glEnable(GL_DEPTH_TEST); para activar la comprobación de profundidad. glDisable(GL_DEPTH_TEST); para desactivarla.

La condición de validación según la profundidad se calcula con la siguiente función: glDepthFunc(GLenum tipo); donde tipo es el tipo de condición.

Tipo GL_NEVER GL_LESS

Significado Los fragmentos nunca pasan la prueba de profundidad. Los fragmentos sólo pasan la prueba de profundidad si el valor z entrante es menor que el valor z presente en el búfer de profundidad. Éste es el valor predeterminado.

GL_LEQUAL

Los fragmentos sólo pasan la prueba de profundidad si el valor z entrante es menor o igual que el valor z presente en el búfer de profundidad.

GL_EQUAL

Los fragmentos sólo pasan la prueba de profundidad si el valor z entrante es igual que el valor z presente en el búfer de profundidad.

GL_GREATER

Los fragmentos sólo pasan la prueba de profundidad si el valor z entrante es mayor que el valor z presente en el búfer de profundidad.

GL_NOTEQUAL Los fragmentos sólo pasan la prueba de profundidad si el valor z entrante es distinto que el valor z presente en el búfer de profundidad.

GL_GEQUAL

Los fragmentos sólo pasan la prueba de profundidad si el valor z entrante es mayor o igual que el valor z presente en el búfer de profundidad.

GL_ALWAYS

Los

fragmentos

siempre

15

pasan

la

prueba

de

profundidad,

independientemente del valor z. Tabla 4 – Manejo de la profundidad (glDepthFunc)

Para evitar los problemas con las fusiones y la profundidad, es recomendable pintar en primer lugar los objetos opacos y dibujar los objetos comenzando por los que se encuentran al fondo para continuar sucesivamente con los objetos a medida que van estando más próximos al punto de vista.

Esto no siempre puede realizarse, porque se enmarca casi exclusivamente en la representación estática, así que se recomienda la activación de la comprobación de profundidad cuando se incluyan movimientos de los objetos o del punto de vista.

1.5 – Capas ocultas de los objetos Cuando se representan objetos translúcidos tridimensionales hay que tener en cuenta las siguientes capas: Capa delantera visible: la porción que se aprecia en primer plano. Parte posterior de la capa delantera: el interior de la capa delantera visible. Parte anterior de la capa trasera: el interior de la capa trasera. Parte posterior de la capa trasera. El mayor grado de realismo se consigue con el uso de tarjetas gráficas con capacidades para el almacenamiento de varios búfer de profundidad.

En algunos casos, las características del objeto hacen que haya que eliminar el dibujo de sus capas ocultas (cuando esas capas tengan un grosor mínimo). Un ejemplo muy claro de este caso es la representación de una burbuja. Al aplicar el efecto de las fusiones de transparencia se muestra no sólo la transparencia, sino también los brillos y reflejos correspondientes a las cuatro capas de la esfera.

16

Para usar esta característica se usan las siguientes funciones: glEnable(GL_CULL_FACE); para habilitar el efecto de representación de capas ocultas. glDisable(GL_CULL_FACE); para deshabilitar el efecto.

17

2 – Antiescalonado (Antialiasing o Suavizado) Cuando representamos imágenes en la pantalla un punto se representa como mínimo por un píxel que suelen tener forma cuadrática o casi cuadrática. De hecho debido a la resolución de pantalla varios puntos pueden ser representados por el mismo píxel con lo que líneas que tienen distinto ángulo pueden tener una representación similar al ser formadas por puntos situados en los mismos píxeles. Esto produce que cuando pintamos líneas oblicuas se vea muy claramente la división de colores entre la línea y el fondo, observándose los bordes dentados. Estos bordes dejan descubrir al observador que la imagen esta claramente generada por ordenador con lo que se pierde la sensación de realidad que queremos que tenga la imagen; este realismo es muy deseado.

Figura 8 – Ejemplo de bordes dentados

Para eliminar los bordes dentados se utiliza el suavizado para fundir el color de lo que queremos pintar con el color de destino del píxel y los píxeles próximos, esto consiste en difuminar ligeramente los colores del píxel hacía los píxeles próximos a los bordes.

Para realizar el suavizado se activan las mezclas estableciendose la misma función de fusión que para la transparencia:

glEnable(GL_Blend); glBlenfunc(Gl_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

18

La ecuación de fusión utilizada será la predeterminada no es necesario cambiarla.

Seguidamente

se

activa

el

suavizado

también

con

glEnable

seleccionando:

glEnable(GL_POINT_SMOOTH); // Suavizar puntos glEnable(GL_LINE_SMOOTH); // Suavizar líneas glEnable(GL_POLYGON_SMOOTH);

//

Suavizar

bordes

de

polígono

Finalmente con glHint podemos especificar el algoritmo deseado para realizar el suavizado:

glHInt (GLenum Objetivo,Glenum metodo)

En Objetivo podemos introducir:

Objetivo

Significado

GL_LINE_SMOOTH_HINT El tipo de suavizado

GL_POINT_SMOOTH_HINT

GL_POLYGON_SMOOTH_HINT

Para especificar la calidad de la

GL_FOG_HINT

niebla, por píxel (mayor coste mejor calidad) o por vértice

GL_PERSPECTIVE_CORRECTION_HINT

Para

especificar

la

calidad

de

interpolación en colores y texturas

Tabla 5 –Objetivos

19

En método seleccionaremos:

Método

Significado

GL_FASTEST

El de mayor rendimiento

GL_NICEST

El de mayor calidad

El que se pueda

GL_DONT_CARE

Tabla 6 – Metodos

Finalmente decir que si queremos desactivar el suavizado usaremos

glDisable (tipo de suavizado)

Figura 9 – Puntos sin suavizado

20

Figura 10 – Ejemplo de suavizado en puntos

Figura 11 – Ejemplo de suavizado en lineas

El cono rojo esta suavizado mientras que antes de pintar el verde se desactivo el suavizado.

21

En la función Iniciar que se ejecuta al comenzar el programa activamos las mezclas, seleccionamos la función de mezclas y el algoritmo a utilizar. En la función Mostrar que genera la escena se activa y desactiva el suavizado previamente a pintar la figura deseada (con o sin suavizado). void CALLBACK Iniciar(void) { glEnable(GL_BLEND); //Activar mezclas glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //Tipo de mezcla glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); //Aplicar mezclas como sea glLineWidth(1.5); glClearColor(0.0, 0.0, 0.0, 0.0); //Color de fondo negro }

void CALLBACK Mostrar(void) { //Limpiado de los buffers de color y profundidad 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); //Cono rojo suavizado glTranslatef(-0.9f, 0.0f, 0.0f); glColor4f(1.0, 0.0, 0.0, 1.0); glEnable(GL_LINE_SMOOTH); //Activamos suavizado auxWireCone(0.7,1); //Cono verde no suavizado glTranslatef(1.8f, 0.0f, 0.0f); glDisable(GL_LINE_SMOOTH); //Desactivamos suavizado glColor4f(0.0, 1.0, 0.0, 1.0); auxWireCone(0.7,1); glPopMatrix(); glFlush(); } Tabla 7 – Fragménto de código fuente de suavizado

2.1 – Suavizado en color indexado En el modo de color indexado no están habilitadas las mezclas por lo que tenemos que construir rampas de color para producir el difuminado del color. Normalmente se suele hacer en escala de grises pero si se hace con detalle se puede realizar con cualquier color. 22

2.2 – Muestreo múltiple El suavizado de puntos y líneas se admite ampliamente pero no todas las implantaciones de Opengl admiten el suavizado poligonal e incluso en aquellas que lo admiten no es el medio más conveniente para realizar el suavizado ya que se deberían ordenar todos los dibujos de adelante hacia atrás. Una alternativa para resolver esto es el muestreo múltiple, consistente en utilizar búfer que incluye los valores decolor de la profundidad y las plantillas; todos los primitivos se muestrean varias veces por píxel y el resultado se guarda en este búfer

Par activar el muestreo múltiple hay que tener un contexto que lo admita, por ejemplo en glut se establece con el campo de bits GLUT_MULTISAMPLE de la forma:

glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH|GL UT_MULTISAMPLE) ;

Seguidamente activamos o desactivamos el muestreo con:

glEnable(GL_MULTISAMPLE) o glDisable(GL_MULTISAMPLE)

Una última aclaración es que si se activa el muestreo múltiple se ignoran los suavizados de líneas, puntos y polígonos por lo que lo más conveniente es dibujar primero lo que queramos que tenga suavizado y después activar el muestreo y dibujar seguidamente lo que creamos necesite el muestreo múltiple ya que los cambios de estado pueden ser costosos en cuanto al rendimiento.

23

3 – La niebla La niebla es un efecto de openGL que simula la limitación de visibilidad, consiguiéndose la fusión del color especificado para la niebla en el elemento geométrico una vez efectuados los cálculos del color. Para utilizar las nieblas deben

aplicarse las funciones de OpenGL: glEnable(GL_FOG); para habilitar las nieblas. glDisable(GL_FOG); para deshabilitar las nieblas.

Para cambiar el comportamiento de las nieblas deben aplicarse las variantes de la función glFog de OpenGL: void glFogi(GLenum paname, GLint param); void glFogf(GLenum paname, GLfloat param); void glFogiv(GLenum paname, Glint* param); void glFogfv(GLenum paname, GLfloat* param);

Con todo ello se conseguirá un efecto 3D, gracias a que los objetos mas alejados geométricamente de la cámara, irán “desapareciendo” en función de la distancia.

Para hacer distintas escalas de niebla se emplean las ecuaciones de niebla. Estas calculan un factor de niebla entre 0 y 1 en función de la progresión de la distancia. Existen tres ecuaciones de niebla para conseguir distintos efectos en función de la profundidad, considerando densidades de nieblas: Modo de niebla

Ecuación de niebla

GL_LINEAR

f=(fin – c)/(fin – inicio)

GL_EXP

f=exp(-d * c)

GL_EXP2

f=exp(-(d * c)^2) Tabla 8 – Ecuaciones de niebla

24

Donde c es la distancia del fragmento al punto visual, fin es la distancia GL_FOG_END, inicio es la distancia GL_FOG_START y d la densidad de la niebla. Para emplear una u otra ecuación bastara con introducirla como param en la función glFog vista anteriormente.

En la figura 3.2 se puede apreciar el comportamiento de la niebla generado por las distintas ecuaciones:

Figura 12 – Comportamiento de ecuaciones de niebla

El factor f de niebla se utiliza para obtener el color definitivo aplicando la siguiente ecuación: C = F*Ci + (1 - f)*Cf donde Ci representa el color del objeto y Cf el color de la niebla definido utilizando GL_FOG_COLOR.

A continuación se puede observar el comportamiento de la niebla según la ecuación empleada:

25

Figura 13 – Sin niebla

Figura 14 – Niebla generada con la ecuación GL_LINEAR

Figura 15 – Niebla generada con la ecuación GL_EXP

Figura 16 – Niebla generada con la ecuación GL_EXP2

26

Las partes interesantes del código son las siguientes: //Inicialización

GLfloat final = 25.0; GLfloat densidad = 0.1; GLint fogMode = GL_EXP2; GLfloat fog_color[4] = { 0.5, 0.5, 0.5, 1.0}; //Inicializacion de las nieblas

glFogi(GL_FOG_MODE, GL_EXP); glFogfv(GL_FOG_COLOR, fog_color); 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); //activación

glFogf(GL_FOG_START, 0.0); glFogf(GL_FOG_END, final); Tabla 9 – Fragménto de código fuente de niebla

27

4 – Búfer de acumulación El búfer de acumulación ha sido creado para la integración de múltiples imágenes. Esto se consigue mediante la acumulación, en el búfer de acumulación, de copias del contenido del búfer de color, fusionándose así el contenido del búfer de color con el contenido acumulado en el búfer de acumulación. Tras acabar la acumulación de la imagen, se copiara de nuevo el contenido del búfer de acumulación al búfer de color.

Para manejar este búfer se emplea las funciones de OpenGL: glClearAccum();para la limpieza del búfer glAccum(GLenumm operación,GLfloat valor);

El parámetro valor será el valor en punto flotante que se usa para escalar la operación, las posibles operaciones que se pueden realizar son:

operación

Acción

GL_ACCUM

Escala los valores del búfer de color por un valor y los añade al contenido actual del búfer de acumulación.

GL_LOAD

Escala los valores del búfer de color por un valor y reemplaza al contenido actual del búfer de acumulación.

GL_RETURN

Escala los valores del búfer de color por un valor y copia los valores del búfer de color.

GL_ADD

Escala los valores del búfer de color por un valor y lo añade al contenido del búfer de acumulación.

GL_MULT

Escala los valores del búfer de color por un valor y lo guarda en el búfer de acumulación. Tabla 10 – Operaciones del búfer de acumulación.

A continuación se puede observar como se comporta el búfer de acumulación en los ejemplos Depth of Field y Motion Blur:

28

Figura 17 – Vista antes la acumulación

Figura 18 – Vista tras el volcado del búfer (Depth of Field)

29

Figura 19 – Vista tras el volcado del búfer (Motion Blur)

En ambos casos se parte de la misma imagen inicial, en el primer caso toda la habitación (salvo la esfera) es movida a partir de un corte horizontal y en el segundo caso solo se mueve la espera. Después de cada movimiento, se almacena la situación en el búfer de acumulación y al final se vuelca el contenido de éste, dotando a la imagen con una sensación de movimiento en los lugares donde antes estuvo la imagen.

30

5 – Otras operaciones de color A parte de admitir las fusiones, la niebla y el búfer de acumulación, OpenGL también admite otros medios de ajuste de valores y fragmentos del color cuando se describen en el búfer de color.

5.1 – Máscaras de color Una vez calculado un color final y antes de escribirlo en el búfer de color, OpenGl permite enmascarar uno o más canales del color con la siguiente función: void glColorMask(GLboolean rojo, GLboolean verde, GLboolean azul, GLboolean alpha);

Cada parámetro de la función se corresponde con un canal. El paso de GL_TRUE permite la escritura en ese canal, mientras que GL_FALSE evita la escritura.

5.2 – Operaciones de color lógicas La ejecución de operaciones lógicas entre los colores de origen y destino se permiten en muchos gráficos y APIs 2D. OpenGL también admite este tipo de operaciones 2D mediante la siguiente función: void glLogicOp(GLenum op);

Los modos de operación lógica que puede recibir como parámetros la función anterior son los siguientes:

Valor del argumento

Operación

GL_CLEAR

0

AL_AND

S & D

31

GL_AND_REVERSE

S & -D

GL_COPY

S

GL_AND_INVERTED

-S & D

NOOP

D

XOR

S XOR D

OR

S | D

NOR

-(S | D)

GL_EQUIV

-(S XOR D)

GL_INVENT

-D

GL_OR_REVERSE

S | -D

GL_COPY_INVERTED

-S

GL_OR_INVERTED

-S | D

GL_NAND

-(S & D)

SET

Todo 1

Tabla 11 – Operaciones de color lógicas (glLogicOp)

La operación lógica se encuentra desactivada de forma predeterminada y se controla con las siguientes funciones: glEnable(GL_COLOR_LOGIC_OP); para activar la operación lógica. glDisable(GL_COLOR_LOGIC_OP); para desactivarla.

5.3 – Prueba Alpha La prueba alpha permite indicar que se descarte fragmentos cuyo valor de alpha falle en la prueba de comparación alpha. Los fragmentos que se descarten no se escriben en los búferes de color, profundidad, plantillas o acumulación.

Esta opción es muy útil para mejorar el rendimiento al descartar valores y permite elementos del búfer de profundidad que pueden no ser visibles en el búfer de color por tener un valor de alpha muy bajo.

32

La activación y desactivación de la prueba alpha se realiza con las siguientes funciones: glEnable(GL_ALPHA_TEST); para activar la prueba alpha. glDisable(GL_ALPHA_TEST); para desactivarla.

El valor de la prueba alpha y de la función de comparación se especifican con la siguiente función: void glAlphaFunc(GLenum tipo, GLclampf ref);

El valor de referencia ref se ajusta al rango 0.0f a 1.0f. La función de comparación se especifica con los siguientes valores:

Tipo GL_NEVER GL_LESS GL_LEQUAL GL_EQUAL

Significado Nunca pasa. Pasa si el fragmento es menor que el valor de referencia. Pasa si el fragmento es menor o igual que el valor de referencia. Pasa si el fragmento es igual que el valor de referencia.

GL_GREATER

Pasa si el fragmento es mayor que el valor de referencia.

GL_NOTEQUAL

Pasa si el fragmento es distinto que el valor de referencia.

GL_GEQUAL

Pasa si el fragmento es mayor o igual que el valor de referencia.

GL_ALWAYS

Pasa siempre. Tabla 12 – Prueba Alpha (glAlphaFunc)

5.4 – Tramado El tramado es una operación que permite mostrar un sistema con un pequeño número de colores discretos para simular la presentación de un rango de colores mucho más amplio. Por ejemplo, se puede simular un color gris mostrando una mezcla de puntos blancos y negros.

Esta técnica es útil para mostrar sistemas que sólo admiten 8 o 16 bits de información de color.

33

El tramado se encuentra activado de forma predeterminada, y se puede controlar con las siguientes funciones: glEnable(GL_DITHER); para activar el tramado. glDisable(GL_DITHER); para desactivarlo.

En sistemas de presentación con una mayor resolución de color puede que no se necesite el tramado y puede desactivarse para conseguir ahorros de rendimiento considerables.

34

Conclusiones En Opengl podemos conseguir efectos espectaculares y dotar de mayor realismo a las imágenes usando las mezclas y las nieblas y con el suavizado eliminar la apariencia cuadrática (lo que también hace más reales las imágenes) Para aplicar estas herramientas debemos tener en cuenta: Las mezclas están sólo habilitadas en modo RGBA aunque de forma excepcional el antiescalonado se puede realizar en modo indexado definiendo correctamente una rampa de color por la que desplazarnos de forma suave Podemos

seleccionar

la

implementación

para

los

efectos

de

antiescalonado y nieblas; no siempre es aconsejable utilizar el mejor algoritmo, ya que puede afectar seriamente al rendimiento de la animación. Se debe activar la comprobación de profundidad para no representar las partes ocultas y que estas no afecten a las mezclas y a las nieblas No todas las implementaciones de Opengl permiten la realización de todos los efectos y la utilización de algunos efectos desactiva otros.

35

Bibliografía Richard S. Wright, Benjamín Lipchak, OpenGL Superbible. Ediciones Anaya Multimedia (Grupo Anaya S.A.), 2005.

Mason Woo, Jackie Neider, Tom Davis, OpenGL Programming Guide, 2nd Edition, Addison-Wesley Publishing Company, 1997.

Silicon Graphics, Inc., OpenGL Reference Manual, The Official Reference Document for OpenGL, Release1, Addison-Wesley Publishing Company, 1994.

Alan Oursland, Using OpenGL in Visual C++, Interface Technologies, Inc., 2000.

http://www.opengl.org

http://ponton.dcs.fi.uva.es/web/programacion/opengl/index2.html

http://www.sgi.com/products/software/opengl/examples/index.html

36

Related Documents

Lecc 11
December 2019 18
Lecc 6
December 2019 16
Lecc 12
December 2019 17
Lecc 9
December 2019 15
Lecc 3
December 2019 7
Lecc 13
December 2019 9

More Documents from "maria"