06.05.2013 Views

colores y sombras

colores y sombras

colores y sombras

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Universidad & Salamanca<br />

Ingeniería Superior Informática.<br />

TEMA 7<br />

Colores y Sombras<br />

Informática Gráfica<br />

José María Corral Martín<br />

Álvaro F. García Sánchez


Colores y <strong>sombras</strong> 2<br />

7.1. Introducción................................................................................................. 4<br />

7.2. ¿Qué es el color? ........................................................................................ 4<br />

7.2.1. La luz como Onda................................................................................. 5<br />

7.2.2. La luz como partícula............................................................................ 6<br />

7.2.3. Dualidad onda - partícula...................................................................... 6<br />

7.3. Percepción del color.................................................................................... 6<br />

7.3.1. Características psicológicas del color................................................... 7<br />

7.4. Dispositivos de visualización ....................................................................... 9<br />

7.4.1. TRC ...................................................................................................... 9<br />

7.4.1.1. Análisis de los tiempos involucrados............................................ 10<br />

7.4.1.2. Exploración de línea..................................................................... 10<br />

7.4.1.3. Sincronizaciones horizontales y verticales ................................... 11<br />

7.4.2. LCD..................................................................................................... 12<br />

7.4.2.1. Funcionamiento............................................................................ 14<br />

7.4.2.2 LCD de texto ................................................................................. 14<br />

7.4.2.3. TFT............................................................................................... 14<br />

7.4.3. Pantalla de plasma ............................................................................. 15<br />

7.5. El monitor vs. El ojo................................................................................... 16<br />

7.6. Profundidad del color ................................................................................ 16<br />

7.6.1. Color de 1-bit ...................................................................................... 16<br />

7.6.2. Color de 4-bits .................................................................................... 17<br />

7.6.3. Color de 8-bits .................................................................................... 18<br />

7.6.4. Color de 24-bits .................................................................................. 18<br />

7.7. Modelos de color ....................................................................................... 19<br />

7.7.1. Modelo de color XYZ .......................................................................... 19<br />

7.7.1.1. Espacio de color CIE.................................................................... 19<br />

7.7.1.1.1. Diagrama de cromaticidad CIE.............................................. 20<br />

7.7.1.1.2. Gama de <strong>colores</strong> ................................................................... 20<br />

7.7.2. El modelo de color RGB ..................................................................... 21<br />

7.7.3. El modelo de color CMY (Cyan, Magenta, Amarillo)........................... 23<br />

7.7.4. El modelo de color YUV...................................................................... 24<br />

7.7.5. El modelo de color YIQ ....................................................................... 24<br />

7.7.6. El modelo de color HSI ....................................................................... 25<br />

7.7.7. El sistema HLS (Hue, Saturation and Luminance).............................. 26<br />

7.7.8. Modelo HSV........................................................................................ 26<br />

7.8. Colores en OpenGL .................................................................................. 28<br />

7.8.1. Utilización de <strong>colores</strong> con OpenGL..................................................... 28<br />

7.8.2. Modelo de color RGBA ....................................................................... 30<br />

7.8.3. Modelo de color indexado................................................................... 36<br />

7.8.4. Modelo de color RGBA vs. Modelo de color Indexado........................ 48<br />

7.8.5. Ocultaciones ....................................................................................... 49<br />

7.8.5.1. Algoritmo de las caras de detrás.................................................. 49<br />

7.8.5.2 Algoritmo del Z-buffer.................................................................... 50<br />

7.8.5.3. Combinando ambos algoritmos.................................................... 51<br />

7.8.6. El color de los materiales.................................................................... 52<br />

7.9. Sombras.................................................................................................... 58<br />

7.9.1 Efecto falloff (Distance falloff) .............................................................. 60<br />

7.9.2 Sombreado .......................................................................................... 61<br />

7.9.3 Tipos de sombreado ............................................................................ 62<br />

7.9.3.1 Sombreado plano (Flat Shading)................................................... 62


Colores y <strong>sombras</strong> 3<br />

7.9.3.2 Sombreado de Gouraud................................................................ 63<br />

7.9.3.3 Sombreado de Phong ................................................................... 65<br />

7.9.3.4 Sombreado Blinn–Phong .............................................................. 67<br />

7.9.4 Sombreado en OpenGL....................................................................... 68<br />

7.9.4.1 Sombreado Plano (Flat) ................................................................ 68<br />

7.9.4.2 Sombreado Interpolativo y Gouraud.............................................. 70<br />

7.9.4.3 Stencil Buffer................................................................................. 71<br />

7.9.4.4 Buffer de Profundidad o Z buffer ................................................... 75<br />

7.9.5. Volúmenes de <strong>sombras</strong> ...................................................................... 76<br />

7.9.5.1 Paso de profundidad (Depth pass)................................................ 78<br />

7.9.5.2 Error de Profundidad (Depth fail)................................................... 78<br />

7.9.7.3 OR exclusivo ................................................................................ 78<br />

7.10 Fusión (Dithering)..................................................................................... 78<br />

7.11. Creación de Paletas de Ventana............................................................. 80<br />

7.11.1 Arbitraje de paletas............................................................................ 80<br />

7.11.2. Creación de una paleta..................................................................... 82<br />

7.11.3 Estructura de la paleta....................................................................... 82<br />

7.11.4 Destrucción de una paleta. ............................................................... 85<br />

7.12 Conclusión................................................................................................ 87<br />

7.13 Otras funciones para luces y <strong>sombras</strong> ..................................................... 87<br />

glAccum........................................................................................................ 87<br />

glColorMask.................................................................................................. 88<br />

glDrawBuffer................................................................................................. 88<br />

glFog............................................................................................................. 89<br />

glIndexMask.................................................................................................. 90<br />

glIsEnabled................................................................................................... 90<br />

glLogicOp...................................................................................................... 90<br />

glPolygonMode ............................................................................................. 91<br />

7.14 Bibliografia................................................................................................ 92<br />

7.15 Enlaces de interés.................................................................................... 96


Colores y <strong>sombras</strong> 4<br />

7.1. Introducción<br />

Los despliegues realistas de objetos se obtienen generando<br />

proyecciones en perspectiva con superficies ocultas eliminadas y después<br />

aplicando modelos de sombreado y color a las superficies visibles. Un modelo<br />

de sombreado se utiliza para calcular la intensidad de luz que debe observarse<br />

cuando se visualiza una superficie. Estos cálculos de intensidad se basan en<br />

las propiedades ópticas de las superficies, las posiciones relativas de las<br />

superficies y su orientación con respecto a las fuentes de luz.<br />

En este tema se introducirán los conceptos de color y sombreado,<br />

algunos de los modelos más utilizados actualmente para su representación<br />

para posteriormente mostrar todo lo necesario para la utilización del color y del<br />

sombreado en escenas con OpenGL con multitud de ejemplos sencillos.<br />

7.2. ¿Qué es el color?<br />

El color de un objeto percibido por la vista se debe a las propiedades<br />

inherentes al mismo, de reflejar, seleccionar y absorber determinados rayos de<br />

los que integran la luz blanca. La luz solar es un fenómeno vibratorio de<br />

innumerables variaciones en cuanto a longitud de onda. Al pasar la luz por un<br />

prisma se ve que está compuesta por un sinnúmero de <strong>colores</strong>; los<br />

fundamentales son: violeta (que corresponde a la vibración más pequeña y<br />

simple), añil, azul, verde, amarilla, naranja y rojo. El color negro resulta de la<br />

ausencia de toda impresión luminosa.<br />

Diccionario Enciclopédico Abreviado Espasa-Calpe.S.A<br />

Según la definición el color de un objeto se debe a la combinación de las<br />

distintas longitudes de onda que el objeto refleja, así por ejemplo un objeto rojo<br />

sería aquel que absorbiese todos los rayos que componen la luz blanca menos<br />

el de menor longitud de onda (el rojo).<br />

El color en las artes es el medio más valioso para que una obra<br />

transmita las mismas sensaciones que el artista experimenta frente a la escena<br />

o motivo original; utilizando el color adecuadamente y con conocimiento de su<br />

naturaleza y efectos será posible expresar la alegría o tristeza, la luminosidad u<br />

oscuridad, tranquilidad o la exaltación, etc.<br />

El color en la informática gráfica se desenvuelve de la misma manera<br />

que en el arte de la pintura, aunque en su actuación va mucho mas allá porque<br />

su fin es especialmente especifico, puede servir para favorecer, destacar,<br />

disimular y aún ocultar, para crear una sensación excitante o tranquila, para<br />

denotar temperatura, tamaño, profundidad o peso y como la música, puede ser<br />

utilizada deliberadamente para despertar un sentimiento.<br />

El color tiene su propia técnica y está sometido a ciertas leyes,<br />

conociéndolas será posible dominar el arte de la armonización, conocer los<br />

medios útiles que sirven para evitar la monotonía en una combinación


Colores y <strong>sombras</strong> 5<br />

cromática, estimular la facultad del gusto selectivo y afirmar la sensibilidad,<br />

desconociéndolas es posible trastornar y anular las percepciones deseadas.<br />

7.2.1. La luz como Onda<br />

Lo que percibimos como color es una banda de frecuencias del espectro<br />

electromagnético, otras bandas de frecuencias incluidas en el espectro son las<br />

ondas de radio, infrarrojos, etc. Cada<br />

frecuencia contenida en el espectro<br />

visible se corresponde con un color<br />

distinto.<br />

El espectro visible abarca<br />

desde los 4.3*10 14 Hz (rojo) hasta los<br />

7.5 * 10 14 Figura 1 - Estructura de una onda<br />

Hz (violeta). En este<br />

intervalo de frecuencias el ojo humano distingue aproximadamente unos<br />

400.000 <strong>colores</strong> diferentes (esta gama se extiende desde el rojo pasando por el<br />

anaranjado y amarillo en el extremo de las bajas frecuencias hasta los azules y<br />

violetas de las altas frecuencias).<br />

Figura 2 - Espectro Electromagnético<br />

Lo que se designa como luz blanca es la impresión creada por el<br />

conjunto de radiaciones que son visibles por nuestro ojo; la luz blanca cuando<br />

es descompuesta produce el fenómeno de arco iris, estos son los que<br />

llamamos <strong>colores</strong>, el conjunto de estos, o franja continua de longitudes de onda<br />

creada por la luz al descomponerse, constituye el espectro.<br />

Describimos los <strong>colores</strong> en función de su frecuencia o de su longitud de<br />

onda dado que la luz es una onda electromagnética (C = λ*f). La longitud de<br />

onda en el espectro visible varía desde los 720 nanómetros del rojo a los 390<br />

nanómetros del violeta.<br />

Cualquier fuente de luz (sol, foco de luz ...) emite todas las<br />

frecuencias en el intervalo visible para producir la luz blanca.


Colores y <strong>sombras</strong> 6<br />

Un objeto sobre el que incide luz blanca absorberá algunas frecuencias<br />

y reflejará otras. La combinación de éstas últimas determinará el color del<br />

objeto. Describimos el objeto como violeta si predominan las altas frecuencias<br />

en la luz reflejada, es decir, la luz tiene una frecuencia dominante o longitud<br />

de onda dominante en el extremo violeta del espectro. La frecuencia<br />

dominante se denomina color o matiz de la luz.<br />

7.2.2. La luz como partícula<br />

La luz puede ser descrita como una onda oscilante, pero también puede<br />

ser considerada como un haz de partículas viajando a altas velocidades (3,0 x<br />

10 8 m/s). Los haces de luz están compuestos por partículas denominadas<br />

fotones.<br />

A nivel físico, los llamados <strong>colores</strong> compuestos, están hechos de<br />

diversas cantidades de de <strong>colores</strong> “puros” encontrados en el espectro.<br />

Al iluminar cualquier objeto dado con una fuente de luz es golpeado por<br />

“billones y billones” de fotones, o pequeñas partículas de luz, algunos de ellos<br />

serán absorbidos y otros reflejados. La reflexión de la luz sobre un objeto<br />

depende del tipo, distribución y cantidad de átomos que contenga.<br />

Cada uno de esos fotones es también una onda, con su correspondiente<br />

longitud de onda y por tanto un color específico en el espectro.<br />

7.2.3. Dualidad onda - partícula<br />

La frecuencia (υ) de la teoría de las ondas se puede relacionar con la<br />

teoría del fotón (E) de la teoría de la partícula a través de la ecuación de<br />

Planck:<br />

E = h υ<br />

donde h es la constante de planck (factor de proporcionalidad = 6,63 x<br />

10 -34 (Js)).<br />

La frecuencia (υ) de una determinada onda es inversamente<br />

proporcional a su longitud de onda.<br />

7.3. Percepción del color<br />

El color es la impresión producida al incidir en la retina los rayos<br />

luminosos difundidos o reflejados por los cuerpos. El ojo humano es capaz de<br />

captar las variaciones de la longitud de onda del espectro electromagnético<br />

visualizándolo como diferentes <strong>colores</strong>, desde el violeta hasta el rojo.


Colores y <strong>sombras</strong> 7<br />

Este fenómeno se debe al aspecto físico de la radiación, el ojo humano<br />

que actúa como sensor y el cerebro que es capaz de percibir, diferenciar e<br />

interpretar las imágenes que<br />

conforman este espectro.<br />

La retina del ojo, a<br />

través de una estructura<br />

formada por unos elementos<br />

denominados bastones<br />

(concentrados en los lados de<br />

la retina) y conos<br />

(concentrados en el centro),<br />

tiene la capacidad para<br />

discernir los <strong>colores</strong>, la<br />

forma, los detalles y la<br />

posición de los objetos.<br />

Los conos están especializados en la visión del color, así unos ven<br />

solamente el azul y el violeta, otros el verde y el amarillo y otros el rojo y el<br />

naranja. Además, es capaz de adaptarse a las diferentes cantidades de luz y al<br />

brillo de las escenas y discernir e identificar los diferentes <strong>colores</strong>.<br />

Los bastones al contrario que los conos requieren muy poca luz, lo que<br />

los hace muy adecuados para la visión nocturna, sin embargo, no son capaces<br />

de discernir los <strong>colores</strong>.<br />

Los fotones penetran en nuestro ojo enfocándose en la retina, ésta actúa<br />

como una película fotográfica. Las células de la retina son excitadas por los<br />

fotones, lo cual provoca un estímulo que es transmitido por las neuronas al<br />

cerebro.<br />

El cerebro interpreta esta información como luz y color. El nivel de<br />

excitación es proporcional al número de fotones que llegan a la retina.<br />

7.3.1. Características psicológicas del color<br />

Figura 3 - Sección de un ojo humano<br />

Necesitamos otras propiedades, además de la frecuencia, para<br />

caracterizar nuestra percepción de la luz.<br />

La cromaticidad hace referencia al conjunto de variables del color que<br />

se utilizan normalmente para describir las diferentes propiedades de una fuente<br />

de luz.<br />

- El matiz es el croma de un color y depende de la longitud de onda<br />

dominante. Es la cualidad que permite clasificar a los <strong>colores</strong> como<br />

amarillo, rojo, violeta, etc. El matiz se mide de acuerdo con la proximidad<br />

que tiene un color con relación a otro que se halle próximo en el círculo<br />

cromático; por ejemplo: verde amarillento, naranja rojizo, azul violáceo,<br />

etcétera


Colores y <strong>sombras</strong> 8<br />

Figura 4 – Matiz<br />

- Valor o luminosidad indica las luminancias de un color; es decir, el<br />

grado de claridad u oscuridad que posee como cualidad intrínseca.<br />

Dentro del círculo cromático, el amarillo es el color de mayor luminancia<br />

y el violeta el de menor. Independientemente de los valores propios de<br />

los <strong>colores</strong>, éstos se pueden alterar mediante la adición de blanco que<br />

lleva el color a claves o valores de luminancia más altos, o de negro que<br />

los disminuye.<br />

- El tono es la resultante de la mezcla de los <strong>colores</strong> con blanco o<br />

negro y tiene referencia de valor y de matiz. Por ejemplo, el amarillo<br />

mezclado con negro modifica su matiz hacia el verde y se oscurece.<br />

Figura 5 - Tono<br />

- La saturación se refiere al grado de pureza de un color y se mide<br />

con relación al gris. Los <strong>colores</strong> muy saturados poseen mayor grado de<br />

pureza y se presentan con más intensidad luminosa en relación con su<br />

valor. Los <strong>colores</strong> con menor saturación se muestran más agrisados,<br />

con mayor cantidad de impurezas y con menor intensidad luminosa.<br />

Figura 6 - Saturación<br />

Se utilizan modelos de color con combinaciones de luz en términos de<br />

frecuencia dominante haciendo uso de 3 <strong>colores</strong> para obtener una gama amplia<br />

de <strong>colores</strong>. Esto se suele denominar gama de color del modelo. Los tres<br />

<strong>colores</strong> utilizados en el modelo se denominan <strong>colores</strong> primarios.<br />

Ningún conjunto de <strong>colores</strong> primarios describe todas las frecuencias del<br />

espectro visible. Agregando <strong>colores</strong> primarios aumentamos el número de<br />

posibles <strong>colores</strong> pero harían falta un número infinito de <strong>colores</strong> para poder<br />

representar todos los posibles <strong>colores</strong>. Para muchos fines con los tres <strong>colores</strong>


Colores y <strong>sombras</strong> 9<br />

primarios es suficiente, sino se puede representar un color concreto se pueden<br />

utilizar métodos extendidos.<br />

Cuando se proyectan juntas luces rojas, verdes y azules, obtenemos el<br />

blanco.<br />

Los <strong>colores</strong> secundarios se obtienen de la mezcla de los <strong>colores</strong><br />

primarios.<br />

Figura 7 - Colores Primarios<br />

7.4. Dispositivos de visualización<br />

7.4.1. TRC<br />

Figura 8 - Colores Secundarios<br />

Un monitor para mostrar una imagen utiliza un tubo de rayos catódicos<br />

(TRC) cuyo frente se "ilumina" con un cañón de electrones localizado en la<br />

parte posterior del tubo, el cual dispara un haz de electrones muy concentrado<br />

que al impactar con el material sensible del frente del tubo lo excita iluminando<br />

los puntos que componen la imagen.<br />

La forma en<br />

que el haz "barre" la<br />

pantalla para<br />

desplegar una<br />

imagen se denomina<br />

deflexión. Ésta se<br />

realiza excitando<br />

convenientemente un<br />

juego de bobinas<br />

(def. Horizontal y def.<br />

Vertical) que están<br />

colocadas de forma<br />

muy precisa en el<br />

cuello del TRC. El<br />

campo magnético que<br />

Figura 9 - Tubo de rayos catódicos<br />

generan al ser<br />

excitadas desvía el haz para conseguir que apunten al frente del tubo a la<br />

posición deseada.<br />

Un monitor no forma la imagen, ésta se procesa y forma en la placa de<br />

video del ordenador. Después se almacena en la memoria de video y se envía<br />

esta información (señales de video y sincronización) al monitor. Éste la toma y<br />

la ordena para poder mostrarla, para ello se utilizan dos señales de


Colores y <strong>sombras</strong> 10<br />

sincronización de eventos consiguiendo que la imagen se muestre de forma<br />

coherente y ordenada. La señales de sincronismo horizontal y vertical se<br />

generan en la placa de video y sus características dependen del modo de video<br />

elegido (resolución).<br />

7.4.1.1. Análisis de los tiempos involucrados<br />

Tiempo activo horizontal<br />

Para desplegar una imagen, el haz apunta a la esquina superiorizquierda<br />

de la pantalla y se mueve horizontalmente hasta el derecho de la<br />

misma. El tiempo que emplea el haz para desplazarse del lado izquierdo al<br />

derecho se denomina "tiempo activo horizontal".<br />

Retardo Horizontal o tiempo de borrado<br />

Es el tiempo utilizado en el regreso del haz a la izquierda de la pantalla<br />

cuando éste ha alcanzado el lado derecho de la misma.<br />

Tiempo Total horizontal<br />

El haz cumple un ciclo horizontal completo cuando, empezando en el<br />

borde izquierdo de la pantalla va hacia el lado derecho, y regresa atrás de<br />

nuevo. Este “tiempo total horizontal” se obtiene sumando los tiempos de<br />

Retardo Horizontal y Activo Horizontal<br />

Velocidad de Refresco Horizontal<br />

Dependiendo de la velocidad con la que el monitor puede trabajar,<br />

pueden ocurrir cada segundo unos 20.000 a 80.000 ciclos horizontales . El<br />

número de ciclos horizontales por segundo es denominado Refresco Horizontal<br />

y normalmente está en KHz.<br />

Tiempo Total Horizontal<br />

Cuando trabajamos con la velocidad horizontal de un monitor<br />

generalmente utilizamos el Refresco Horizontal. Sin embargo, al tratar con los<br />

ciclos horizontales de un monitor específico, normalmente utilizaremos el<br />

tiempo real de cada ciclo horizontal. El ciclo horizontal de un monitor es la<br />

suma de los tiempos real horizontal y tiempo de borrado o retrazo.<br />

7.4.1.2. Exploración de línea<br />

Para desplegar una imagen completa no sólo hay que desplegar el haz<br />

“de izquierda a derecha” de la pantalla, es decir, horizontalmente, sino también<br />

“de arriba abajo”, es decir, verticalmente. Cada recorrido horizontal del haz se<br />

llama exploración de línea "scanline”.


Colores y <strong>sombras</strong> 11<br />

Tiempo activo vertical<br />

Es el tiempo total que necesita el monitor para desplegar todas las líneas<br />

horizontales. Dependiendo de la resolución vertical de un monitor, una imagen<br />

en la pantalla puede componerse de 320 a 1600 líneas horizontales.<br />

Retrazo o borrado vertical o tiempo de retardo<br />

Es el tiempo que necesita el haz para una vez que ha alcanzado la<br />

esquina inferior derecha de la pantalla retornar rápidamente a la parte superior<br />

izquierda de la misma.<br />

Tiempo Total Vertical<br />

Es el tiempo que utiliza el haz para "barrer" desde la parte superior hasta<br />

la inferior de la pantalla y volver a la esquina superior-izquierda.<br />

Tiempo Total Vertical = Tiempo activo Vertical + Tiempo de Retrazo<br />

Vertical<br />

Hz.<br />

Velocidad de Refresco Vertical o refresco vertical de un monitor<br />

Es el número de ciclos verticales completados por segundo medido en<br />

Raster: Es el ciclo completo de formación de un cuadro de imagen<br />

7.4.1.3. Sincronizaciones horizontales y verticales<br />

Señal de sincronización vertical<br />

Utilizando esta señal el monitor controla el regreso del haz desde la<br />

esquina inferior-derecha a la esquina superior-izquierda<br />

Señal de sincronización Horizontal<br />

Con esta señal el monitor controla el regreso del haz desde el lado<br />

derecho al izquierdo<br />

Pulso de Sincronización horizontal y posición de la imagen<br />

Durante el tiempo de retardo horizontal el monitor recibe el pulso de<br />

sincronización horizontal. El tiempo entre el extremo del tiempo activo<br />

horizontal y la salida del pulso de la sincronización horizontal se denomina el<br />

Porche Delantero Horizontal.<br />

El tiempo durante el cual el pulso de sincronización horizontal<br />

permanece activo, se denomina Ancho de Sincronización Horizontal.<br />

Después de recibir el pulso de la sincronización horizontal, el monitor<br />

devuelve el haz al lado izquierdo de la pantalla. El periodo de tiempo entre el<br />

extremo del pulso de la Sincronización Horizontal y el comienzo del próximo<br />

tiempo activo horizontal es denominado Porche Trasero Horizontal.


Colores y <strong>sombras</strong> 12<br />

Modificando la posición del pulso de la sincronización horizontal respecto<br />

al tiempo de retrazo horizontal se ajusta la posición de la imagen en la pantalla<br />

a la derecha o izquierda.<br />

Figura 10 - Pulso de sincronización horizontal<br />

Pulso de Sincronización vertical y posición de imagen<br />

Durante el tiempo de retrazo vertical el monitor recibe el pulso de la<br />

sincronización vertical. El tiempo entre el extremo del tiempo activo vertical y la<br />

salida del pulso de la sincronización vertical se llama el Porche Delantero<br />

Vertical.<br />

El tiempo durante el cual el pulso de la sincronización vertical<br />

permanece activo se denomina la Anchura de la Sincronización Vertical.<br />

Después de recibir el pulso de la sincronización vertical, el monitor devuelve el<br />

haz al tope de la pantalla.<br />

El periodo de tiempo entre el extremo del pulso de la Sincronización<br />

Vertical y la salida del próximo tiempo activo vertical es el Porche Trasero<br />

Vertical.<br />

Modificando la posición del pulso de la sincronización vertical respecto al<br />

tiempo de retardo vertical se ajusta la situación de la imagen en la pantalla<br />

arriba o abajo.<br />

7.4.2. LCD<br />

LCD (Liquid Crystal Display) son las siglas en inglés de Pantalla de<br />

Cristal Líquido, dispositivo inventado por Jack Janning, quien fue empleado de<br />

NCR.<br />

Se trata de un sistema eléctrico de presentación de datos formado por 2<br />

capas conductoras transparentes y en medio un material especial cristalino<br />

(cristal líquido) que tienen la capacidad de orientar la luz a su paso.


Colores y <strong>sombras</strong> 13<br />

Cuando la<br />

corriente circula<br />

entre los<br />

electrodos<br />

transparentes con<br />

la forma a<br />

representar (por<br />

ejemplo, un<br />

segmento de un<br />

número) el<br />

material cristalino<br />

se reorienta<br />

alterando su<br />

transparencia.<br />

Figura 11 - LCD<br />

El material base de un LCD lo constituye el cristal líquido, el cual exhibe<br />

un comportamiento similar al de los líquidos y unas propiedades físicas<br />

anisotrópicas similares a las de los sólidos cristalinos. Las moléculas de cristal<br />

líquido poseen una forma alargada y son más o menos paralelas entre sí en la<br />

fase cristalina. Según la disposición molecular y su ordenamiento, se clasifican<br />

en tres tipos: nemáticos, esméticos y colestéricos. La mayoría de cristales<br />

responden con facilidad a los campos eléctricos, exhibiendo distintas<br />

propiedades ópticas en presencia o ausencia del campo. El tipo más común de<br />

visualizador LCD es, con mucho, el denominado nemático de torsión, término<br />

que indica que sus moléculas en su estado desactivado presentan una<br />

disposición en espiral. La polarización o no de la luz que circula por el interior<br />

de la estructura, mediante la aplicación o no de un campo eléctrico exterior,<br />

permite la activación de una serie de segmentos transparentes, los cuales<br />

rodean al cristal líquido. Según sus características ópticas, pueden también<br />

clasificarse como: reflectivos, transmisivos y transreflectivos.<br />

Las pantallas LCD se encuentran en multitud de dispositivos industriales<br />

y de consumo: máquinas expendedoras, electrodomésticos, equipos de<br />

telecomunicaciones, computadoras, etc. Todos estos dispositivos utilizan<br />

pantallas fabricadas por terceros de una manera más o menos estandarizada.<br />

Cada LCD se compone de una pequeña placa integrada que consta de:<br />

• La propia pantalla LCD.<br />

• Un microchip controlador.<br />

• Una pequeña memoria que contiene una tabla de caracteres.<br />

• Un interfaz de contactos eléctricos, para conexión externa.<br />

• Opcionalmente, una luz trasera para iluminar la pantalla.<br />

El controlador simplifica el uso del LCD proporcionando una serie de<br />

funciones básicas que se invocan mediante el interfaz eléctrico, destacando:<br />

• La escritura de caracteres en la pantalla.<br />

• El posicionado de un cursor parpadeante, si se desea.<br />

• El desplazamiento horizontal de los caracteres de la pantalla<br />

(scrolling).


Colores y <strong>sombras</strong> 14<br />

La memoria implementa un mapa de bits para cada carácter de un juego<br />

de caracteres, es decir, cada octeto de esta memoria describe los puntitos o<br />

píxel que deben iluminarse para representar un carácter en la pantalla.<br />

Generalmente, se pueden definir caracteres a medida modificando el contenido<br />

de esta memoria. Así, es posible mostrar símbolos que no están originalmente<br />

contemplados en el juego de caracteres.<br />

El interfaz de contactos eléctricos suele ser de tipo paralelo, donde<br />

varias señales eléctricas simultáneas indican la función que debe ejecutar el<br />

controlador junto con sus parámetros. Por tanto, se requiere cierta<br />

sincronización entre estas señales eléctricas.<br />

La luz trasera facilita la lectura de la pantalla LCD en cualquier condición<br />

de iluminación ambiental.<br />

Existen dos tipos de pantallas LCD en el mercado: pantallas de texto y<br />

pantallas gráficas.<br />

7.4.2.1. Funcionamiento<br />

El funcionamiento de estas pantallas se fundamenta en sustancias que<br />

comparten las propiedades de sólidos y líquidos a la vez. Cuando un rayo de<br />

luz atraviesa una partícula de estas sustancias tiene necesariamente que<br />

seguir el espacio vacío que hay entre sus moléculas como lo haría atravesar un<br />

cristal sólido pero a cada una de estas partículas se le puede aplicar una<br />

corriente eléctrica que cambie su polarización dejando pasar a la luz o no.<br />

Una pantalla LCD esta formada por 2 filtros polarizados colocados<br />

perpendicularmente de manera que al aplicar una corriente eléctrica al segundo<br />

de ellos dejaremos pasar o no la luz que ha atravesado el primero de ellos.<br />

Para conseguir el color es necesario aplicar tres filtros más para cada uno de<br />

los <strong>colores</strong> básicos rojo, verde y azul y para la reproducción de varias<br />

tonalidades de color se deben aplicar diferentes niveles de brillo intermedios<br />

entre luz y no luz lo, cual consigue con variaciones en el voltaje que se aplicaba<br />

los filtros.<br />

7.4.2.2 LCD de texto<br />

Los LCD de texto son los más baratos y simples de utilizar. Solamente<br />

permiten visualizar mensajes cortos de texto. Existen algunos modelos<br />

estandarizados en la industria, en función de su tamaño medido en número de<br />

líneas y columnas de texto. Existen modelos de una, dos y cuatro filas<br />

únicamente. El número de columnas típico es de ocho, dieciséis, veinte y<br />

cuarenta caracteres.<br />

7.4.2.3. TFT<br />

TFT o Thin Film Transistor (Transistor de Película Fina) es un tipo<br />

especial de transistor de efecto campo construido depositando finas películas<br />

sobre contactos metálicos, capa activa semiconductora y capa dieléctrica.


Colores y <strong>sombras</strong> 15<br />

La aplicación más conocida de los TFT son las pantallas de visualización<br />

planas de LCD, en las cuales cada píxel se controla mediante uno a cuatro<br />

transistores. La tecnología de TFT proporciona la mejor resolución de todas las<br />

técnicas flat-panel, pero es también la más costosa. Las pantallas de TFT a<br />

veces se llaman LCDs de matriz activa.<br />

Opera de forma individual con cada píxel, es decir, es direccionamiento<br />

directo o de matriz activa. esto se consigue mediante una delgada capa de<br />

transistores que controlan de forma individual cada píxel obteniendo mejores<br />

tiempos de respuesta al no ser necesario el barrido completo de la pantalla ya<br />

que el tiempo de de excitación de un píxel es menor que el tiempo de barrido<br />

de la pantalla consiguiendo imágenes más nítidas y sin parpadeos.<br />

7.4.3. Pantalla de plasma<br />

Una pantalla de plasma es una pantalla plana en la cual la luz se crea<br />

por la excitación de sustancias<br />

fosforecentes mediante una<br />

descarga de plasma entre dos<br />

pantallas planas de vidrio. La<br />

descarga de gas no contiene<br />

mercurio (como en la luz de fondo<br />

de las pantallas de LCD); una<br />

mezcla de gases nobles (neón y<br />

xenón) es utilizada en su lugar. Esta<br />

mezcla de gas es inerte y totalmente<br />

inofensiva.<br />

La pantalla de plasma fue<br />

inventada en la Universidad de Illinois<br />

en Urbana-Champaign por Donald L.<br />

Bitzer y H. Gene Slottow en 1964 para<br />

Figura 12 – Funcionamiento de una<br />

pantalla de plasma<br />

el sistema informático PLATO. Los paneles originales eran monocromáticos.<br />

Desde 1975, Larry Weber, de la Universidad de Illinois en Urbana-<br />

Champaign, intentó crear una pantalla de plasma de color, consiguiéndolo<br />

finalmente en 1995.<br />

El mayor brillo y ángulo de visión de las pantallas de plasma actuales ha<br />

provocado que estas pantallas sean cada vez más populares.<br />

El plasma consiste en una sustancia eléctrica neutra con una lata de<br />

ionización compuesta por iones, electrones y partículas neutras. Básicamente<br />

el plasma es un mar de electrones e iones que conduce de manera excelente<br />

la electricidad. Si se aplica suficiente calor los electrones se separan de sus<br />

núcleos.


Colores y <strong>sombras</strong> 16<br />

Una pantalla de plasma se compone de una matriz de celdas conocidas<br />

como píxeles, que se componen a su vez de tres sub-píxeles, que<br />

corresponden a los <strong>colores</strong> rojo, verde y azul.<br />

El gas en estado de plasma reacciona con el fósforo de cada sub-píxel<br />

para producir luz coloreada (roja, verde o azul). Estos fósforos son los mismos<br />

que se utilizan en los tubos de rayos catódicos de los televisores y monitores<br />

convencionales. Cada sub-píxel está controlado individualmente por un<br />

procesador y se pueden producir más de 16 millones de <strong>colores</strong> diferentes.<br />

Imágenes perfectas en un display de profundidad mínima.<br />

7.5. El monitor vs. El ojo<br />

El ojo no es como una cámara de televisión, la cámara produce una<br />

imagen como la superposición de una serie de puntos brillantes y oscuros<br />

obtenidos cuando los electrones acelerados por el cañón del televisor a lo largo<br />

del tubo que se halla en el interior impactan contra una pantalla de material<br />

fluorescente: este material absorbe la energía del choque, se excita y<br />

posteriormente se des-excita emitiendo luz... ¡el puntito brillante que vemos!<br />

Para una televisión en color, esos puntos brillantes corresponden cada<br />

uno a un color primario, emitido en función de la energía que ha cedido el<br />

electrón acelerado en el choque. Además existe una conexión uno-a-uno entre<br />

cada punto del objeto y su imagen final, la cual se mantiene a través del<br />

proceso por el que la cámara lo produce. Por lo tanto se puede interrumpir el<br />

proceso en cualquiera de sus fases y se puede establecer que esa señal<br />

electrónica proviene de ese punto en particular del objeto.<br />

En el cerebro, ¡las cosas son muy distintas! Una parte de la corteza<br />

visual que es la que procesa la señal, puede conectarse a muchas partes<br />

diferentes de la retina de modo que el proceso de ver se hace muy complejo.<br />

Se cree que ciertas partes de la corteza son muy buenas en el reconocimiento<br />

de líneas horizontales y otras lo son en el reconocimiento de las verticales,<br />

otras reconocen mejor el contorno de los objetos, etc... Esta compleja<br />

arquitectura es la que hace que el cerebro sea mucho mejor en procesar la<br />

información visual que incluso el más moderno de los ordenadores, el cual,<br />

como una cámara de televisión, trabaja la información sobre la base de uno-auno<br />

(1:1).<br />

7.6. Profundidad del color<br />

La calidad de la imagen se puede mejorar incrementando la resolución<br />

de la pantalla, el número de píxeles del dibujo o también incrementando el<br />

número de <strong>colores</strong> disponibles.<br />

7.6.1. Color de 1-bit<br />

No existe un nombre que se utilice habitualmente para denominar este<br />

simple modo de color. La denominación de “blanco y negro” ha sido utilizada


Colores y <strong>sombras</strong> 17<br />

incorrectamente para referirnos a la “escala de grises” cuando en realidad sólo<br />

se pueden representar 2 <strong>colores</strong>.<br />

Este modo de video permite 2 <strong>colores</strong> ya que se utiliza 1 bit dedicado a<br />

la información de color por cada píxel (2 1 ).<br />

Cuando hablamos de color de 1 bit nos<br />

referimos a blanco o negro; algunas veces los 2 <strong>colores</strong><br />

no son blanco y negro, hubo terminales que utilizaron 2<br />

tipos de verdes: claro y oscuro. El siguiente dibujo es<br />

un ejemplo de una imagen de 1 bit de profundidad, sólo<br />

utiliza el blanco y el negro.<br />

El color de 1-bit se utilizó en dispositivos<br />

de texto, hubo excepciones, los Macintosh (que<br />

no tenían este modo de texto) y los originales IBM<br />

MGA (Monochome Graphics Adapter, que tenía<br />

un modo grafico adicional al modo de texto).<br />

7.6.2. Color de 4-bits<br />

Fue utilizado por los dispositivos IBM EGA (Enhanced Graphics<br />

Adapter), también por el Commodore 64 y 128 y otros muchos.<br />

BLACK DARK GREY BLUE LIGHT BLUE<br />

GREEN LIGHT GREEN CYAN LIGHT CYAN<br />

RED LIGHT RED PURPLE LIGHT PURPLE<br />

YELLOW LIGHT YELLOW LIGHT GREY<br />

Figura 13 - Imagen con<br />

1 bit de profundidad<br />

WHITE<br />

Este modo de video permite 16 <strong>colores</strong> ya que se utilizan 4 bits<br />

dedicados a la información de color por cada píxel (2 4 )<br />

El Commodore Amiga e IBM VGA (Vídeo Graphics Adapter) permitían<br />

indexación. Sólo se podía disponer de 16 <strong>colores</strong> de manera simultánea, pero<br />

los 16 <strong>colores</strong> se pueden elegir de una amplia paleta y cada paleta puede<br />

redefinir sus <strong>colores</strong>. Así un programa puede utilizar una escala de 16 grises,<br />

los 16 <strong>colores</strong> originales de EGA, o elegir cualquier combinación de <strong>colores</strong> de<br />

la amplia paleta de <strong>colores</strong> disponible. La única restricción es la utilización de<br />

16 <strong>colores</strong> de forma simultánea.


Colores y <strong>sombras</strong> 18<br />

7.6.3. Color de 8-bits<br />

Este modo de video permite 256 <strong>colores</strong><br />

en pantalla ya que se utilizan 8 bits dedicados a<br />

la información de color por cada píxel (2 8 ). Con<br />

estos bits se hace referencia al índice de la<br />

paleta de color. La paleta nos permite<br />

seleccionar entre 16 millones de <strong>colores</strong>. Cada<br />

color de la paleta se selecciona especificando 8<br />

bits para cada intensidad de rojo, verde y azul<br />

(la intensidad de cada componente puede tener<br />

una valor entre 0 y 255)<br />

Este modo de color combinado con la fusión<br />

permite obtener resultados aceptables para<br />

ciertas aplicaciones. También se pueden utilizar<br />

los 8 bits para imágenes de un tono continuo en<br />

blanco y negro con 256 matices de color, vemos<br />

un ejemplo de imagen de tono continuo.<br />

7.6.4. Color de 24-bits<br />

Este modo de video permite 16.777.216 <strong>colores</strong> en pantalla ya que se<br />

utilizan 24 bits dedicados a la información de color por cada píxel (2 24 ). Este<br />

modo de color mantiene 8 bits de color para componente de color rojo, verde y<br />

azul. Disponemos de los más de 16 millones de <strong>colores</strong> en cada píxel de la<br />

pantalla.<br />

Figura 15 - Imagen con 24 bits de profundidad<br />

Figura 14 - Imagen byn<br />

con 256 matices de color<br />

El inconveniente de la utilización de este modo es la utilización de<br />

memoria que se necesita para pantallas de alta resolución (2MB para<br />

1024x768). También es más lento mover grandes cantidades de memoria para<br />

realizar una animación o simplemente dibujar en pantalla. Aunque las tarjetas<br />

aceleradoras están optimizadas para este tipo de operaciones.


Colores y <strong>sombras</strong> 19<br />

7.7. Modelos de color<br />

El propósito de un modelo de color es facilitar la especificación de<br />

<strong>colores</strong> en algún formato estándar. Un modelo de color es una especificación<br />

de un modelo de coordenadas 3-D y un subespacio dentro de ese sistema<br />

donde cada color se representa por un punto único.<br />

La mayoría de los modelos de color que se utilizan están orientados<br />

hacia el hardware como monitores o impresoras o aplicaciones de<br />

manipulación de color. El modelo orientado al hardware más común es el RGB<br />

(red-green-blue), el modelo CMY (cyan-magenta-yellow) para impresoras en<br />

color y el YIQ que es el estándar para la difusión de TV ( Y = luminancia, I y Q<br />

son dos componentes cromáticas). Para la manipulación del color se suelen<br />

utilizar los modelos HSI (matiz, saturación e intensidad) y HSV (matiz,<br />

saturación y valor).<br />

Los modelos más utilizados en el procesamiento de imágenes son RGB,<br />

YIQ y HSI.<br />

7.7.1. Modelo de color XYZ<br />

En los años 30, la Commission Internationale de l'Eclairage (CIE) definió<br />

un espacio de color estándar, una manera de definir <strong>colores</strong> en términos<br />

matemáticos, para facilitar la comunicación de la información de color. Este<br />

espacio de color está basado en la investigación sobre la naturaleza de la<br />

percepción del color.<br />

7.7.1.1. Espacio de color CIE<br />

En el intento de lograr una representación que utilice solamente<br />

coeficientes de mezcla positivos, el CIE ("d'Eclairage de Internationale de la<br />

Comisión") definió tres nuevas fuentes de luz hipotéticas, x, y, y z, resultando<br />

curvas positivas:<br />

Figura 16 - representación de las fuentes de luz x, y, z<br />

Dado un espectro y un deseamos encontrar los valores correspondientes<br />

de X, de Y, y de Z, lo podemos lograr integrando el producto de la energía


Colores y <strong>sombras</strong> 20<br />

espectral con cada una de las tres curvas sobre todas las longitudes de onda.<br />

Los pesos de X, Y y Z se toman del espacio tridimensional del CIE XYZ, según<br />

lo mostrado arriba.<br />

Esto es logrado proyectando el espacio de color 3D sobre el plano<br />

X+Y+Z=1, resultando un diagrama de la cromaticidad del CIE.<br />

Se define la proyección como:<br />

Resultando el diagrama de cromaticidad CIE<br />

7.7.1.1.1. Diagrama de cromaticidad CIE<br />

El diagrama de cromaticidad CIE es un<br />

modelo de dos dimensiones de visión del color.<br />

El arco alrededor de la parte superior de la<br />

herradura incluye los <strong>colores</strong> espectrales puros<br />

desde el violeta azulado hasta el rojo.<br />

Mezclando dos <strong>colores</strong> espectrales puros<br />

en diferentes proporciones es posible crear<br />

todos los <strong>colores</strong> que se encuentran en la línea<br />

recta dibujada entre ellos en el diagrama. Es<br />

posible crear el mismo tono de gris mezclando el<br />

verde azulado y el rojo o mezclando el verde<br />

amarillento y el violeta azulado. Esto es<br />

posible debido a un fenómeno peculiar<br />

de la visión del color llamado<br />

metamerismo. Los <strong>colores</strong> púrpura, que<br />

no existen en el espectro de la luz pura, se encuentran en la parte inferior del<br />

diagrama. Los púrpuras son mezclas de rojo y azul, los extremos opuestos del<br />

espectro.<br />

El diagrama de cromaticidad CIE refleja el tono y la saturación, pero es<br />

necesario un modelo tridimensional para añadir el componente del brillo.<br />

Muchas aplicaciones informáticas incluyen cuadros de diálogo en los que es<br />

posible seleccionar <strong>colores</strong> manipulando el tono, la saturación y el brillo. Por<br />

ejemplo, Adobe Photoshop utiliza un cuadro Selector de Color que puede<br />

configurarse según las preferencias personales.<br />

7.7.1.1.2. Gama de <strong>colores</strong><br />

Figura 17 - Diagrama de cromaticidad<br />

CIE<br />

El diagrama de cromaticidad se puede utilizar para comparar las<br />

"gamas" de varios dispositivos de salida posibles (es decir, los monitores e<br />

impresoras). Note que una impresora de color no puede reproducir todos los<br />

<strong>colores</strong> visibles en un monitor de color.


Colores y <strong>sombras</strong> 21<br />

7.7.2. El modelo de color RGB<br />

Figura 18 - Comparación de gamas de <strong>colores</strong><br />

El modelo aditivo de color utilizado para los gráficos de computadora es<br />

representado por el cubo del color del RGB, donde R, G, y B representan los<br />

<strong>colores</strong> producidos por los fósforos rojos, verdes y azules, cubo del color de<br />

respectivamente. El cubo se proyecta dentro del espacio de color del CIE XYZ<br />

Nuestros ojos perciben el color a través de la simulación de tres<br />

pigmentos visuales en los conos de la retina. Estos pigmentos tienen una<br />

sensibilidad pico en las longitudes de onda 630 nm (rojo), 530 nm (verde), y<br />

430 nm (azul). Comparando las intensidades en una fuente de luz, se percibe<br />

el color de la luz. Esta teoría es la base para desplegar la salida de color en un<br />

monitor de video mediante el uso de los tres <strong>colores</strong> primarios, conocido como<br />

modelo de color RGB.<br />

Cada color aparece en sus componentes primarias espectrales rojo,<br />

verde y azul. El modelo está basado en un sistema de coordenadas cartesiano.<br />

El subespacio de interés es el cubo que se muestra en la figura 19.<br />

Todos los <strong>colores</strong> han sido normalizados de<br />

forma que el cubo es unitario, es decir, se supone<br />

que todos los valores de rojo, verde y azul están<br />

en el rango [0, 1].<br />

Este esquema de color es un modelo<br />

aditivo: las intensidades de los <strong>colores</strong> primarios<br />

se suman para producir otros <strong>colores</strong>. Cada punto<br />

de color contenido en los límites del cubo puede<br />

representarse como la tríada (R,G,B), donde los<br />

valores de R,G,B se asignan en el intervalo de 0 a<br />

1. Por ejemplo, el vértice magenta se obtiene<br />

sumando el rojo y el azul para producir la tríada Figura 19 - Cubo RGB<br />

(1,0,1) y el blanco en (1,1,1) es la suma de los<br />

vértices rojo, verde y azul. Las <strong>sombras</strong> de gris se representan a lo largo de la<br />

diagonal principal del cubo del origen (negro) al vértice blanco. Cada punto<br />

situado en esta diagonal tiene una contribución igual de cada color primario, de<br />

manera que una sombra de gris en medio del negro y el blanco se representan<br />

como (0.5, 0.5, 0.5).


Colores y <strong>sombras</strong> 22<br />

Las imágenes en el modelo de color RGB están formadas por tres<br />

planos de imágenes independientes, cada una de los <strong>colores</strong> primarios.<br />

Cuando se introducen en un monitor RGB, las tres imágenes se combinan en la<br />

pantalla de fósforo para producir una imagen de color compuesta. Por tanto, se<br />

utiliza el modelo RGB para el procesamiento de imágenes si las imágenes se<br />

expresan en términos de los tres planos de <strong>colores</strong>. La mayoría de las cámaras<br />

en color que se usan para adquirir imágenes digitales utilizan el formato RGB.<br />

Uno de los mejores ejemplos de la utilidad del modelo RGB es el<br />

procesamiento de imágenes aéreas y de satélites multiespectrales. Estas<br />

imágenes se obtienen para diferentes rangos espectrales. Por ejemplo, las<br />

imágenes LANDSAT se obtienen como mínimo en cuatro ventanas espectrales<br />

distintas de la misma escena. Dos ventanas estarán alojadas en el espectro<br />

visible y se corresponden aproximadamente con verde y rojo; las otras dos se<br />

encontrarán en el infrarrojo. Así pues cada plano de la imagen tiene sentido<br />

físico y la combinación de color utilizando el modelo RGB para procesamiento y<br />

visualización tiene sentido cuando se ve en una pantalla en color.<br />

A continuación se muestra una imagen en color de verduras y frutas<br />

junto con sus tres bandas de color rojo, verde y azul. El mayor nivel de gris en<br />

cada banda corresponde con el color predominante en cada objeto (fruta o<br />

verdura).<br />

Figura 20 - (a) Imagen original en color. (b) Plano de rojo. (c) Plano verde. (d)<br />

Plano azul<br />

Sin embargo este modelo de color no siempre es el mejor para el<br />

procesamiento de imágenes, por ejemplo para realizar una imagen en color con<br />

sombra de una cara humana. Este problema puede resolverse mediante la<br />

igualación del histograma. Al tener tres bandas y puesto que el histograma<br />

trabaja sólo con las intensidades, cuando igualemos el histograma en cada


Colores y <strong>sombras</strong> 23<br />

banda, en cada una de ellas tendremos mejora, sin embargo, el resultado<br />

global, (cuando se combinen las tres bandas), será impredecible.<br />

A pesar de todo este modelo es la elección más corriente para gráficos<br />

por ordenador ya que los CRT usan fósforo rojo, verde y azul para crear el<br />

color deseado. Sin embargo, este modelo no describe de forma eficiente las<br />

tres componentes de color (R,G,B). El igual ancho de banda da lugar a la<br />

misma profundidad del píxel y resolución del dispositivo para cada<br />

componente. Sin embargo, la sensibilidad de la componente de color del ojo<br />

humano es menor que la de la luminancia.<br />

Por estas razones, muchos métodos de codificación de imágenes y<br />

sistemas de transmisión utilizan la luminancia y dos diferencias de <strong>colores</strong>.<br />

Estos son los formatos YUV, YIQ, Y CbCr.<br />

7.7.3. El modelo de color CMY (Cyan, Magenta, Amarillo)<br />

Un modelo de color definido con los <strong>colores</strong> primarios cyan, magenta y<br />

amarillo (CMY) es útil para describir la salida de color de los dispositivos de<br />

copia hardware. A diferencia de los monitores de video, que producen un<br />

modelo de color combinando luz de los fósforos de la pantalla, los dispositivos<br />

hardware como las impresoras producen una imagen de color cubriendo un<br />

papel con pigmentos de color. Se obtienen los <strong>colores</strong> por luz reflejada, lo cual<br />

es un proceso sustractivo.<br />

Por ejemplo, el cyan (azul-verde) puede formase combinando luz verde<br />

con luz azul, por tanto cuando se refleja luz blanca sobre un objeto que es<br />

verde-azul la luz reflejada no debe tener componente roja, es decir, la luz roja<br />

es absorbida, o sustraída por el objeto. De forma análoga para obtener el<br />

magenta se resta la componente verde de la luz incidente y el amarillo sustrae<br />

la componente azul.<br />

En el modelo CMY, el<br />

punto (1,1,1) representa el<br />

negro, ya que todas las<br />

componentes de la luz incidente<br />

se sustraen. El origen representa<br />

la luz blanca. Cantidades iguales<br />

de cada uno de los <strong>colores</strong><br />

primarios producen grises a lo<br />

largo de la diagonal principal del<br />

cubo.<br />

Rojo<br />

Magenta<br />

Azul<br />

Negro<br />

Blanco<br />

Amarillo Verde<br />

Figura 21 - Cubo de Color<br />

Cyan (Verde-Azul)<br />

Como ya sabemos el cyan, magenta y amarillo son los <strong>colores</strong><br />

secundarios. Para convertir los <strong>colores</strong> primarios en secundarios hemos de<br />

realizar la siguiente transformación:


Colores y <strong>sombras</strong> 24<br />

⎛ C ⎞ ⎛1⎞<br />

⎛ R ⎞<br />

⎜ ⎟ ⎜ ⎟ ⎜ ⎟<br />

⎜ M ⎟ = ⎜1⎟<br />

⋅⎜<br />

G⎟<br />

⎜ ⎟ ⎜ ⎟ ⎜ ⎟<br />

⎝ Y ⎠ ⎝1⎠<br />

⎝ B ⎠<br />

La figura 20 (a,b,c) muestra las representaciones en las<br />

correspondientes bandas de la imagen en la figura 20 (a). Para obtener estas<br />

imágenes se ha normalizado cada canal a uno independientemente,<br />

dividiéndolo por 255, a continuación se le ha restado a uno dicha cantidad y por<br />

último se ha multiplicado el resultado por 255.<br />

7.7.4. El modelo de color YUV<br />

Este es el formato de color que se utiliza por los estándares de TV<br />

NTSC, PAL y SECAM. La Y representa la componente de blanco y negro y la<br />

información de color U y V se añade para mostrar una imagen en color. La<br />

transformación es:<br />

⎛ Y ⎞ ⎛ 0.<br />

299<br />

⎜ ⎟ ⎜<br />

⎜U<br />

⎟ = ⎜−<br />

0.<br />

147<br />

⎜ ⎟ ⎜<br />

⎝V<br />

⎠ ⎝ 0.<br />

615<br />

0.<br />

587<br />

− 0.<br />

289<br />

− 0.<br />

515<br />

0.<br />

114 ⎞ ⎛ R ⎞<br />

⎟ ⎜ ⎟<br />

0.<br />

436 ⎟ − ⎜G<br />

⎟<br />

− 0.<br />

100⎟<br />

⎜ ⎟<br />

⎠ ⎝ B ⎠<br />

Observemos que U = 0.492 (B - Y). y que V = 0.877 (R – Y ).<br />

Normalmente U y V son submuestreados por un factor de dos a cuatro en la<br />

dimensión espacial, ya que el ojo humano es mucho menos sensible a estos<br />

factores. Esto es muy útil, por ejemplo, para reducir el número de bits utilizado<br />

en técnicas de compresión de imágenes.<br />

7.7.5. El modelo de color YIQ<br />

Este modelo se utiliza en las emisiones de TV en color. Básicamente,<br />

YIQ es una recodificación de RGB para aumentar la eficiencia en la trasmisión<br />

y para mantener la compatibilidad con los estándares de TV monocromo. De<br />

hecho, la componente Y del sistema YIQ proporciona toda la información de<br />

video que se requiere para una televisión monocromo. La conversión de RGB a<br />

YIQ viene dada por:<br />

⎛Y<br />

⎞ ⎛0.<br />

299<br />

⎜ ⎟ ⎜<br />

⎜ I ⎟ = ⎜0.<br />

596<br />

⎜ ⎟ ⎜<br />

⎝Q<br />

⎠ ⎝0.<br />

212<br />

0.<br />

587<br />

− 0.<br />

275<br />

− 0.<br />

523<br />

0.<br />

114 ⎞ ⎛ R ⎞<br />

⎟ ⎜ ⎟<br />

− 0.<br />

321⎟<br />

• ⎜G<br />

⎟<br />

0.<br />

311 ⎟ ⎜ ⎟<br />

⎠ ⎝ B ⎠<br />

Este sistema fue diseñado teniendo en cuenta las características del<br />

sistema visual humano, obteniendo mayor sensibilidad a los cambios en<br />

luminancia que a los cambios de matiz o saturación. Así pues, este estándar<br />

usa más bits (o ancho de banda) para representar Y y menos para I y Q.<br />

Es uno de los modelos que más se utilizan. Una de sus mayores<br />

ventajas es que las informaciones de luminancia (Y) y color (I y Q) están<br />

separadas, esto nos permite procesar la luminancia sin afectar al color.


Colores y <strong>sombras</strong> 25<br />

La figura 22 (d,e,f) muestra las representaciones en las correspondientes<br />

bandas de la imagen en la figura 22 (a).<br />

Figura 22 - (a) Plano C del modelo CMY (b) Plano M del modelo CMY (c) Plano<br />

Y del modelo CMY (d) Plano Y del modelo YIQ (e) Plano I del modelo YIQ (f)<br />

Plano Q del modelo YIQ.<br />

Observemos que la figura 22(d) es una imagen en niveles de gris de la<br />

imagen original. Puesto que las bandas YUV tienen rangos distintos todas han<br />

sido llevadas al [0,255] para la visualización. Tengamos en cuenta que tanto la<br />

banda U como V pueden tener valores negativos.<br />

7.7.6. El modelo de color HSI<br />

El matiz es un atributo que describe la pureza de un color. La saturación<br />

es una medida del grado en el que un color puro se diluye con la luz blanca. La<br />

utilidad del modelo de color HSI se debe principalmente a estas dos<br />

características:<br />

- La componente de intensidad se separa de la información de color<br />

- Las otras dos componentes están muy relacionadas con la forma en<br />

la que el ser humano percibe el color.<br />

Gracias a estas propiedades este modelo es muy apropiado para el<br />

desarrollo de algoritmos de procesamiento de imágenes basados en<br />

propiedades del sistema de visión humano.


Colores y <strong>sombras</strong> 26<br />

7.7.7. El sistema HLS (Hue, Saturation and Luminance)<br />

Este modelo utiliza los tres componentes básicos del color: matiz (Hue),<br />

saturación (Saturation) y brillo (Luminance). Una representación gráfica<br />

incluyendo estas tres propiedades genera el<br />

denominado "espacio y color".<br />

En el perímetro del disco están situados<br />

los <strong>colores</strong> azul, magenta, rojo, amarillo, verde<br />

y cyan, separados 60º uno de otro:<br />

Cada punto del perímetro describe un<br />

color que es mezcla de los dos adyacentes.<br />

Un punto que no esté en el perímetro<br />

contendrá una mezcla de todos. Por lo tanto,<br />

estos puntos describen <strong>colores</strong> pastel que<br />

contienen una cierta cantidad de blanco. La<br />

distancia al centro (radio) indicará la<br />

saturación del color. El brillo (intensidad del<br />

color) depende de la altura en el doble cono, y<br />

es un valor entre 0 y 1.<br />

El punto medio del disco central<br />

describe un blanco de intensidad media.<br />

Supongamos que, por ejemplo, comenzamos<br />

en el perímetro del cono en el ángulo cero<br />

(color azul) y nos movemos en línea recta<br />

hacia arriba: estamos añadiendo más blanco,<br />

Figura 23 - Modelo HLS<br />

por lo que pasaremos por un azul claro, un azul pastel casi blanco hasta llegar<br />

finalmente a un blanco brillante. Esto sucede con todos los <strong>colores</strong>.<br />

La conclusión es que todos los <strong>colores</strong> convergen al blanco a medida<br />

que avanzamos hacia el vértice superior y hacia el negro a medida que<br />

bajamos.<br />

7.7.8. Modelo HSV<br />

Fue creado a partir de un concepto intuitivo de la manera de trabajar de<br />

un artista y su modo de mezclar <strong>colores</strong> para obtener el correcto sombreado y<br />

la obtención de los tonos intermedios. La selección y obtención de <strong>colores</strong> en el<br />

modelo HSV es mucho más intuitiva que en los modelos RGB y CMY. Se basa<br />

principalmente en el control de los valores de matiz, saturación y valor (HSV).<br />

− Hue (Matiz): Se representa en un ángulo en torno a un eje vertical<br />

(0º...360º). Los vértices del hexágono se separaran a intervalos de 60º. El rojo<br />

está en 0º, el amarillo en 60º, el verde en 120º y el azul-verde opuesto al rojo<br />

en H = 180º. Los <strong>colores</strong> complementarios distan 180º.


Colores y <strong>sombras</strong> 27<br />

− Saturation (Saturación): Varia<br />

de 0 a 1. Representa la pureza de un<br />

matiz. La pureza máxima se representa<br />

en S = 1. En S = 0 se tiene la escala de<br />

gris.<br />

− Value (Valor): Varia de 0 en la<br />

cúspide del cono hexagonal a 1 en la<br />

parte superior. En la cúspide se<br />

encuentra el negro, en la parte superior<br />

los <strong>colores</strong> de máxima intensidad.<br />

Los conceptos de color<br />

Figura 24 - Modelo HSV<br />

asociados con los términos <strong>sombras</strong>,<br />

tintes y tonos se representan en un plano seccional-transversal del cono<br />

hexagonal HSV. Si se agrega negro a un matiz puro se disminuye V hacia el<br />

lado del cono hexagonal. Por lo tanto, varias <strong>sombras</strong> se representan con<br />

valores S=1 y 0


Colores y <strong>sombras</strong> 28<br />

7.8. Colores en OpenGL<br />

7.8.1. Utilización de <strong>colores</strong> con OpenGL<br />

OpenGL especifica un color utilizando las intensidades separadas de<br />

componentes rojo, verde y azul. Por lo tanto un color se especifica con 3<br />

valores positivos, y puesto que el máximo disponible en el PC para el<br />

almacenamiento de esta información son 24 bits (8 bits para cada componente)<br />

podemos modelar los <strong>colores</strong> disponibles mediante un cubo de 255 unidades<br />

en cada cara. A este volumen lo denominamos el espacio de color RGB.<br />

Este “cubo de color” contiene todos los <strong>colores</strong> que podremos utilizar en<br />

nuestras aplicaciones, tanto en la superficie como en el interior del mismo.<br />

El modelo de color RGBA es el que utilizamos cuando definimos un color<br />

con la función glColor*; utilizamos el modelo de color indexado cuando<br />

seleccionamos un color de dibujo indicando un índice en una matriz de <strong>colores</strong><br />

disponible llamada paleta. Dentro de esta paleta, especificamos el color exacto<br />

que queremos seleccionando las intensidades de las componentes roja, verde<br />

y azul.<br />

Los elementos geométricos se dibujan con los atributos activos en cada<br />

momento. En cualquier momento se pude modificar el valor de<br />

los atributos, sustituyendo el nuevo valor al anterior. Los atributos<br />

podrán apilarse y desapilarse.<br />

La figura siguiente muestra el dibujo simple de dos<br />

triángulos de diferentes <strong>colores</strong>. Estos se definen con la<br />

instrucción glColor3f(red,green,blue) tal como se muestra en el<br />

código C (ver código completo en el anexo, ejemplo 1).<br />

void triangulo1(void)<br />

{<br />

}<br />

glBegin(GL_TRIANGLES);<br />

glColor3f(1.0,0.0,0.0);<br />

glVertex2f(0.0,0.4);<br />

glVertex2f(-0.4,0.0);<br />

glVertex2f(0.4,0.0);<br />

glEnd();<br />

void triangulo2(void)<br />

{<br />

}<br />

glBegin(GL_TRIANGLES);<br />

glColor3f(0.0,0.0,1.0);<br />

glColor3f(0.0,1.0,0.0);<br />

glVertex2f(0.0,-0.4);<br />

glVertex2f(-0.4,0.2);<br />

glVertex2f(0.4,0.2);<br />

glEnd();<br />

Figura 25 - Triángulos


Colores y <strong>sombras</strong> 29<br />

Listado 1 - Ejemplo de definición de <strong>colores</strong><br />

A pesar de que existe una instrucción que establece el color del segundo<br />

triángulo a azul, ésta no tendrá efecto ya que quedará anulado por la siguiente<br />

instrucción que lo pone a verde.<br />

La sintaxis de la función glColor es la siguiente:<br />

• Propósito: Selecciona el color actual en el modo de color RGBA.<br />

• Fichero de inclusión: <br />

• Sintaxis: void glColor. Donde número de argumentos<br />

puede ser 3 ó 4 (si hay componente alfa), y tipo de argumentos puede ser b(byte),<br />

d(double), f(float), etc.. Por ejemplo: void glColor4b( GLbyte rojo, GLbyte verde,<br />

GLbyte azul, GLbyte alfa); o void glColor3fv(const GLfloat *v);<br />

• Descripción: Selecciona el color activo especificando por separado las<br />

componentes roja, verde y azul. Algunas aceptan también la componente alfa (si no<br />

se especifica vale por defecto 1.0). Las funciones con sufijo v toman un puntero a<br />

una matriz que especifica las componentes.<br />

• Parámetros:<br />

rojo<br />

Especifica la componente roja del color.<br />

verde<br />

Especifica la componente verde del color.<br />

azul<br />

Especifica la componente azul del color.<br />

alfa<br />

Especifica la componente alfa del color. (Ver siguiente apartado)<br />

*v<br />

Al dibujar polígonos se puede controlar que se dibujen sus aristas o solo<br />

el interior. Es normal dibujar las aristas al realizar esquemas, mientras que<br />

estas se suelen suprimir cuando se desea general imágenes realistas. El<br />

control de visibilidad de las aristas se realiza con la función glEdgeflag(b)<br />

donde el argumento b será 0 o 1 dependiendo de que se active o no el dibujo<br />

de las aristas.<br />

Pero no sólo podemos conseguir <strong>colores</strong> solidos, también gradientes. Eso<br />

lo podemos llevar a la con un triángulo, por ejemplo; bastará con que le<br />

asignemos un color distinto a cada vértice para que OpenGL rendere la imagen<br />

con el gradiente de color resultante entre ellos (fijémonos que estamos con lo<br />

que se denomina, color suave). La construcción del triángulo quedará así:


Colores y <strong>sombras</strong> 30<br />

glBegin GL_TRIANGLES<br />

glColor3f( 1.0,0.0,0.0 ) //color rojo<br />

glVertex3f( 0.0,1.0,0.0 )<br />

glColor3f( 0.0,1.0,0.0 ) //color verde<br />

glVertex3f( -1.0,-1.0,0.0 )<br />

glColor3f( 0.0,0.0,1.0 ) //color azul<br />

glVertex3f( 1.0,-1.0,0.0 )<br />

glEnd<br />

Listado 2 - Ejemplo de definición de un gradiente<br />

El resultado de la coloración de la escena es la siguiente:<br />

7.8.2. Modelo de color RGBA<br />

Figura 26 - Gradiente<br />

En el modelo RGBA utilizamos la función glColor*( ) para seleccionar el<br />

color actual que establece los <strong>colores</strong> rojo, verde, azul y la componente alfa (si<br />

se utiliza transparencia). Todos los objetos dibujados después de la aplicación<br />

de esta función tendrán el último color especificado en la misma.<br />

Canal alpha<br />

El canal alpha no es más que una imagen de 8 bits en escala de grises.<br />

OpenGL interpreta esta información como sigue:<br />

• Un valor alpha de 0 (color negro) indica transparencia total, es<br />

decir, que la zona del polígono afectada por este valor no se verá.<br />

• Un valor de 128 (color gris "puro") indica semitransparencia.<br />

• Un valor de 255 (color blanco) indica opacidad total<br />

El funcionamiento es el siguiente:<br />

El modelo RGBA de color dota a cada punto de una cuarta componente<br />

llamada canal alfa. Este sirve para decidir que debe hacerse con ese punto si<br />

contribuye junto con otros a colorear un píxel. Hasta ahora el citado píxel se


Colores y <strong>sombras</strong> 31<br />

pintaría del color del polígono más cercano pero si activamos el canal alfa<br />

obtendremos “mezclas de <strong>colores</strong>” para el píxel. Cada polígono contribuirá en<br />

un cierto tanto por ciento a colorear el píxel de forma que podemos obtener<br />

interesantes efectos como emular un cristal tintado o un papel de celofán rojo,<br />

por ejemplo:<br />

Figura 27 - Funcionamiento<br />

canal alpha<br />

En esta imagen se observa que<br />

mezclando dos <strong>colores</strong> generamos un<br />

tercero o lo que es lo mismo, que si tengo<br />

un objeto de color rojo y le pongo delante<br />

un papel translúcido de color azul, la<br />

intersección de ambos se verá de color<br />

lila.<br />

Eso ocurre porque el polígono que<br />

está más cerca tiene un cierto grado de<br />

transparencia por lo cuál nos deja ver lo<br />

que tiene detrás. A esto se le llama<br />

“Blending”. Siempre se habla de una<br />

fuente (source) y un destino (destination). El destino es el valor de color que<br />

un píxel ya tiene asignado en el frame buffer. La fuente es el color que<br />

viene, el color que se mezclará con el que ya tiene.<br />

Se combinan los <strong>colores</strong> de la fuente y del destino según el valor de<br />

alfa que tiene cada uno de ellos. Se define una función de mezclado, o de<br />

“blending” que, según sea, aplicará de una forma o de otra el canal alfa de<br />

cada color.<br />

Para hacer esto con OpenGL se deberá activar el mezclado de<br />

<strong>colores</strong> y desactivarlo con las funciones glEnable(GL_BLEND) y<br />

glDisable(GL_BLEND).<br />

Para indicar como debe hacerse la mezcla se usará la función<br />

glBlendFunc(Glenum factorfuente, Glenum factordestino). Dos<br />

ejemplos:<br />

1. glBlendFunc(GL_ONE,GL_ZERO). En este caso estamos<br />

dando una importancia de 1 (máxima) al canal alfa de la fuente y<br />

de 0 (nula) al canal alfa del destino. Eso equivale a decir que el<br />

color final se compone de un 100% del de la fuente y de un 0%<br />

del color destino por lo cual el píxel acaba siendo del color de la<br />

fuente.<br />

2. glBlendFunc(GL_SRC_ALPHA, GL_ONE). En este caso le<br />

decimos que multiplique a la fuente por su valor de alfa y sume el<br />

resultado al color destino. En este caso y asumiendo un valor de<br />

alfa igual a 0.75 para la fuente, podríamos decir que el color<br />

resultante=(color de la fuente*0.75)+Color del destino.<br />

Sintaxis de la funcion:<br />

glBlendFunc(Glenumfactor_o,Glenumfactor_d):


Colores y <strong>sombras</strong> 32<br />

• Propósito: Define el color de las funciones de mezcla.<br />

• Fichero de inclusión: <br />

• Sintaxis: void glBlendFunc( GLenum factor_o, GLenum factor_d);<br />

• Descripción: Selecciona los factores de origen y destino para la mezcla de <strong>colores</strong>.<br />

Primero debemos llamar a glEnable(GL_BLEND) para activar la mezcla de <strong>colores</strong>.<br />

• Parámetros:<br />

factor_o<br />

GLenum: la función de mezcla de color en origen.<br />

factor_d<br />

GLenum: la función de mezcla de color en destino.<br />

• Retornos: Ninguno


Colores y <strong>sombras</strong> 33<br />

Para las funciones glColor que aceptan valores enteros el rango de<br />

valores que se acepta varía entre 0.0 y 1.0. el máximo y el mínimo valor que<br />

puede ser almacenado en el framebuffer.<br />

Cuando se especifican las componentes de color utilizando enteros sin<br />

signo, estas componentes son mapeadas linealmente a valores de coma<br />

flotante, de manera que representen valores comprendidos entre el 1.0<br />

(intensidad total) y 0.0 (intensidad nula). Las componentes especificadas<br />

utilizando valores enteros con signo son mapeadas linealmente a valores de<br />

coma flotante, de manera que el valor más positivos representa al 1.0 y el<br />

más negativo al 0.0<br />

Sufijo Tipo de Dato Valor mínimo mínimo Valor de<br />

Mapeo<br />

Valor<br />

Máximo<br />

B 1-byte-integer -128 -1.0 127 1.0<br />

S 2-byte-integer -32768 -1.0 32767 1.0<br />

I 4-byte-integer -<br />

Ub Unsigned 1- byte-<br />

integer<br />

Us Unsigned 2- byte-<br />

integer<br />

Ui Unsigned 4- byte-<br />

integer<br />

2.147.483.648<br />

-1.0 2.147.483.647 1.0<br />

0 0.0 255 1.0<br />

0 0.0 65535 1.0<br />

0 0.0 4.294.967.295 1.0<br />

Valor Máximo de<br />

Mapeo<br />

• Propósito: Selecciona los valores de color y alfa para borrar los buffers de color.<br />

• Fichero de inclusión: <br />

• Sintaxis: void glClearColor(GLclampf rojo, GLclampf verde, GLclampf azul,<br />

GLclampf alfa);<br />

• Descripción: Selecciona los valores de relleno para borrar los buffers rojo, verde,<br />

azul y alfa, que varían entre [0.0f,1.0f].<br />

• Parámetros:<br />

rojo<br />

GLclampf: la componente roja del valor de relleno.<br />

verde<br />

GLclampf: la componente verde del valor de relleno.<br />

azul<br />

GLclampf: la componente azul del valor de relleno.<br />

alfa<br />

GLclampf: la componente alfa del valor de relleno.<br />

• Retornos: Ninguno.<br />

Una de las primeras acciones que hay que realizar en nuestras<br />

aplicaciones es limpiar el área de dibujo en la que vamos a trabajar.


Colores y <strong>sombras</strong> 34<br />

Limpiaremos la ventana cada vez que dibujemos una nueva imagen. Utilizando<br />

el modelo tetradimensional RGBA podemos crear efectos en la ventana de<br />

dibujo que interactúa con otras ventanas que se encuentren debajo de ella,<br />

manipulando la opacidad de la ventana al limpiarla.<br />

La función glClearColor(GLclampf rojo, GLclampf verde, GLclampf azul,<br />

GLclampf alfa) selecciona los valores de relleno para<br />

borrar los buffers rojo, verde, azul y alfa, que varían entre<br />

[0.0f,1.0f]. Su sintaxis es la siguiente:<br />

La figura muestra un ejemplo de modelo de color<br />

RGBA en el que se muestra la transparencia de un<br />

cristal de color rojo que deja ver parte de la esfera verde<br />

situada por detrás de él. El código correspondiente a la<br />

misma es el siguiente:<br />

Figura 28 – modelo<br />

de color RGBA


Colores y <strong>sombras</strong> 35<br />

#include <br />

#include <br />

#include <br />

#include <br />

int idventana;<br />

void cristal(void)<br />

{<br />

glShadeModel(GL_FLAT);<br />

glEnable(GL_BLEND);<br />

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);<br />

glPushMatrix();<br />

glTranslatef(-10,-10,-100.0);<br />

glBegin(GL_QUADS);//Dibuja el cristal<br />

glColor4f(1.0,0.0,0.0,0.10);<br />

glVertex3f(0,0,0);<br />

glVertex3f(0,10,0);<br />

glVertex3f(10,10,0);<br />

glVertex3f(10,0,0);<br />

glEnd();<br />

}<br />

glPopMatrix();<br />

glDisable(GL_BLEND);<br />

void bola(void)<br />

{<br />

glPushMatrix();<br />

glTranslatef(0,0,-150);<br />

glColor4f(0.0,0.8,0.0,1.0);//Dibuja la bola amarilla<br />

glutSolidSphere(6,20,10);<br />

glPopMatrix();<br />

}<br />

void display(void)<br />

{<br />

GLfloat pos[4]={2.0,12.0,3.0,0.0};<br />

glClearColor(1,1,1,1);<br />

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);<br />

bola();<br />

cristal();<br />

glutSwapBuffers();<br />

glFlush();<br />

}<br />

void myReshape(GLsizei w, GLsizei h)<br />

{<br />

glViewport(0,0,w,h);<br />

glMatrixMode(GL_PROJECTION);


Colores y <strong>sombras</strong> 36<br />

}<br />

glLoadIdentity();<br />

if (h==0)<br />

gluPerspective(20,(GLdouble)w,1.0,500.0);<br />

else<br />

gluPerspective(20,(GLdouble)w/(GLdouble)h,1.0,500.0);<br />

glMatrixMode(GL_MODELVIEW);<br />

glLoadIdentity();<br />

glFlush();<br />

void Idle(void)<br />

{<br />

angulo+=0.5;<br />

if (angulo>360) angulo=0;<br />

glutPostRedisplay();<br />

}<br />

int main(int argc, char **argv)<br />

{<br />

glutInit(&argc,argv);<br />

glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);<br />

glutInitWindowPosition(0,0);<br />

glutInitWindowSize(300,300);<br />

idventana=glutCreateWindow("Transparencia");<br />

glutReshapeFunc(myReshape);<br />

glutDisplayFunc(display);<br />

glutIdleFunc(Idle);<br />

glutMainLoop();<br />

}<br />

return 0;<br />

Listado 3 - Ejemplo de definición de transparencia<br />

7.8.3. Modelo de color indexado<br />

Muchos sistemas tienen frame buffer limitado en profundidad. Podemos<br />

tener una resolución espacial para el frame buffer de 1280x1024, pero cada<br />

píxel tendría solo 8 bits de profundidad. Podemos dividir estos 8 bits en grupos<br />

más pequeños de bits para asignar rojo, verde y azul. En algunas aplicaciones<br />

esta técnica puede ser adecuada, pero no es muy flexible en la asignación de<br />

<strong>colores</strong> ya que divide los bytes en distintos grupos de bits que pueden afectar<br />

al resultado.


Colores y <strong>sombras</strong> 37<br />

Podemos seleccionar los <strong>colores</strong> interpretando nuestra limitación de<br />

profundidad (en los píxeles) como índices mejor que como valores de color.<br />

Estos índices corresponden a filas o entradas en una tabla. Suponiendo que<br />

nuestro frame buffer tiene k bits por píxel. Cada valor de píxel o índice es un<br />

entero entre 0 y 2 k -1. Si podemos mostrar <strong>colores</strong> con una precisión de m bits<br />

podremos elegir entre 2 m rojos, 2 m verdes y 2 m azules. Produciremos<br />

cualquiera de los 2 3m <strong>colores</strong> aunque el frame buffer solo pueda especificar 2 k<br />

<strong>colores</strong>. Utilizamos una tabla de búsqueda de <strong>colores</strong> de tamaño 2 k * 3 m, el<br />

programa del usuario considerará 2 k filas de la tabla con los <strong>colores</strong> deseados<br />

utilizando m bits para cada rojo, verde y azul.<br />

Una vez que el usuario ha construido la tabla puede especificar un color<br />

por su índice que apunta a la posición adecuada en la tabla de búsqueda de<br />

color. Para k=m=8, una configuración muy común, se pueden elegir 256<br />

<strong>colores</strong> de entre 16 millones de <strong>colores</strong>. Las 256 entradas en la tabla<br />

constituyen la paleta de color del usuario.<br />

Entrada Rojo Verde Azul<br />

0 0 0 0<br />

1 2 m -1 0 0<br />

. 0 2 m -1 0<br />

. . . .<br />

. . . .<br />

2 k -1 . . .<br />

m bits m bits m bits<br />

Si estamos utilizando el modelo de color indexado, el color actual es<br />

seleccionado llamando a la función:<br />

void glIndex{sifd ub} (TYPE c );<br />

void glIndex{sifd ub}v (const TYPE *c );<br />

Sintaxis de la función glIndex:


Colores y <strong>sombras</strong> 38<br />

• Propósito: Selecciona el índice de color actual para usar con las<br />

operaciones de color.<br />

• Fichero de inclusión: <br />

• Sintaxis:<br />

• void glIndexd( GLdouble c);<br />

• void glIndexf( GLfloat c);<br />

• void glIndexi( GLint c);<br />

• void glIndexs( GLshort c);<br />

• void glIndexdv( const GLdouble *c);<br />

• void glIndexfv( const GLfloat*c);<br />

• void glIndexiv( const GLint *c);<br />

void glIndexsv( const GLshort *c);<br />

• Descripción: Esta función cambia el índice de color actual al<br />

especificado por c.<br />

• Parámetros:<br />

c<br />

El índice del nuevo color para uso en las siguientes operaciones.<br />

*c<br />

Un puntero al índice del nuevo color para uso en las siguientes<br />

operaciones.<br />

• Retornos: Ninguno.<br />

En el modelo RGBA vimos la especificación de glClearColor(), para el<br />

modelo de color indexado existe su análogo que es glClearIndex().<br />

Formato de la instrucción glClearIndex:<br />

• Propósito: Especifica un índice de color para el buffer de<br />

color.<br />

• Fichero de inclusión: <br />

• Sintaxis: void glClearIndex(GLfloat indice);<br />

• Descripción: Selecciona el valor de color que usaremos<br />

para borrar el buffer de color con<br />

glClear(GL_COLOR_BUFFER_BIT).<br />

• Parámetros:<br />

índice<br />

GLfloat: el índice de color para el buffer de color.<br />

• Retornos: Ninguno.<br />

Para especificar el modo indexado de color debemos seleccionar el<br />

miembro iPixelType de la estructura PIXELFORMATDESCRIPTOR como se<br />

muestra a continuación:


Colores y <strong>sombras</strong> 39<br />

PIXELFORMATDESCRIPTOR pfd; //declaración estructura<br />

pfd.iPixelType = PFD_TYPE_COLORINDEX; //Selección modo<br />

indexado de color<br />

Si por el contrario trabajamos con el modo RGBA de color<br />

seleccionaremos el miembro iPixelType de la estructura<br />

PIXELFORMATDESCRIPTOR de esta manera:<br />

pfd.iPixelType = PFD_TYPE_RGBA; //Selección<br />

modo RGBA de color<br />

Pegar código paleta.c<br />

/////////////////////////////////////////////////////<br />

// Principal o punto de entrada para todos los<br />

programas Windows<br />

/////////////////////////////////////////////////////<br />

int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE<br />

hPreviousInst,<br />

{<br />

LPSTR lpszCmdLine, int nCmdShow)<br />

HGLRC hRC; // Contexto para OpenGL<br />

HWND hWnd; // Almacenamiento<br />

para la gestion de Ventana<br />

MSG msg; // Estructura de<br />

mensajes de Windows<br />

buffer<br />

color<br />

DWORD buffer = PFD_DOUBLEBUFFER; // tipo de<br />

BYTE color = PFD_TYPE_RGBA; // tipo de<br />

// Si en la llamada a la aplicación se ha<br />

incluido el parámetro -sb<br />

if (strstr(lpszCmdLine, "-sb")) { // Modo RGB<br />

}<br />

buffer = 0;


Colores y <strong>sombras</strong> 40<br />

// Si en la llamada a la aplicación se ha<br />

incluido el parámetro -ci<br />

color Indexado<br />

if (strstr(lpszCmdLine, "-ci")) {<br />

}<br />

color = PFD_TYPE_COLORINDEX; // Modo de<br />

// Si en la llamada a la aplicación se ha<br />

incluido el parámetro -h<br />

el tipo<br />

if (strstr(lpszCmdLine, "-h")) {<br />

}<br />

//Mostramos ayuda<br />

MessageBox(NULL, "paleta [-ci] [-sb]\n"<br />

" -sb single buffered\n"<br />

" -ci color index\n",<br />

"Usage help", MB_ICONINFORMATION);<br />

exit(0); //saliendo!!<br />

// Crea la ventana principal de la aplicación con<br />

// y buffer de color seleccionado<br />

hWnd = CreateOpenGLWindow("paleta", 0, 0, 256,<br />

256, color, buffer);<br />

if (hWnd == NULL)<br />

salimos del programa!!<br />

// Si no se puede crear correctamente<br />

exit(1);<br />

// Almacena el contexto de dispositivo<br />

hDC = GetDC(hWnd);<br />

// Crea el contexto de generación y lo activa<br />

hRC = wglCreateContext(hDC);<br />

wglMakeCurrent(hDC, hRC);<br />

// Visualiza la ventana<br />

ShowWindow(hWnd, SW_SHOW);


Colores y <strong>sombras</strong> 41<br />

hasta que<br />

UpdateWindow(hWnd);<br />

while (1) //bucle infinito!!<br />

{<br />

PM_NOREMOVE)) {<br />

programa<br />

}<br />

rota, colorea, ...)<br />

}<br />

// Procesa los mensajes de la aplicación<br />

// la aplicación se cierra<br />

while(PeekMessage(&msg, hWnd, 0, 0,<br />

if(GetMessage(&msg, hWnd, 0, 0))<br />

{<br />

}<br />

else<br />

{<br />

}<br />

TranslateMessage(&msg);<br />

DispatchMessage(&msg);<br />

goto quit; //solicitada salida del<br />

// Le hace de todo al triangulo (lo dibuja,<br />

triangulo();<br />

//Solicitan salir del programa<br />

quit:<br />

activado<br />

// Deselecciona el contexto de generación<br />

wglMakeCurrent(NULL, NULL);<br />

ReleaseDC(hDC, hWnd);<br />

wglDeleteContext(hRC);<br />

//destruye la ventana window!<br />

DestroyWindow(hWnd);


Colores y <strong>sombras</strong> 42<br />

}<br />

// Borra la paleta si fue creada<br />

if (hPalette)<br />

DeleteObject(hPalette);<br />

return 0;<br />

/////////////////////////////////////////////////////<br />

// Creacion de la ventana para la aplicación<br />

/////////////////////////////////////////////////////<br />

HWND CreateOpenGLWindow(char* title, int x, int y, int<br />

width, int height,<br />

{<br />

BYTE type, DWORD flags)<br />

int n, pf;<br />

HWND hWnd; //<br />

Almacenamiento para la gestion de Ventana<br />

clase de Windows<br />

WNDCLASS wc; // Estructura de<br />

LOGPALETTE* lpPal; // Puntero a<br />

memoria para la paleta logica<br />

PIXELFORMATDESCRIPTOR pfd; // Descriptor<br />

del formato de pixel<br />

almacenamiento<br />

vez<br />

static HINSTANCE hInstance = 0; // Instancia de<br />

// Tan solo registro la clase de la ventana una<br />

// uso hInstance como un flag<br />

if (!hInstance) {<br />

hInstance = GetModuleHandle(NULL);<br />

// Registra el estilo de la Ventana<br />

wc.style = CS_OWNDC;


Colores y <strong>sombras</strong> 43<br />

ventana OpenGL<br />

wc.lpfnWndProc = (WNDPROC)WindowProc;<br />

wc.cbClsExtra = 0;<br />

wc.cbWndExtra = 0;<br />

wc.hInstance = hInstance;<br />

wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);<br />

wc.hCursor = LoadCursor(NULL, IDC_ARROW);<br />

// No se necesita para la brocha de fondo de la<br />

wc.hbrBackground = NULL;<br />

wc.lpszMenuName = NULL;<br />

wc.lpszClassName = "OpenGL";<br />

// Registra la clase de la ventana<br />

if (!RegisterClass(&wc)) {<br />

Window.", "Error", MB_OK);<br />

}<br />

}<br />

MessageBox(NULL, "RegisterClass() failed: "<br />

return NULL;<br />

"No puedo registrar la class<br />

// Crea la ventana principal de la aplicación<br />

hWnd = CreateWindow("OpenGL", title,<br />

WS_OVERLAPPEDWINDOW |<br />

hInstance, NULL);<br />

mostramos error!<br />

WS_CLIPSIBLINGS | WS_CLIPCHILDREN,<br />

x, y, width, height, NULL, NULL,<br />

// Si no se puede crear la ventana principal<br />

if (hWnd == NULL) {<br />

MessageBox(NULL, "CreateWindow() failed: No<br />

puedo crear la ventana.","Error", MB_OK);<br />

return NULL;


Colores y <strong>sombras</strong> 44<br />

}<br />

hDC = GetDC(hWnd);<br />

// No hay garantías de que el contenido de la<br />

pila que comienza en<br />

la estructura<br />

esta estructura<br />

// pfd este a 0, nos aseguramos de ello<br />

memset(&pfd, 0, sizeof(pfd));<br />

pfd.nSize = sizeof(pfd); // Tamaño de<br />

pfd.nVersion = 1; // Version de<br />

// Dibuja<br />

en la ventana (No en el mapa de bits), // Soporta llamada<br />

OpenGL en la ventana, flags<br />

pfd.dwFlags = PFD_DRAW_TO_WINDOW |<br />

PFD_SUPPORT_OPENGL | flags;<br />

pfd.iPixelType = type; // Tipo de pixel<br />

pfd.cColorBits = 32; // Tamaño del<br />

Buffer de Profundidad<br />

lo descrito por pfd<br />

// Escoge el formato de pixel que mejor encaje en<br />

pf = ChoosePixelFormat(hDC, &pfd);<br />

if (pf == 0) {<br />

MessageBox(NULL, "ChoosePixelFormat() failed: "<br />

ajuste!.", "Error", MB_OK);<br />

}<br />

return 0;<br />

"No encuentro un formato de píxel que se<br />

// Selecciona el formato de píxel para el<br />

contexto de dispositivo<br />

if (SetPixelFormat(hDC, pf, &pfd) == FALSE)<br />

{


Colores y <strong>sombras</strong> 45<br />

"<br />

"Error", MB_OK);<br />

}<br />

return 0;<br />

MessageBox(NULL, "SetPixelFormat() failed:<br />

"No encuentro el formato especificado.",<br />

//Toma el formato de píxel y recupera la<br />

descripcion del formato de píxel<br />

DescribePixelFormat(hDC, pf,<br />

sizeof(PIXELFORMATDESCRIPTOR), &pfd);<br />

necesita una paleta<br />

/* Si el tipo de píxel seleccionado es Index ó se<br />

entradas especificadas*/<br />

entonces realiza selecciona una paleta con las<br />

if (pfd.dwFlags & PFD_NEED_PALETTE ||<br />

pfd.iPixelType == PFD_TYPE_COLORINDEX) {<br />

n = 1 256) n = 256;<br />

lpPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +<br />

sizeof(PALETTEENTRY) * n);<br />

memset(lpPal, 0, sizeof(LOGPALETTE) +<br />

sizeof(PALETTEENTRY) * n);<br />

>palPalEntry[0]);<br />

lpPal->palVersion = 0x300;<br />

lpPal->palNumEntries = n;<br />

GetSystemPaletteEntries(hDC, 0, n, &lpPal-<br />

/* Si el tipo de píxel seleccionado es RGBA,<br />

entonces realiza selección


Colores y <strong>sombras</strong> 46<br />

se selecciona Indexado<br />

individual 1 a 1 */<br />

de las mascaras para RGB, si por el contrario<br />

hay que elegir los elementos de forma<br />

if (pfd.iPixelType == PFD_TYPE_RGBA) {<br />

int redMask = (1 pfd.cRedShift) & redMask) *<br />

lpPal->palPalEntry[i].peGreen =<br />

(((i >> pfd.cGreenShift) & greenMask) *<br />

lpPal->palPalEntry[i].peBlue =<br />

(((i >> pfd.cBlueShift) & blueMask) *<br />

lpPal->palPalEntry[i].peFlags = 0;<br />

/* Rellena las entradas con los <strong>colores</strong><br />

lpPal->palPalEntry[0].peRed = 0;<br />

lpPal->palPalEntry[0].peGreen = 0;<br />

lpPal->palPalEntry[0].peBlue = 0;<br />

lpPal->palPalEntry[0].peFlags =


Colores y <strong>sombras</strong> 47<br />

PC_NOCOLLAPSE;<br />

PC_NOCOLLAPSE;<br />

PC_NOCOLLAPSE;<br />

}<br />

lpPal->palPalEntry[1].peRed = 255;<br />

lpPal->palPalEntry[1].peGreen = 0;<br />

lpPal->palPalEntry[1].peBlue = 0;<br />

lpPal->palPalEntry[1].peFlags =<br />

lpPal->palPalEntry[2].peRed = 0;<br />

lpPal->palPalEntry[2].peGreen = 255;<br />

lpPal->palPalEntry[2].peBlue = 0;<br />

lpPal->palPalEntry[2].peFlags =<br />

lpPal->palPalEntry[3].peRed = 0;<br />

lpPal->palPalEntry[3].peGreen = 0;<br />

lpPal->palPalEntry[3].peBlue = 255;<br />

lpPal->palPalEntry[3].peFlags =<br />

//Crea la paleta<br />

hPalette = CreatePalette(lpPal);<br />

if (hPalette) {<br />

//Avanza, selecciona y realiza la paleta<br />

para este contexto de dispositivo<br />

}<br />

}<br />

}<br />

SelectPalette(hDC, hPalette, FALSE);<br />

RealizePalette(hDC);<br />

//libera la memoria de la estructura lpPal<br />

free(lpPal);<br />

ReleaseDC(hDC, hWnd);<br />

return hWnd;<br />

Listado 4 - Color indexado vs. Color RGBA


Colores y <strong>sombras</strong> 48<br />

Figura 29 - Paleta modelo de color RGB<br />

7.8.4. Modelo de color RGBA vs. Modelo de color Indexado<br />

Figura 30 - Paleta modelo de color Index<br />

No podemos usar el modo de color indexado y el modo de color RGBA<br />

juntos. Esto significa que si usamos el modo indexado en un dispositivo de<br />

color real, no tendremos acceso a todos los <strong>colores</strong> disponibles. Bajo algunas<br />

implementaciones, la paleta de color indexado puede tener hasta 4096<br />

entradas; sin embargo, la implementación de Microsoft sólo soporta 256<br />

entradas.<br />

Además de limitar la selección de <strong>colores</strong>, el modo indexado de color no<br />

soporta otros efectos especiales de OpenGL, incluidos muchos efectos de<br />

iluminación y sombreado, niebla, anti-escalonado y mezcla alfa. Generalmente<br />

es mejor usar el modo RGBA. La ventaja más significativa de usar el indexado<br />

es un mayor control de la paleta en dispositivos de pantalla de 8 bits.<br />

Nuestra decisión en la utilización de modelo de color RGBA o Indexado<br />

puede basarse en el hardware disponible y en las necesidades de nuestra<br />

aplicación. Para la mayoría de sistemas muchos <strong>colores</strong> pueden ser<br />

representados simultáneamente tanto con el modelo de color RGBA como con<br />

el modelo de color Indexado. Sin embargo, en muchos efectos como el<br />

sombreado, la iluminación, mapeado de texturas y niebla, el modelo RGBA<br />

proporciona una mayor flexibilidad que el modelo de color indexado.<br />

Podemos optar por utilizar el modelo de color indexado en tres casos:<br />

1. Si estamos migrando una aplicación que hace un uso importante del<br />

modelo de color indexado es más sencillo no cambiarlo al modelo RGBA.


Colores y <strong>sombras</strong> 49<br />

2. Si disponemos de un pequeño numero de planos de color el modelo<br />

RGBA puede producir sombreados de color de baja calidad. Por ejemplo,<br />

si sólo disponemos de 8 planos de color con el modelo RGBA sólo<br />

dispondremos de 3 bits para el rojo, 3 bits para el verde y 2 para el azul,<br />

es decir, 8 (2 3 ) <strong>sombras</strong> de rojo y verde, y sólo 4 de azul.<br />

En esta situación si tenemos limitados los requerimientos de sombreado<br />

podemos utilizar una tabla de búsqueda de color para obtener mas<br />

<strong>colores</strong> de sombra. Por ejemplo, si requerimos sólo <strong>sombras</strong> azules se<br />

puede utilizar el modelo de color indexado y almacenar 256 (2 8 ) <strong>sombras</strong><br />

de color azul, esto es mucho mejor que las 4 <strong>sombras</strong> que nos ofrecía el<br />

modelo de color RGBA.<br />

3. El modelo de color indexado puede ser utilizado para hacer varios<br />

trucos, como mapas de color, animaciones y dibujo por capas.<br />

En general, utilizaremos el modelo de color RGBA siempre que sea<br />

posible ya que permite mapeado de texturas y trabaja mejor con sombreado,<br />

iluminación, niebla, antialiasing y combinación de <strong>colores</strong> (blending).<br />

7.8.5. Ocultaciones<br />

OpenGL permite utilizar dos métodos de ocultación: el algoritmo de las<br />

caras de detrás (Back Face Removal), y el algoritmo del Z-buffer.<br />

7.8.5.1. Algoritmo de las caras de detrás<br />

Consiste en ocultar las caras que no se dibujarían porque formarían<br />

parte de la parte trasera del objeto. Para decirle a OpenGL que queremos<br />

activar este método de ocultación, tenemos que escribir:<br />

glEnable(GL_CULL_FACE)


Colores y <strong>sombras</strong> 50<br />

Figura 32 - Ocultando caras de detrás<br />

Figura 31 - Sin ocultaciones<br />

Importante. OpenGL ignora totalmente la normal que le podamos pasar<br />

con la función glNormalf, así que esta normal sólo se utiliza a efectos de<br />

iluminación. A efectos de ocultación de caras, OpenGL decide si oculta o no<br />

una cara a partir del orden de definición de los vértices que la forman.<br />

Así, si la proyección sobre del camino que forman los vértices del<br />

primero al último es en el sentido de las agujas del reloj, entonces se dice que<br />

el orden es clockwise. Si es en sentido inverso, se dice que es<br />

counterclockwise. Por defecto, OpenGL sólo renderiza aquellos polígonos<br />

cuyos vértices estan en orden counterclockwise cuando son proyectados<br />

sobre la ventana. Pero los objetos definidos por la GLUT no tienen porqué estar<br />

definidos clockwise (como es el caso de la tetera). Por tanto, antes de<br />

renderizarlos usando este algoritmo de ocultación, debemos llamar a<br />

glFrontFace(GL_CW) o a glFrontFace(GL_CCW).<br />

7.8.5.2 Algoritmo del Z-buffer<br />

El algoritmo del Z-buffer es del tipo espacio-imagen. Cada vez que se va<br />

a renderizar un pixel, comprueba que no se haya dibujado antes en esa<br />

posición un pixel que esté más cerca respecto a la cámara. Este algoritmo<br />

funciona bien para cualquier tipo de objetos: cóncavos, convexos, abiertos y<br />

cerrados. Para activarlo, hay que hacer una llamada a:<br />

glEnable(GL_DEPTH_TEST)


Colores y <strong>sombras</strong> 51<br />

Esta llamada le dice a OpenGL que active el test de profundidad.<br />

Además, cada vez que se redibuje la escena, a parte de borrar el buffer de<br />

color, hay que borrar el buffer de profundidad. Esto se hace con la llamada:<br />

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT).<br />

Por último, pero no menos importante, al inicializar OpenGL se le tiene<br />

que decir que cree el buffer de profundidad. Esto se hace al definir el modo de<br />

visualización (ver capítulo GLUT).<br />

Figura 33 - Sin Z-Buffer Figura 34 - Con Z-Buffer<br />

7.8.5.3. Combinando ambos algoritmos<br />

El algoritmo de la eliminación de las caras de detrás es suficiente para<br />

renderizar para objetos convexos y cerrados, como este octahedro, pero para<br />

objetos cóncavos y cerrados no basta. Por ejemplo, un objeto con una cara<br />

parcialmente oculta, como el de la figura, no tiene porqué renderizarse bien:<br />

Figura 35 - Sin ocultaciones Figura 36 - Eliminando caras de detrás<br />

Ahora bien, si sabemos que todos nuestros objetos están cerrados, es<br />

decir, no se ve el interior, podemos combinarlo con el Z-buffer, ya que<br />

descartaremos ya para empezar las caras que no vamos a ver, ganando así en<br />

velocidad de renderización.


Colores y <strong>sombras</strong> 52<br />

Figura 37 - Z-Buffer Figura 38 - Caras de detrás + Z-Buffer<br />

Ahora bien, la combinación de estos dos algoritmos no siempre es<br />

adecuada. En el caso de la tetera, por ejemplo, puesto que la tapa no está<br />

perfectamente ajustada a la tetera, y por tanto, queda un hueco (es decir, se ve<br />

el interior) ¡Si utilizamos el algoritmo de las caras de detrás veremos a través!<br />

Por tanto, en este caso lo mejor es utilizar sólo el algoritmo del Z-buffer.<br />

Figura 39 - Caras de detrás + Z-Buffer Figura 40 - Sólo Z-Buffer<br />

7.8.6. El color de los materiales<br />

La forma en que la luz incide sobre las superficies de los objetos<br />

depende de las propiedades del material de los mismos. En OpenGL la forma<br />

de definir estas propiedades es la función glMaterial cuya sintaxis es void<br />

glMaterial{if}[v](GLenum face, GLenum pname, TYPEparam);<br />

El primer argumento determina la cara del objeto donde se aplica el<br />

material, puede tomar los valores GL_FRONT, GL_BACK, o<br />

GL_FRONT_AND_BACK.<br />

El siguiente argumento indica la propiedad del material que va a fijarse<br />

(sus posibles valores se muestran en la tabla). Finalmente, el argumento param<br />

permite asignar los valores a la propiedad pname.


Colores y <strong>sombras</strong> 53<br />

Nombre del parámetro Valor por<br />

defecto<br />

GL_AMBIENT (0.2, 0.2, 0.2,<br />

1.0)<br />

GL_DIFFUSE (0.8, 0.8, 0.8,<br />

1.0)<br />

Significado<br />

ambient color of material<br />

diffuse color of material<br />

GL_AMBIENT_AND_DIFFUSE ambient and diffuse color of<br />

GL_SPECULAR (0.0, 0.0, 0.0,<br />

1.0)<br />

material<br />

specular color of material<br />

GL_SHININESS 0.0 specular exponent<br />

GL_EMISSION (0.0, 0.0, 0.0,<br />

1.0)<br />

emissive color of material<br />

GL_COLOR_INDEXES (0,1,1) ambient, diffuse, and specular<br />

Reflexión ambiente y difusa<br />

color indices<br />

La reflexión difusa determina el color de un objeto y la reflexión ambiente<br />

la forma en que el objeto redistribuye la luz ambiente que recibe. Los objetos<br />

del mundo real suelen tener el mismo color de reflexión ambiente y difusa.<br />

Reflexión especular<br />

La componente especular define el color de los brillos del objeto cuya<br />

forma se controla con el parámetro GL_SHININESS de modo que cuando<br />

mayor sea este parámetro el brillo aparecerá más concentrado.<br />

Emisión<br />

OpenGL permite asignar a los objetos un color de emisión para que<br />

parezca que dichos objetos emiten luz de un color, lo que permite simular<br />

lámparas y objetos luminosos. Se pueden conseguir mejores efectos simulando<br />

fuentes de luz en la misma posición que los objetos para los que se define un<br />

color de emisión.<br />

Cambio de las propiedades del material<br />

Para minimizar el coste asociado a la realización de cambios en las<br />

propiedades del material se usa la función glColorMaterial cuya sintaxis es la<br />

siguiente:


Colores y <strong>sombras</strong> 54<br />

Propósito: Permite que los <strong>colores</strong> del material sigan el color definido<br />

por glColor.<br />

• Fichero de inclusión: <br />

• Sintaxis: void glColorMaterial(GLenum cara, GLenum modo);<br />

• Descripción: Esta función permite seleccionar las propiedades de un<br />

material sin tener que llamar directamente a glMaterial. Usando esta<br />

función, podemos definir ciertas propiedades del material siguiendo<br />

el color especificado actualmente por glColor. Para habilitar el<br />

seguimiento, llamaremos a glEnable(GL_COLOR_MATERIAL).<br />

• Parámetros:<br />

func<br />

• Retornos: Ninguno.<br />

Cara podrá tomar los valores GL_FRONT_AND_BACK, GL_FRONT o<br />

GL_BACK y modo GL_AMBIENT_AND_DIFFUSE, GL_DIFFUSE,<br />

GL_SPECULAR o GL_EMISIÓN.<br />

Una vez que se realiza la llamada a la función, se puede cambiar el color<br />

de la propiedad que indica el parámetro modo para la cara definida en cara<br />

usando glColor.<br />

Después de llamar a la función glColorMaterial es necesario realizar<br />

una llamada a glEnable con el argumento GL_COLOR_MATERIAL.<br />

glColorMaterial(GL_FRONT, GL_DIFFUSE);<br />

glEnable(GL_COLOR_MATERIAL);<br />

glColor3f(0.2, 0.5, 0.8);<br />

......../* dibujamos algo aquí */<br />

glColor3f(0.9, 0.0, 0.2);<br />

......... /*y otros */<br />

glDisable(GL_COLOR_MATERIAL);<br />

Veamos un ejemplo de todo esto:<br />

#include <br />

Listado 5 - Definiciones para materiales


Colores y <strong>sombras</strong> 55<br />

#include <br />

#include <br />

GLfloat mat_diffuse [] = {0.5, 0.5,<br />

0.5, 1.0};<br />

GLfloat mat_specular [] = {0.5, 0.5,<br />

0.5, 1.0};<br />

GLfloat mat_shininess [] = {50};<br />

void init (void)<br />

{<br />

GLfloat light_position[] = {1.0, 1.0,<br />

1.0, 0.0};<br />

glLightfv(GL_LIGHT0, GL_POSITION,<br />

light_position);<br />

glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);<br />

glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);<br />

glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);<br />

glEnable (GL_LIGHTING);<br />

glEnable (GL_LIGHT0);<br />

glDepthFunc(GL_LEQUAL);<br />

glEnable (GL_DEPTH_TEST);<br />

}<br />

void display (void)<br />

{<br />

int i,j;<br />

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />

for (i=-1; i


Colores y <strong>sombras</strong> 56<br />

glTranslatef((float)i*3.0,(float)j*3.0,0.0);<br />

}<br />

}<br />

}<br />

glutSwapBuffers();<br />

glutSolidSphere(1.0,16,16);<br />

glPopMatrix();<br />

void reshape(int w, int h)<br />

{<br />

glViewport ( 0, 0, w, h );<br />

glMatrixMode ( GL_PROJECTION );<br />

glLoadIdentity ( );<br />

if ( h==0 )<br />

else<br />

1.0, 20.0 );<br />

gluPerspective ( 60, ( float ) w, 1.0, 20.0 );<br />

gluPerspective ( 60, ( float ) w / ( float ) h,<br />

glMatrixMode ( GL_MODELVIEW );<br />

glLoadIdentity ( );<br />

gluLookAt(0.0,0.0,10.0,0.0,0.0,0.0,0.0,1.0,0.0);<br />

}<br />

/* Ciclo principal<br />

* Abre una ventana con tamaño inicial definido, barra de<br />

titulo,<br />

* modo RGB, y control de eventos */<br />

int main (int argc, char** argv)<br />

{<br />

glutInit (&argc, argv);


Colores y <strong>sombras</strong> 57<br />

glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE |<br />

GLUT_DEPTH);<br />

glutInitWindowSize (250,250);<br />

glutInitWindowPosition (100,100);<br />

glutCreateWindow ("Ejemplo de luz");<br />

init ();<br />

/* llamada a inicializacion*/<br />

glutReshapeFunc (reshape); /* llamada<br />

para eventos de reshape de ventana*/<br />

glutDisplayFunc (display); /* llamada<br />

para dibujar...*/<br />

glutMainLoop (); /* Crea la<br />

ventana y dibuja...*/<br />

}<br />

Listado 6 - Ejemplo uso de propiedades de materiales


Colores y <strong>sombras</strong><br />

7.9. Sombras<br />

Una sombra es una región de oscuridad donde la luz es obstaculizada.<br />

Una sombra ocupa todo el espacio de detrás de un objeto opaco con una<br />

fuente de luz frente a él. La sección eficaz de una sombra es una silueta<br />

bidimensional o una proyección invertida del objeto que bloquea la luz.<br />

Cuanto menor es el ángulo entre la dirección de la luz y un objeto<br />

alargado que la obstaculice, más corta será su sombra. Por otro lado, cuanto<br />

menor sea el ángulo entre la dirección de la luz y la superficie en la que<br />

aparece la sombra, más larga será ésta. Si el objeto está cerca de la fuente<br />

luminosa, la sombra será mayor que si el objeto se encuentra lejos. Si la<br />

superficie está curvada, habrá más distorsiones.<br />

Cuando la fuente de luz no es puntual, la sombra se divide en umbra y<br />

penumbra. Cuanto más ancha es la fuente de luz, más difuminada o borrosa<br />

será la sombra.<br />

Si hay múltiples fuentes luminosas, habrá múltiples <strong>sombras</strong>, con las<br />

partes solapadas más oscuras, o con una combinación de <strong>colores</strong>. Cuando una<br />

persona o un objeto está en contacto con la superficie, como una persona<br />

sentada en el suelo o un poste clavado, las <strong>sombras</strong> convergen al punto de<br />

contacto.<br />

Si sólo existe una fuente de luz, las <strong>sombras</strong> arrojadas por aquella serán<br />

siempre grises, sea cual sea el color de la fuente. En cambio, si existen dos<br />

fuentes de luz de distintos <strong>colores</strong>, supongamos rojo y azul, las <strong>sombras</strong><br />

proyectadas por cada una de ellas serán del color de la otra fuente de luz, y<br />

sólo la intersección de ambas <strong>sombras</strong> será gris. Es decir, la sombra de la luz<br />

roja será azul, pues está iluminada por la fuente azul, y viceversa. En el caso<br />

de que existan más fuentes de luz, cada sombra será del color resultante de la<br />

adición de las fuentes que aún iluminan esa zona, permaneciendo en gris las<br />

zonas donde intersecten las <strong>sombras</strong> de todas las fuentes luminosas.<br />

El proceso de sombreado o shading (en el contexto de los gráficos<br />

realizada por ordenador) implica la simulación de computadora (o más<br />

exactamente; el cálculo) como las caras de un polígono se comportarán<br />

cuando es iluminado por una fuente de la luz virtual. El cálculo exacto varía<br />

según no sólo que datos están disponibles sobre la cara sombreada, sino<br />

también la técnica de sombreado.<br />

Generalmente este afecta propiedades de la especularidad y valores de<br />

intensidad, reflexión y transparencia.<br />

Este proceso se realiza durante el renderizado.<br />

El sombreado altera el color de las caras de un modelo 3D basándose<br />

en el ángulo de la superficie con la fuente de luz. Las siguientes imágenes<br />

muestran las diferencias:<br />

58


Colores y <strong>sombras</strong><br />

Figura 42 Imagen renderizada de una caja.<br />

Esta imagen no tiene sombreado de las caras, pero usa líneas en los<br />

bordes para separar las caras.<br />

Figura 43 Imagen sin líneas en los bordes<br />

Aquí se observa como el sombreado altera el color de las 3 caras<br />

basándose en el ángulo de las fuentes de luz.<br />

Figura 44 Imagen son sombreado en las caras<br />

59


Colores y <strong>sombras</strong><br />

7.9.1 Efecto falloff (Distance falloff)<br />

Teóricamente, dos superficies que son paralelas son iluminadas con la<br />

misma intensidad por una fuente de luz distante, como por ejemplo el sol.<br />

Incluso si una superficie está más distante, el ojo ve más en el mismo espacio,<br />

por eso la iluminación parece la misma.<br />

Nótese que en la primera imagen el color de las caras frontales de las<br />

dos cajas son exactamente iguales. Parece que hay una pequeña diferencia en<br />

el punto de encuentro de las caras, pero esto es una ilusión óptica causada por<br />

el borde vertical debajo de donde se encuentran las caras.<br />

En la segunda imagen se puede observar que las superficies de las<br />

caras son brillantes en la caja delantera y más oscuras en la situada en la parte<br />

de atrás. También la superficie sobre la que están pasa de claro a oscuro<br />

según se aleja.<br />

Este efecto falloff produce imágenes que parezcan más realistas.<br />

Figura 45 Cajas renderizadas con OpenGL<br />

Figura 46 Cajas renderizadas con ARRIS CAD, efecto falloff<br />

Un modelo de intensidad puede aplicarse al sombreado de superficies de<br />

varias formas dependiendo del tipo de superficie y de los requisitos de la<br />

aplicación. Los objetos con varias superficies suelen sombrearse de forma<br />

realista con una sola intensidad por cada superficie. Para una superficie curva<br />

60


Colores y <strong>sombras</strong><br />

podríamos aplicar el modelo de intensidad a cada punto de la superficie;<br />

aunque esto produce un efecto muy realista es un proceso muy lento.<br />

Para acelerar el proceso se podría representar una superficie curva<br />

como un conjunto de polígonos y aplicar el modelo de sombreado a cada<br />

plano. Cada una de estas superficies poligonales podría sombrarse después<br />

con intensidad constante o bien podríamos variar el sombrado con valores de<br />

intensidad interpolados.<br />

Los algoritmos de superficies visibles determinan qué superficies ve el<br />

ojo dependiendo de su posición. Los algoritmos de <strong>sombras</strong> determinan que<br />

objetos se ven desde la fuente de luz. Por tanto, estos dos tipos de algoritmos<br />

son esencialmente iguales. Las superficies visibles desde la fuente de luz están<br />

iluminadas, las no visibles están en sombra.<br />

Cuando hay múltiples fuentes de luz una superficie debe clasificarse<br />

respecto a cada fuente de luz. Consideraremos en este tema algoritmos de<br />

sombra para fuentes de luz puntuales. La visibilidad a partir de una fuente<br />

puntual de luz es como la visibilidad en el ojo: “todo o nada”.<br />

Cuando un punto en la superficie no puede verse desde una fuente<br />

puntual de luz, el cálculo de iluminación debe ajustarse para tenerlo en cuenta.<br />

Las áreas en la sombra de todas las fuentes puntuales de luz todavía<br />

están iluminadas por la luz ambiente.<br />

Aunque la utilización de <strong>sombras</strong> requiere el cálculo de la visibilidad de la<br />

fuente de luz, pueden generarse <strong>sombras</strong> falsas sin hacer pruebas de<br />

visibilidad.<br />

7.9.2 Sombreado<br />

La intensidad de luz que se observa en cada superficie de un objeto<br />

depende del tipo de fuentes de luz que la ilumine y de las características de la<br />

superficie del objeto. Algunos objetos tienen superficies brillantes y otros<br />

opacas o mate. Además, algunos objetos se construyen con materiales opacos,<br />

mientras que otros son mas o menos trasparentes. Un modelo de sombreado<br />

para producir intensidades realistas sobre las superficies de un objeto debe<br />

considerar estas propiedades.<br />

Los patrones de sombra generados por un método de superficie oculta<br />

son validos en cualquier posición de visión seleccionada siempre que las<br />

posiciones de la fuente de luz no se alteren. Las superficies que son visibles<br />

desde la posición de visión se sombrean según el modelo de intensidad, con<br />

patrones de superficie y <strong>sombras</strong> anexados. Las superficies visibles que no son<br />

iluminadas por una fuente de punto se les aplica únicamente intensidad de luz<br />

ambiental. Las superficies visibles que son iluminadas por una fuente de puntos<br />

61


Colores y <strong>sombras</strong><br />

se sombrean combinando el modelo de intensidad y la lista de patrones. Las<br />

áreas de sombra proyectada se sombrean únicamente con la intensidad de la<br />

luz ambiental.<br />

Asumiendo que se puede computar vectores normales, dado un conjunto<br />

de fuentes de luz y un observador, los modelos de luz e iluminación<br />

desarrollados pueden aplicarse a cada punto de una superficie.<br />

Lamentablemente, aunque se tenga ecuaciones sencillas para determinarlos<br />

vectores normales, la cantidad de computaciones requeridas puede ser muy<br />

grande. Se han visto muchas de las ventajas de usar modelos poligonales para<br />

los objetos. Una ventaja adicional, para polígonos planos, es que se puede<br />

reducir bastante el trabajo requerido para el sombreado. La mayoría de los<br />

sistemas gráficos, incluyendo OpenGL, explota las posibles eficiencias para<br />

polígonos planos, descomponiendo superficies curvas en muchos polígonos<br />

planos pequeños, cada uno teniendo un vector normal bien definido.<br />

7.9.3 Tipos de sombreado<br />

7.9.3.1 Sombreado plano (Flat Shading)<br />

Es una técnica usada en gráficos 3D en la que se sombrea cada<br />

polígono de un objeto basándose en el ángulo que existe entre la superficie<br />

normal del polígono y la dirección de la fuente de luz, sus respectivos <strong>colores</strong> y<br />

la intensidad de la luz. Es el tipo de sombreado utilizado para el renderizado de<br />

alta velocidad donde técnicas de sombreado más avanzadas tienen un coste<br />

computacional excesivo.<br />

La desventaja del sombreado de intensidad constante es que da a los<br />

modelos con un número bajo de polígonos un aspecto poco natural, formado<br />

por múltiples caras. A veces esta apariencia puede ser ventajosa, como al<br />

modelar objetos poligonales. Los diseñadores a veces usan esta técnica para<br />

observar las diferentes caras del objeto que están creando.<br />

Bajo ciertas restricciones se puede obtener un sombreado realista en un<br />

objeto con superficies planas utilizando intensidades con superficies<br />

constantes. Si el objeto está únicamente expuesto a luz ambiental y no se<br />

aplican texturas, <strong>sombras</strong> de superficie, etc., el sombreado de intensidad<br />

constante genera representaciones exactas de la superficie del objeto. Para<br />

objetos cuya superficie se ilumina con un foco de luz puntual el modelo produce<br />

una superficie de intensidad constante siempre que el punto de referencia<br />

visual y el foco estén suficientemente alejados de la superficie del objeto. Si por<br />

el contrario el foco está alejado de la superficie no hay variación en la dirección<br />

hacia la fuente. La dirección hacia un punto de visión distinto no cambiara<br />

sobre una superficie, por lo tanto V.R = cte.<br />

Si se representa mediante un conjunto de superficies planas una<br />

superficie curva y los planos que subdividen esta superficie se hacen lo<br />

suficientemente pequeños. Se pueden sombrear con intensidades de superficie<br />

constante.<br />

62


Colores y <strong>sombras</strong><br />

Cuando la orientación entre planos adyacentes cambia en forma<br />

abrupta, la diferencia en intensidades de superficie puede producir un efecto<br />

áspero e irreal. Se pueden aliar las discontinuidades de intensidad en estos<br />

casos variando la intensidad sobre cada superficie de acuerdo con algún<br />

esquema de interpolación.<br />

Existen otro tipo de técnicas de sombreado más avanzadas como el<br />

sombreado de Gouraud y el sombreado de Phong.<br />

Figura 47 Comparación de las técnicas de sombreado<br />

7.9.3.2 Sombreado de Gouraud<br />

Creada en 1971 y llamada así en honor a Henri Gouraud, este método<br />

es usado para simular el efecto de difusión de de la luz y los <strong>colores</strong> a través<br />

de la superficie del objeto, esta técnica consigue alcanzar el sombreado de<br />

superficies con pocos polígonos sin el alto coste computacional de calcular la<br />

iluminación de cada píxel.<br />

El sombreado de Gouraud aplica el patrón de iluminación a cada<br />

vértice del polígono y entonces promedia los valores de color en toda la<br />

superficie del objeto para así alcanzar un efecto de sombreado suave<br />

que parece más realista sobre superficies curvas.<br />

Este método de sombreado se emplea para disimular los polígonos<br />

cuando éstos se emplean para aproximar una superficie curva, como una<br />

esfera o un toroide, por ejemplo.<br />

El método es el siguiente: primero calculamos las normales a la<br />

superficie en los vértices de los polígonos. Esta normal en cada punto podemos<br />

calcularla de dos maneras: 1ª-basándonos las características de la superficie<br />

que vamos a aproximar, por ejemplo si se trata de una esfera, sabemos que la<br />

normal va a ir en dirección opuesta al centro de la esfera. 2ª- Si no conocemos<br />

la superficie que estamos aproximando, podemos sumar todas las normales de<br />

los polígonos de los que forme parte ese vértice y normalizar el resultado.<br />

63


Colores y <strong>sombras</strong><br />

Una vez hecho esto, calculamos por los procedimientos de iluminación<br />

vistos anteriormente el color que correspondería a cada vértice. Después,<br />

cuando vamos a dibujar el polígono, vamos interpolando linealmente a través<br />

de cada arista entre los dos <strong>colores</strong> de los extremos de dicha arista, y por<br />

último al ir trazando las líneas horizontales (o scanlines) que forman el<br />

polígono, interpolamos de nuevo linealmente entre los dos valores que<br />

correspondan a los puntos de las dos aristas entre las que estemos trazando la<br />

línea horizontal. El resultado final de todo esto es un polígono con un suave<br />

gradiente de intensidades sobre su superficie.<br />

Se puede ver gráficamente esto con el ejemplo de<br />

la figura 48, en la que conocemos los valores de la<br />

intensidad en los puntos 1 2 y 3. Al ir dibujando el<br />

triángulo, calculamos los valores del primer y el ultimo<br />

píxel del triangulo en cada línea interpolando, a lo largo<br />

de las aristas, los valores de los vértices. Esto nos da el<br />

valor inicial y el final de cada línea horizontal, y para<br />

rellenarla solo tenemos que interpolar linealmente de<br />

nuevo los estos valores a lo largo de la línea.<br />

Un vector normal a una superficie es un vector<br />

que apunta en una dirección perpendicular a dicha<br />

superficie. Si partimos de un triángulo, con tres vértices<br />

P1, P2 y P3, el procedimiento para calcular la normal es<br />

muy sencillo; se escoge un punto como origen, digamos<br />

P2, y se calculan los vectores v1=P1-P2, y v2=P3-P2;<br />

calculamos el producto vectorial entre V1 y V2, y nos sale<br />

el vector normal.<br />

Además, puesto que el vector normal prácticamente<br />

solo se va a usar para calcular su ángulo con otros<br />

vectores, es muy útil hacer que su módulo sea uno,<br />

dividiendo cada una de las componentes (x,y,z) entre el<br />

módulo del vector.<br />

En la figura se ve un triángulo con su vector normal. Una cosa que hay<br />

que tener en cuenta al calcular un vector normal a un triangulo, es que el<br />

producto vectorial no cumple la propiedad<br />

conmutativa, o sea que hay que tener cuidado<br />

porque según en que orden se multipliquen v1 y v2<br />

el vector normal puede apuntar en una dirección o<br />

en la opuesta.<br />

La aplicación de las normales a la hora de<br />

acelerar el dibujado de polígonos es la siguiente:<br />

como normalmente los triángulos se usan para<br />

representar aproximaciones a superficies, como por<br />

ejemplo esferas, se puede considerar que tales<br />

64<br />

Figura 48 - Scanlines<br />

Figura 49 - Normal<br />

Figura 50 - Normales


Colores y <strong>sombras</strong><br />

superficies tienen una cara interior que no se ve (el interior de la esfera, p ej) y<br />

una exterior que si se ve. Entonces, podemos calcular las normales a los<br />

triángulos asegurándonos de que apunten al exterior de la superficie, y<br />

después eliminar los polígonos cuya normal no apunte en dirección a la<br />

pantalla, porque se entiende que estamos viendo su parte trasera y por tanto<br />

no se dibuja. En la figura vemos un ejemplo en 2D de este método. En este<br />

caso, hay una serie de segmentos que aproximan una circunferencia.<br />

Descartamos por medio de las normales las caras 4, 5, 6 y 7 y dibujamos las<br />

caras 1 2 y 3. A estas tres caras que vamos a dibujar hay que aplicarles otro<br />

algoritmo para verificar superficies ocultas, como el del pintor o el buffer z, ya<br />

que el método de las normales no garantiza que las caras que apuntan hacia la<br />

cámara no vayan a estar parcial o totalmente tapadas por otro objeto.<br />

Algunas veces los objetos sombreados con Gouraud muestran las zonas<br />

de unión de polígonos conocido como el efecto de la banda de Mach. Este<br />

fenómeno es una consecuencia de como se conectan los conos al nervio óptico<br />

en el ojo, y no hay nada que se pueda hacer al respecto, fuera de buscar<br />

técnicas de sombreado mas suaves que no produzcan grandes diferencias en<br />

sombreado en los bordes de los polígonos.<br />

7.9.3.3 Sombreado de Phong<br />

Figura 51 Sombreado Gouraud banda de Mach<br />

Es el método usado en los gráficos 3D para la interpolación de<br />

superficies en el pasterizado de polígonos, para obtener mejor resolución<br />

especular que en las generadas en el modelo de reflexión de Pong.<br />

Este método fue desarrollado por Bui Tuong Phong en 1973 en la<br />

universidad de Utah. El modelo de reflexión de Phong es un modelo de<br />

iluminación local que puede producir un cierto grado de realismo en los objetos<br />

3D mediante la combionación de e elementos: difusión, reflexión especular y<br />

luz ambiente para cada punto de la superficie considerada.<br />

65


Colores y <strong>sombras</strong><br />

La interpolación de Phong , como método de renderizado, se peude<br />

considerar como una mejora del sombreado de Gouraud que proporciona una<br />

mejor aproximación a la aplicación punto-por-punto de un modelo de reflexión<br />

superficial, asumiendo una suavidad variante de la superficie como vector<br />

normal.<br />

Para ello se determina el vector normal promedio en cada vértice del<br />

polígono. Se interpola linealmente los vértices normales sobre la superficie del<br />

polígono. Se aplica un modelo de iluminación sobre los puntos de la superficie<br />

utilizando las normales interpoladas.<br />

Phong propuso que, en lugar de interpolar intensidades de los vértices,<br />

según se hace en el sombreado Gouraud, se interpole normales a lo largo del<br />

polígono. Para un polígono que comparte lados y vértices con otros polígonos,<br />

Figura 52 - Esquema<br />

se pueden computar normales en los vértices interpolando sobre las normales<br />

de los polígonos que comparten el vértice. Luego, se puede usar interpolación<br />

bilineal, para interpolar las normales sobre el polígono<br />

Figura 53 - Esquema<br />

Se puede usar las normales interpoladas en los vértices A y B para<br />

interpolar a lo largo de lado entre ellas:<br />

n( ) = (1- )nA + nB<br />

Se puede hacer una interpolación similar en todos los lados. LA normal<br />

en cualquier punto interior se puede obtener de los puntos en los lados<br />

mediante<br />

n( , ) = (1- )nC + nD<br />

66


Colores y <strong>sombras</strong><br />

Una vez obtenidas las normales en cada punto, se puede hacer cálculos<br />

de sombreado independientes. Normalmente, este proceso se combinará con<br />

la rasterización del polígono, para que la línea entre C y D proyecte a una línea<br />

de rastreo en el frame buffer.<br />

7.9.3.4 Sombreado Blinn–Phong<br />

Es una variante del modelo de reflexión de Phong que intercambia la<br />

precisión visual por eficiencia computacional.<br />

En sombrado de Phong solo se recalcula el ángulo R*V entre el<br />

observador (V) y el rayo de luz de la fuente (L) reflejado (R) en una superficie.<br />

Si en vez de eso se calcula el vector intermedio entre el observador y los<br />

vectores de las fuentes de luz:<br />

Podemos reemplazar R*V con N*H, este producto de puntos representa<br />

el coseno de un ángulo que es la mitad del ángulo representado por el producto<br />

de puntos de Phong si V,L y R se encuentran en el mismo plano. Esto produce<br />

modelos empíricos más certeros para determinar la distribución de las<br />

funciones de reflexión bidireccional que el modelo de Phong. Blinn-Phong es el<br />

modelo de sombreado por defecto que utiliza OpenGL y se lleva a todos los<br />

vértices según pasan por la tubería de gráficos, mientras que los valores de los<br />

pixeles entre los vértices son interpolados por el sombreado de Gouraud<br />

(menos costoso).<br />

Figura 54 Sombreado de Phong y Blinn-Phong<br />

67


Colores y <strong>sombras</strong><br />

7.9.4 Sombreado en OpenGL<br />

Se especifica la técnica de sombreado deseada con la función<br />

glShadeModel.<br />

Void glShadeModel(Glenum mode);<br />

El parámetro mod puede tener 2 valores GL_SMOOTH (por defecto) o<br />

GL_FLAT.<br />

7.9.4.1 Sombreado Plano (Flat)<br />

Los tres vectores, l, n y v, pueden variar según se va entre puntos sobre<br />

una superficie.<br />

*Para un polígono plano, n es constante.<br />

*Si se asume un observador distante (la bandera<br />

GL_DISTANT_VIEWER en OpenGL), v es constante sobre el polígono.<br />

*Si la fuente de luz es distante, l es constante.<br />

Distante se puede interpretar como una fuente o un observador en el<br />

infinito; en particular, si los polígonos son pequeños, las distancias relativas<br />

para el infinito no tienen que ser muy grandes. Los ajustes necesarios, como<br />

cambiar la ubicación de la fuente u observador a la dirección de la fuente u<br />

observador, de forma correspondiente, puede hacerse a las ecuaciones de<br />

sombreado y a su implementación.<br />

Si los tres vectores son constantes, entonces el cálculo de sombreado<br />

se lleva a cabo una sola vez para cada polígono, y se asignará la misma<br />

sombra a cada punto en el polígono. Esta técnica se conoce como sombreado<br />

plano o constante. En OpenGL, se especifica sombreado plano mediante<br />

glShadeModel(GL_FLAT);<br />

Si se usa sombreado plano, OpenGL usará las normales asociadas con<br />

el primer vértice de un polígono<br />

Sencillo para el cálculo de sombreado. Para primitivas como un strip de<br />

triángulo, OpenGL usa la normal del tercer vértice para el primer triángulo, la<br />

normal del cuarto vértice para el segundo, etc. Reglas similares se aplican para<br />

otras primitivas, como strips cuadriláteros.<br />

Sombreado plano mostrará diferencias de sombreado entre los<br />

polígonos. Si las fuentes de luz y el observador están cerca del polígono, los<br />

vectores v y l serán diferentes para cada polígono. Sin embargo, si los<br />

polígonos se diseñaron para modelar una superficie suave, sombreado plano<br />

no será el mas apropiado, ya que se verán aunque sea diferencias de<br />

sombreado pequeñas entre polígonos adyacentes.<br />

68


Colores y <strong>sombras</strong><br />

Figura 55 Variación se sombreado<br />

El sistema visual humano tiene una sensibilidad remarcada para<br />

pequeñas diferencias de intensidad de color, causada por la propiedad de<br />

inhibición lateral. Si se ve una secuencia incremental de intensidades, se<br />

percibe los incrementos de brillantez reforzados en un lado del intervalo de<br />

intensidad y decremento de brillantez reforzado del otro lado<br />

Ejemplo de código en Open GL<br />

Figura 56 Percepción de intensidad<br />

glShadeModel(GL_FLAT);<br />

glBegin(GL_TRIANGLES);<br />

glColor3f(1.0f, 0.0f, 0.0f); // activamos el color rojo<br />

glVertex3f(-1.0f, 0.0f, 0.0f);<br />

glColor3f(0.0f, 1.0f, 0.0f); // activamos el color verde<br />

glVertex3f(1.0f, 0.0f, 0.0f);<br />

glColor3f(1.0f, 0.0f, 0.0f); // activamos el color azul<br />

glVertex3f(0.0f, 1.0f, 0.0f);<br />

glEnd();<br />

Figura 57 Sombreado G_FLAT<br />

69


Colores y <strong>sombras</strong><br />

El triángulo se rellena con el color azul, puesto que el modelo de<br />

sombreado es GL_FLAT y el color activo en la definición del último vértice es el<br />

azul.<br />

7.9.4.2 Sombreado Interpolativo y Gouraud<br />

Si se asigna el modelo de sombreado para que sea suave, mediante<br />

glShadeModel(GL_SMOOTH);<br />

OpenGL interpolará <strong>colores</strong> para las primitivas, como las líneas. Si se permite<br />

sombreado y luz suaves, y se asigna a cada vértice la normal del polígono<br />

siendo sombreado, se calcularía la luz en cada vértice, determinando el color<br />

del vértice, usando las propiedades materiales y los vectores v y l se computan<br />

para cada vértice. Si la fuente de luz es distante, y el observador es distante o<br />

no hay reflexiones especulares, entonces el sombreado interpolativo<br />

sombreara un polígono con un color constante.<br />

Desde la perspectiva de OpenGL, el sombreado Gouraud es<br />

deceptivamente sencillo. Se necesita solamente asignar correctamente las<br />

normales de vértices. La literatura a menudo no distingue entre el sombreado<br />

interpolativo y el Gouraud. Sin embargo, existe un problema, encontrar las<br />

normales para promediar. Si el programa es lineal, especificar una lista de<br />

vértices (y otras propiedades), no se tiene la información necesaria de cuales<br />

polígonos comparten un vértice. Lo que se requiere es una estructura de datos<br />

para representar un "mesh". Atravesar esta estructura de datos puede generar<br />

los vértices con las normales promediadas. Tal estructura de datos debe<br />

contener, de manera mínima, polígonos, vértices, normales, y propiedades de<br />

los materiales. Una posible estructura se muestra en al siguiente figura,<br />

teniendo como elemento clave los polígonos que se juntan en cada vértice<br />

Figura 58 Estructura de datos para facilitar sombreado<br />

70


Colores y <strong>sombras</strong><br />

Ejemplo de código OpenGL<br />

glShadeModel(GL_SMOOTH);<br />

glBegin(GL_TRIANGLES);<br />

glColor3f(1.0f, 0.0f, 0.0f); // activamos el color rojo<br />

glVertex3f(-1.0f, 0.0f, 0.0f);<br />

glColor3f(0.0f, 1.0f, 0.0f); // verde<br />

glVertex3f(1.0f, 0.0f, 0.0f);<br />

glColor3f(1.0f, 0.0f, 0.0f); // azul<br />

glVertex3f(0.0f, 0.0f, 1.0f);<br />

glEnd();<br />

7.9.4.3 Stencil Buffer<br />

Figura 59 Sombreado GL_SMOOTH<br />

Sirve para mejorar la calidad de las <strong>sombras</strong> y los reflejos.<br />

Es un test extra por píxel y un conjunto de operaciones muy parecidas al<br />

Z-Buffer.<br />

Añade planos de bits adicionales para cada píxel además de los bits de<br />

color y profundidad.<br />

Es una manera de marcar píxeles en una renderización para controlar su<br />

actualización en renderizaciones siguientes.<br />

El valor stencil de un píxel es un entero sin signo (unsigned int).<br />

Para activar y desactivar el test de stencil se utilizará la función<br />

glEnable(GL_STENCIL_TEST) y glDisable(GL_STENCIL_TEST).<br />

Para borrar el stencil buffer se usará la función glClearStencil cuya<br />

sintaxis es la siguiente:<br />

71


Colores y <strong>sombras</strong><br />

• Propósito: Especifica un valor de estarcido para el buffer de estarcido.<br />

• Fichero de inclusión: <br />

• Sintaxis: void glClearStencil(GLint valor);<br />

• Descripción: Esta función selecciona el valor de color que usaremos<br />

para borrar el buffer de estarcido con<br />

glClear(GL_STENCIL_BUFFER_BIT).<br />

• Parámetros:<br />

valor<br />

GLint: el valor de limpieza del buffer de estarcido.<br />

• Retornos: Ninguno.<br />

El stencil test compara el valor del píxel del stencil buffer con un valor de<br />

referencia. Permite las comparaciones: never, always, less than, less than or<br />

equal, greater than, greater than or equal, equal, not equal.<br />

Es más potente que el buffer de profundidad. Antes de comparar realiza<br />

una operación AND tanto del valor de referencia como del valor del buffer, con<br />

un valor que sirve como máscara.<br />

GlStencilFunc(GL_EQUAL, 0x1,0xff).<br />

El primer parámetro será la función de comparación, el segundo el valor<br />

de referencia y el tercero la máscara.<br />

Si el píxel no pasa el test de profundidad es rechazado, en cambio, si lo<br />

pasa, se reemplaza el valor del Z-Buffer. El stencil test es más complicado:<br />

- No pasa el stencil test<br />

- Pasa stencil test y no el test de profundidad<br />

- Pasa stencil test y test de profundidad<br />

Para cada caso tenemos 6 operaciones distintas: GL_KEEP,<br />

GL_REPLACE, GL_INVERT, GL_INCREMENT, GL_DECREMENT, GL_ZERO.<br />

Antes de escribir se aplica un máscara:<br />

GlStencilOp(GL_KEEP //Stencil fail<br />

GL_DECR //Pasa el stencil y falla la profundidad<br />

GL_INCR //Pasa el stencil y pasa la profundidad)<br />

GlStencilMask(0xff);<br />

72


Colores y <strong>sombras</strong><br />

State Initial Value State Update State Query Token<br />

Description<br />

Command<br />

Stencilling GL_FALSE glEnable GL_STENCIL_TEST<br />

enable<br />

glDisable<br />

Stencil<br />

function<br />

GL_ALWAYS glStencilFunc GL_STENCIL_FUNC<br />

Stencil<br />

compare<br />

mask<br />

All 1’s glStencilFunc GL_STENCIL_VALUE_MASK<br />

Stencil<br />

reference<br />

value<br />

0 glStencilFunc GL_STENCIL_REF<br />

Stencil fail GL_KEEP<br />

operation<br />

glStencilOp GL_STENCIL_FAIL<br />

Stencil GL_KEEP glStencilOp GL_STENCIL_PASS_DEPTH_PASS<br />

depth fail<br />

operation<br />

Stencil<br />

depth pass<br />

operation<br />

GL_KEEP glStencilOp GL_STENCIL_PASS_DEPTH_PASS<br />

Stencil<br />

write mask<br />

All 1’s glStencilMask GL_STENCIL_WRITEMASK<br />

Stencil<br />

buffer clear<br />

value<br />

0 glClearStencil GL_STENCIL_CLEAR_VALUE<br />

Tiene una serie de limitaciones:<br />

- El objeto reflejado sale por fuera de la superficie reflectante<br />

- Desde detrás del espejo se ve el objeto reflejado.<br />

- No permite reflejos infinitos. Está limitado a n reflejos.<br />

A continuación se muestra el algoritmo para el empleo del stencil para<br />

simular <strong>sombras</strong>:<br />

1.- Cargar la matriz de modelización.<br />

GlMatrixMode(GL_MODELVIEW);<br />

GlLoadIdentity();<br />

GlLookAt(eye[0], eye[1], eye[2], center[0], center[1], center[2], up[0],<br />

up[1], up[2]);<br />

2.- Dada la luz y la ecuación del plano donde se proyecta, asumiendo que el<br />

objeto esta entre la luz y el plano, habilitar la luz y renderizar el objeto y el<br />

plano<br />

Glfloat lightPosition[4]={LX,LY,LZ,1.0);<br />

Glfloat groundPlaneEquation[4]={A,B,C,D};<br />

73


Colores y <strong>sombras</strong><br />

GlLightfv{GL_LIGHT0, GL_POSITION,lightPosition);<br />

GlEnable(GL_LIGHT0);<br />

GlEnable(GL_LIGHTING);<br />

DibujarObjeto();<br />

DibujarPlano();<br />

3.- Meter en la pila la matriz de modelización<br />

glPushMatrix();<br />

4.- Construir la matriz de proyección, multiplicar la matriz de modelización<br />

por la matriz de proyección de la sombra.<br />

Glfloat Matriz[4][4];<br />

ShadowMatrix(&matriz[0][0], LightPosition, groundPlaneEquation);<br />

glHultMatrix(&Matriz[0][0]);<br />

5.- Asignar un valor distinto de 0 al stencil buffer<br />

glEnable(GL_STENCIL_BUFFER);<br />

glStencilFunc(GL_ALWAYS, valor, ~0);<br />

glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);<br />

DibujarPlanoASombrear();<br />

GlDisable(GL_STENCIL_TEST);<br />

6.- Deshabilitar la iluminación<br />

glDisable(GL_LIGHTING);<br />

glEnable(GL_BLEND);<br />

glBlendFunc(GL_DST_COLOR,GL_ZERO);<br />

glColor3f(0.5,0.5,0.5);<br />

glDisable(GL_DEPTH_TEST);<br />

Solo debemos actualizar los pixeles marcados con valor<br />

GlEnable(GL_STENCIL_TEST);<br />

GlStencilFunc(GL_EQUAL, valor, ~0);<br />

GlStencilOp(GL_KEEP, GL_KEEP,GL_ZERO);<br />

DibujarObjeto();<br />

7.- Restaurar los valores<br />

74


Colores y <strong>sombras</strong><br />

glDisable(GL_BLEND);<br />

glDisable(GL_STENCIL_TEST);<br />

glEnable(GL_DEPTH_TEST);<br />

glPopMatrix();<br />

7.9.4.4 Buffer de Profundidad o Z buffer<br />

Este buffer se utiliza para el manejo de las coordenadas de profundidad<br />

de la imagen 3D. Esta es una solución al problema de visibilidad, para detectar<br />

que objetos de una imagen renderizada son visibles y cuales no. Cuando un<br />

objeto es renderizado por una tarjeta gráfica 3D, la profundidad de cada píxel<br />

es almacenada en un buffer (z-buffer). Este está normalmente formado por un<br />

array bidimensional con un elemento para cada píxel de la pantalla. Si otro<br />

objeto de la escena tiene q renderizarse en el mismo píxel, la tarjeta gráfica<br />

compara las dos profundidades y elige la que está más cercana al observador.<br />

Entonces la profundidad elegida es almacenada en el z-buffer, reemplazando a<br />

la anterior. Al final este buffer permite a la tarjeta gráfica reproducir fielmente la<br />

percepción de profundidad, un objeto cercano tapa a los de más lejos. La<br />

granularidad del z-buffer tiene una gran influencia en la calidad de la imagen:<br />

un buffer de 16 bits puede finalizar en conflicto cuando dos objetos están muy<br />

cercanos. Uno de 24 o 32 se comporta mucho mejor y uno de 8 casi nunca se<br />

usa porque tiene muy poca precisión.<br />

Figura 60 Buffer de profundidad<br />

75


Colores y <strong>sombras</strong><br />

7.9.5. Volúmenes de <strong>sombras</strong><br />

Para construir un volumen de <strong>sombras</strong> básicamente se proyecta un rayo<br />

de luz a través de cada vértice en la proyección de la sombra del objeto hacia<br />

algún punto (normalmente el infinito). El conjunto de estas proyecciones<br />

generan un volumen que engloba todos los puntos que pudieran posiblemente<br />

verse ensombrecidos por un objeto. Cualquier objeto dentro de este volumen<br />

debería ser ensombrecido. El volumen es presentado de tal modo que causa<br />

píxeles ensombrecidos tener valores estarcidos. que difieren de aquellos<br />

píxeles no sombreados.<br />

Para un modelo poligonal, el volumen esta formado normalmente por la<br />

clasificación de cada cara en el modelo ya sea encarándose hacia la fuente de<br />

luz o en su contra. El conjunto de todos los bordes que conectan la cara “hacia”<br />

con la cara “contra” forman la silueta con respecto a la fuente de luz. Los<br />

bordes que forman la silueta son excluidos de la luz para construir las caras del<br />

volumen de sombra. Este volumen debe extenderse sobre el rango total de la<br />

escena visible; a veces las dimensiones del volumen de sombra se extienden<br />

hasta el infinito. Para formar un volumen cerrado, el frente y la trasera de esta<br />

extrusión deben ser cubiertas. Estas cubiertas se llaman “caps”. Dependiendo<br />

del método usado para el volumen de sombra, el frente puede cubrir al objeto<br />

mismo y la parte trasera puede ser omitida.<br />

Los pasos para formar un volumen de <strong>sombras</strong> son:<br />

• Encontrar todos los bordes de siluetas.<br />

• Extender todos los bordes en dirección al foco de luz<br />

• Añadir la capa frontal y trasera a cada superficie para formar un<br />

volumen cerrado.<br />

Figura 61 Volumen de <strong>sombras</strong><br />

76


Colores y <strong>sombras</strong><br />

Determinar y visualizar el volumen ensombrecido es la parte más<br />

compleja de la técnica. Aunque se esté utilizando un método muy simple para<br />

la creación de volúmenes de <strong>sombras</strong> de geometría simple en este trabajo no<br />

sería eficiente para el caso de miles de polígonos. También puede ocurrir que<br />

el método cause algunos lugares donde los bordes de las <strong>sombras</strong> de los<br />

volúmenes se encuentren. ( Debido a que hay un único volumen sombreado<br />

para cada polígono). Esto puede solucionarse visualizando un único volumen<br />

que rodee el modelo entero en lugar de presentar los distintos volúmenes de<br />

cada polígono separados.<br />

Efectos a tener en cuenta son:<br />

• Umbría y penumbra para producir una transición gradual<br />

• La forma, tamaño y distancia de las fuentes de luz<br />

• La iluminación global<br />

Figura 62 Efecto de la fuente en la sombra<br />

Figura 63 Volumen <strong>sombras</strong> en un triángulo<br />

Existen 3 técnicas que usan el stencil buffer para renderizar las <strong>sombras</strong><br />

con volúmenes de <strong>sombras</strong> lo suficientemente rápido como para utilizarlas en<br />

aplicaciones de tiempo real, paso de profundidad, fallo en profundidad y OR<br />

exclusivo, pero todos ellos utilizan el mismo proceso:<br />

-renderizar la escena como si estuviera completamente en sombra.<br />

- para cada punto de luz:<br />

-usar la información de profundidad de la escena para construir una<br />

mascara en el stencil buffer que tiene huecos solo donde la superficie visible<br />

no es una sombra<br />

-Renderizar la escena de nuevo como si estuviera completamente<br />

iluminada, usando el stencil buffer para la máscara de las áreas sombreadas.<br />

77


Colores y <strong>sombras</strong><br />

La diferencia entre estos métodos ocurre en el segundo paso de la<br />

generación de la máscara. Unos requieren un paso, otros dos y requieren<br />

diferente nivel de precisión para el stencil buffer.<br />

7.9.5.1 Paso de profundidad (Depth pass)<br />

Heidemann propuso que si el frente de las superficies y la trasera de las<br />

<strong>sombras</strong> eran renderizadas en pasos separados, el número de caras frontales<br />

y traseras de un objeto puede ser contado usando el stencil buffer. Si la<br />

superficie de un objeto esta en sombra, habrá más superficies sombreadas<br />

frontalmente entre ella y el ojo que con las superficies traseras sombreadas. Si<br />

su número es igual, sin embargo, la superficie del objeto no es una sombra.<br />

7.9.5.2 Error de Profundidad (Depth fail)<br />

Sobre el 200 algunas personas descubrieron que el método de<br />

Heidmann puede trabajar desde cualquier punto de la cámara reinvirtiendo la<br />

profundidad. En vez de contar las caras frontales sombreadas de la superficie<br />

del objeto, las superficies traseras se pueden contar así fácilmente con el<br />

mismo resultado. Esto soluciona el problema de tener el observador en<br />

sombra, pero introduce la condición de que el extremo posterior del volumen de<br />

<strong>sombras</strong> debe ser encapsulado o las <strong>sombras</strong> terminarán perdiéndose donde<br />

los puntos del volumen van al infinito.<br />

7.9.7.3 OR exclusivo<br />

Las dos técnicas anteriores pueden aproximarse mediante la variación<br />

OR exclusivo, que no trata propiamente con la intersección de los volúmenes<br />

de <strong>sombras</strong>, pero ahorra un paso de renderización y solo requiere un bit de<br />

stencil buffer.<br />

7.10 Fusión (Dithering)<br />

Es una técnica usada para crear la ilusión de profundidad de color en<br />

imágenes con una paleta de <strong>colores</strong> limitada. En una imagen con fusión los<br />

<strong>colores</strong> no disponibles en la paleta original son aproximados por una difusión<br />

de los píxel coloreados dentro de la paleta disponible. El ojo humano percibe la<br />

difusión como una mezcla de <strong>colores</strong>.<br />

Figura 64 Ejemplo fusión<br />

78


Colores y <strong>sombras</strong><br />

Esta imagen está formada solo por rojo y azul, pero según se van<br />

haciendo mas pequeños los pixeles el ojo humano empieza a percibir un nuevo<br />

color mezcla de la aproximación de los dos presentes, con lo cual se puede<br />

percibir un color morado no presente en la paleta de <strong>colores</strong> inicial, pero la<br />

imagen sigue estando compuesta solo por rojo y azul.<br />

Figura 65 Imagen sin fusión Figura 66 Imagen con fusión<br />

Se puede obtener una buena calidad de imagen con aproximadamente 8<br />

bits de R,G,B sin utilizar fusión. Sólo porque nuestra maquina tenga 24 planos<br />

de color no significa que la fusión no sea deseable. Por ejemplo, si estamos<br />

ejecutando en modo doble buffer, los planos de color pueden ser divididos en 2<br />

conjuntos de 12, así tendremos sólo 4 bits para cada componente RGB. Sin<br />

fusión 4 bits por componente ofrecen resultados poco satisfactorios.<br />

Figura 67 Incremento de difusión<br />

79


Colores y <strong>sombras</strong><br />

Nota: La fusión al contrario que otras características está habilitada por<br />

defecto.<br />

Se puede deshabilitar con glDisable(GL_DITHER).<br />

Y habilitar con glEnable( GL_DITHER ).<br />

7.11. Creación de Paletas de Ventana<br />

Podemos crear una paleta utilizando la función CreatePalette() e<br />

identificando la paleta mediante un indicador del tipo HPALETTE:<br />

HPALETTE CreatePalette(<br />

CONST LOGPALETTE *lplgpl // puntero a la paleta<br />

lógica de color<br />

);<br />

Esta paleta utiliza una estructura lógica de paleta (LOGPALETE) que<br />

contiene 256 entradas, especificando los 8 bits para las componentes R,G,B.<br />

7.11.1 Arbitraje de paletas<br />

En la publicidad del sistema Windows se afirma que su sistema<br />

operativo es multitarea, por lo tanto se debe permitir la ejecución simultanea de<br />

varias aplicaciones. Pero el hardware solo permite 256 <strong>colores</strong> en la paleta del<br />

sistema que deben ser compartidos por todas las aplicaciones en ejecución. Si<br />

alguna de las aplicaciones modifica la paleta del sistema puede que se altere la<br />

presentación de imágenes de otras aplicaciones produciendo efectos no<br />

deseados. Windows proporciona un conjunto de mensajes para arbitrar el uso<br />

de paletas entre varias aplicaciones. Por lo tanto si una aplicación modifica la<br />

paleta del sistema se notificará este cambio al resto de las aplicaciones en<br />

ejecución.<br />

Cuando una aplicación se convierte en la aplicación activa Windows<br />

envía el mensaje WM_QUERYNEWPALETTE a la ventana principal de la<br />

aplicación, preguntándole si desea copiar las entradas de su paleta privada en<br />

las entradas del sistema. En caso afirmativo la aplicación selecciona la paleta<br />

en el contexto de dispositivo para la ventana actualizada y llama después a<br />

RealizePalette().<br />

Otro mensaje que puede enviar Windows para el arbitraje de las paletas<br />

es WM_PALETTECHANGED que indica a la ventana que puede seleccionar la<br />

paleta, incluso si no es la ventana activa.<br />

En el siguiente ejemplo mostramos la realización de este procedimiento:<br />

// Procedimiento de la ventana, gestiona todos los<br />

mensaje de este programa<br />

LRESULT CALLBACK WndProc (HWND hWnd,UINT<br />

message,WPARAM wParam,LPARAM lParam)<br />

... // Windows le dice a la aplicación que puede<br />

modificar la paleta del sistema.<br />

80


Colores y <strong>sombras</strong><br />

// Es decir, este mensaje solicita una nueva paleta a<br />

la aplicación<br />

case WM_QUERYNEWPALETTE:<br />

// Si la paleta fue creada<br />

if(hPalette)<br />

{<br />

int nRet;<br />

// Selecciona la paleta en el contexto<br />

de dispositivo actual<br />

SelectPalette(hDC, hPalette, FALSE);<br />

//Correspondencia de entradas entre la<br />

paleta actualmente<br />

// seleccionada y la paleta del<br />

sistema. El valor devuelto es<br />

// el número de entradas de la paleta<br />

modificada.<br />

nRet = RealizePalette(hDC);<br />

// Al redibujar se fuerza el<br />

replanteado de la paleta<br />

// en la ventana actual<br />

InvalidateRect(hWnd,NULL,FALSE);<br />

return nRet;<br />

}<br />

break;<br />

// Esta ventana puede seleccionar la paleta,<br />

incluso si no<br />

// es la ventana activa.<br />

case WM_PALETTECHANGED:<br />

// No hacer nada si la paleta no existe, o<br />

si esta<br />

// es la ventana que cambio la paleta<br />

if((hPalette != NULL) && ((HWND)wParam !=<br />

hWnd))<br />

{<br />

// Selecciona la paleta en el contexto<br />

de dispositivo<br />

SelectPalette(hDC,hPalette,FALSE);<br />

// Entrada en la paleta del sistema<br />

RealizePalette(hDC);<br />

// Reasigna los <strong>colores</strong> actuales a la<br />

nueva paleta realizada<br />

UpdateColors(hDC);<br />

return 0;<br />

}<br />

break;}<br />

81


Colores y <strong>sombras</strong><br />

7.11.2. Creación de una paleta.<br />

Determinamos si nuestra aplicación necesita una paleta llamando a la<br />

función DescribePixelFormat() después de haber definido el formato de píxel.<br />

Se ha de comprobar el valor del miembro dwFlags de la estructura<br />

PÍXELFORMATDESCRIPTOR devuelto por DescribePixelFormat(),<br />

comprobaremos el valor del bit PFD_NEED_PALETTE, si estuviese activo<br />

tendríamos que crear una paleta para uso de la aplicación.<br />

7.11.3 Estructura de la paleta.<br />

Para crear una paleta reservaremos memoria para la estructura<br />

LOGPALETTE.<br />

typedef struct tagLOGPALETTE { // lgpl<br />

WORD palVersion;<br />

WORD palNumEntries;<br />

PALETTEENTRY palPalEntry[1];<br />

} LOGPALETTE;<br />

La estructura se ha de completar con información sobre nuestra paleta y<br />

llamar a la función CreatePalette() pasándosela como argumento.<br />

Cada entrada en la paleta es una estructura PALETTEENTRY definida<br />

de la forma:<br />

typedef struct tagPALETTEENTRY { // pe<br />

BYTE peRed;<br />

BYTE peGreen;<br />

BYTE peBlue;<br />

BYTE peFlags;<br />

} PALETTEENTRY;<br />

- peRed, peGreen y peBlue representan las intensidades relativas para las<br />

componentes de 8 bits RGB. Así cada una de las 256 entradas de la paleta<br />

contendrá una definición de color de 24 bits.<br />

- PeFlags se utiliza para especificar opciones avanzadas de la paleta.<br />

Normalmente su valor será NULL.<br />

En el siguiente ejemplo mostramos la creación, arbitraje y estructura de<br />

una paleta:<br />

// Selecciona el formato de píxel para un contexto de<br />

dispositivo<br />

void SetDCPixelFormat(HDC hDC)<br />

{<br />

int nPixelFormat;<br />

static PIXELFORMATDESCRIPTOR pfd = {<br />

82


Colores y <strong>sombras</strong><br />

sizeof(PIXELFORMATDESCRIPTOR), // Tamaño de la<br />

estructura<br />

1,<br />

// Version of this structure<br />

PFD_DRAW_TO_WINDOW | // Dibuja en la ventana (No<br />

en el mapa de bits)<br />

PFD_SUPPORT_OPENGL | // Soporta llamada<br />

OpenGL en la ventana<br />

PFD_DOUBLEBUFFER, // Modo de doble Buffer<br />

PFD_TYPE_RGBA, // Modo de color RGBA<br />

24, // Pide<br />

24 bits de color<br />

0,0,0,0,0,0, // No se usa<br />

para seleccionar el modo<br />

0,0, // No se<br />

usa para seleccionar el modo<br />

0,0,0,0,0, // No se<br />

usa para seleccionar el modo<br />

32, // Tamaño<br />

del Buffer de Profundidad<br />

0, // No se<br />

usa para seleccionar el modo<br />

0, // No se<br />

usa para seleccionar el modo<br />

PFD_MAIN_PLANE, // Dibuja en el plano<br />

principal<br />

0, // No se<br />

usa para seleccionar el modo<br />

0,0,0 }; // No se usa<br />

para seleccionar el modo<br />

// Escoge el formato de píxel que mejor encaje en los<br />

descrito por pfd<br />

nPixelFormat = ChoosePixelFormat(hDC, &pfd);<br />

// Selecciona el formato de píxel para el contexto de<br />

dispositivo<br />

SetPixelFormat(hDC, nPixelFormat, &pfd);<br />

}<br />

// Si es necesario, crea una paleta 3-3-2 para el contexto<br />

de dispositivo listado<br />

HPALETTE GetOpenGLPalette(HDC hDC)<br />

{<br />

HPALETTE hRetPal = NULL; // Indicador a la paleta que<br />

va a crear<br />

PIXELFORMATDESCRIPTOR pfd; // Descriptor del<br />

formato de píxel<br />

LOGPALETTE *pPal; // Puntero a memoria<br />

para la paleta lógica<br />

83


Colores y <strong>sombras</strong><br />

int nPixelFormat; // índice del formato de<br />

píxel<br />

int nColors; // Numero de entradas en<br />

la paleta<br />

int i; // Variable de<br />

cuenta<br />

BYTE RedRange,GreenRange,BlueRange;<br />

// Rango para cada<br />

entrada de color (7,7,y 3)<br />

//Toma el formato de píxel y recupera la descripción<br />

del formato de píxel<br />

nPixelFormat = GetPixelFormat(hDC);<br />

DescribePixelFormat(hDC, nPixelFormat,<br />

sizeof(PIXELFORMATDESCRIPTOR), &pfd);<br />

//¿Necesita una paleta este formato de píxel? Si no,<br />

no crea una paleta<br />

// y devuelve NULL<br />

if(!(pfd.dwFlags & PFD_NEED_PALETTE))<br />

return NULL;<br />

//Numero de entradas en la paleta. 8 bits abarcan 256<br />

entradas<br />

nColors = 1 palVersion = 0x300; // Windows 3.0<br />

pPal->palNumEntries = nColors; // Dimensiones de la<br />

tabla<br />

//Crea una mascara de 1's. esto crea un numero<br />

representado por tener<br />

//activo los bits x de menor orden, donde x =<br />

pfd.cRedBits,<br />

//pfd.cGgreenBits y pfd.cBlueBits.<br />

RedRange = (1


Colores y <strong>sombras</strong><br />

pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift)<br />

& RedRange;<br />

pPal->palPalEntry[i].peRed = (unsigned char)(<br />

(double) pPal->palPalEntry[i].peRed * 255.0<br />

/ RedRange);<br />

pPal->palPalEntry[i].peGreen = (i >><br />

pfd.cGreenShift) & GreenRange;<br />

pPal->palPalEntry[i].peGreen = (unsigned char)(<br />

(double)pPal->palPalEntry[i].peGreen * 255.0<br />

/ GreenRange);<br />

pPal->palPalEntry[i].peBlue = (i >><br />

pfd.cBlueShift) & BlueRange;<br />

pPal->palPalEntry[i].peBlue = (unsigned char)(<br />

(double)pPal->palPalEntry[i].peBlue * 255.0<br />

/ BlueRange);<br />

NULL;<br />

pPal->palPalEntry[i].peFlags = (unsigned char)<br />

}<br />

// Crea la paleta<br />

hRetPal = CreatePalette(pPal);<br />

// Avanza, selecciona y realiza la paleta para este<br />

contexto de dispositivo<br />

SelectPalette(hDC,hRetPal,FALSE);<br />

RealizePalette(hDC);<br />

// Libera la memoria usada para la estructura lógica<br />

de paleta<br />

free(pPal);<br />

// Devuelve el indicador a la nueva paleta<br />

return hRetPal;<br />

}<br />

7.11.4 Destrucción de una paleta.<br />

Debemos crear y realizar la paleta antes de crear o activar el contexto de<br />

dispositivo.<br />

En el siguiente ejemplo mostramos las operaciones necesarias para<br />

crear y destruir una ventana teniendo en cuenta la posible existencia de una<br />

paleta<br />

// Procedimiento de la ventana, gestiona todos los mensaje<br />

de este programa<br />

85


Colores y <strong>sombras</strong><br />

LRESULT CALLBACK WndProc( HWND hWnd,UINT message,<br />

WPARAM wParam, LPARAM lParam)<br />

{<br />

static HGLRC hRC; // Contexto de<br />

generación permanente<br />

static HDC hDC; // GDI privado del<br />

contexto de dispositivo<br />

activa<br />

switch (message)<br />

{<br />

// Creacion de ventana para OpenGL<br />

case WM_CREATE:<br />

// Almacena el contexto de dispositivo<br />

hDC = GetDC(hWnd);<br />

// Selecciona el formato de píxel<br />

SetDCPixelFormat(hDC);<br />

// Crea la paleta<br />

hPalette = GetOpenGLPalette(hDC);<br />

// Crea el contexto de generación y lo<br />

hRC = wglCreateContext(hDC);<br />

wglMakeCurrent(hDC, hRC);<br />

// Llamada a la función de iniciación de la<br />

aplicación<br />

Init();<br />

break;<br />

// Se destruye la aplicación, hay que<br />

limpiar todo!<br />

case WM_DESTROY:<br />

// Desactiva el contexto de generación<br />

actual y lo borra<br />

wglMakeCurrent(hDC,NULL);<br />

wglDeleteContext(hRC);<br />

después de que<br />

ReleaseDC(hWnd,hDC);<br />

// Borra la paleta si fue creada<br />

if(hPalette != NULL)<br />

DeleteObject(hPalette);<br />

// Le dice a la aplicación que termine<br />

// se cierre la ventana<br />

PostQuitMessage(0); break;<br />

86


7.12 Conclusión<br />

En este tema hemos aprendido qué es el color y el sombreado, cual es<br />

la naturaleza de la luz, como la percibe el ojo humano y algunos de los<br />

modelos que se utilizan para su representación.<br />

Hemos visto la necesidad de introducir el sombreado o degradado de<br />

color para obtener un resultado más realista en nuestras escenas.<br />

Se han introducido todas las funciones necesarias para establecer el<br />

color de un objeto, el color con el que se limpia la pantalla, el modelo con el<br />

que se va a realizar el sombreado, la utilización de paletas y su gestión en<br />

OpenGL. Se han proporcionado ejemplos de aplicaciones que hacen uso de<br />

todas para facilitar su comprensión y posterior utilización.<br />

7.13 Otras funciones para luces y <strong>sombras</strong><br />

glAccum<br />

• Propósito: Opera en el buffer de acumulación para establecer los valores de<br />

píxel.<br />

• Fichero de inclusión: <br />

• Sintaxis: void glAccum(GLenum func, GLfloat valor);<br />

• Descripción: Esta función opera en el buffer de acumulación. A excepción de<br />

GL_RETURN, los valores de color se escalan según el parámetro valor y<br />

se añaden o suman al buffer de acumulación. En el caso de<br />

GL_RETURN, los valores de color del buffer de acumulación se escalan<br />

según el parámetro valor y se almacenan en el buffer de color actual.<br />

• Parámetros:<br />

func<br />

GLenum: la función de acumulación aplicada. Las funciones válidas son las<br />

siguientes:<br />

GL_ACCUM: Añade valores de color escalados al buffer<br />

de acumulación.<br />

GL_LOAD: Abre valores de color escalados en el buffer<br />

de acumulación, sustituyendo a los que hubiera antes.<br />

GL_ADD: Añade un color constante a los valores del buffer<br />

de acumulación.<br />

GL_MULT: Multiplica los valores de color en el buffer


Colores y <strong>sombras</strong><br />

de acumulación por un valor constante.<br />

GL_RETURN: Copia el buffer de acumulación en el buffer<br />

de color principal.<br />

• Retornos: Ninguno.<br />

glColorMask<br />

• Propósito: Activa o desactiva la modificación de las componentes de color en<br />

los buffers de color.<br />

• Fichero de inclusión: <br />

• Sintaxis: void glColorMask(GLboolean bRojo, GLboolean bVerde, GLboolean<br />

bBlue, GLboolean bAlfa);<br />

• Descripción: Esta función permite cambios individuales en las componentes<br />

de color en el buffer de color para activarlas o desactivarlas.<br />

• Parámetros:<br />

bRojo<br />

Glboolean: especifica cuándo se puede modificar la componente roja.<br />

bVerde<br />

Glboolean: especifica cuándo se puede modificar la componente verde.<br />

bAzul<br />

Glboolean: especifica cuándo se puede modificar la componente azul.<br />

bAlfa<br />

Glboolean: especifica cuándo se puede modificar la componente alfa.<br />

• Retornos: Ninguno.<br />

glDrawBuffer<br />

• Propósito: Selecciona un buffer de color para dibujar.<br />

• Fichero de inclusión: <br />

• Sintaxis: void glDrawBuffer(GLenum modo);<br />

• Descripción: Esta función selecciona un buffer de color para las operaciones<br />

de dibujo siguientes. Normalmente la usaremos para seleccionar el buffer<br />

frontal u oculto en un contexto de dibujo con doble buffer.<br />

• Parámetros:<br />

modo<br />

Glenum: una constante que selecciona el buffer de color en el que vamos a<br />

trabajar. Puede ser un valor de la siguiente tabla.<br />

88


Colores y <strong>sombras</strong><br />

• Retornos: Ninguno.<br />

Valor de modo Descripción<br />

GL_NONE No se dibuja en ningún buffer de color.<br />

GL_FRONT Dibujamos sólo en el buffer de color frontal (visible).<br />

GL_BACK Dibujamos sólo en el buffer de color trasero (oculto).<br />

GL_FRONT_AND_BACK Dibujamos en ambos buffers de color.<br />

glFog<br />

• Propósito: Especifica los parámetros de niebla.<br />

• Fichero de inclusión: <br />

• Sintaxis:<br />

• void glFogf( GLenum pnombre, GLfloat params);<br />

• void glFogfv( GLenum pnombre, GLfloat *params);<br />

• void glFogi( GLenum pnombre, GLint params);<br />

void glFogiv( GLenum pnombre, GLint *params);<br />

• Descripción: Define los parámetros de niebla. Para dibujar usando niebla,<br />

debemos hacer una llamada a glEnable(GL_FOG).<br />

• Parámetros:<br />

pnombre<br />

Glenum: el parámetro definido. Los nombres válidos son los siguientes:<br />

GL_FOG_COLOR: Color de la niebla.<br />

GL_FOG_DENSITY: Densidad de la niebla.<br />

GL_FOG_END: Distancia más alejada a la que se aplica niebla.<br />

GL_FOG_INDEX: El índice de color usado para niebla si se está<br />

en modo indexado.<br />

GL_FOG_MODE: El tipo de niebla.<br />

GL_FOG_START: La distancia más cercana a la que se aplica la<br />

niebla.<br />

• Retornos: Ninguno.<br />

89


Colores y <strong>sombras</strong><br />

glIndexMask<br />

• Propósito: Evita la modificación de bits individuales del buffer de color.<br />

• Fichero de inclusión: <br />

• Sintaxis: void glIndexMask( GLuint mascara);<br />

• Descripción: Esta función permite enmascarar bits individuales en el buffer<br />

de color indexado. Cuando se activa el bit de máscara, los bits son<br />

modificables; cuando son cero, están protegidos. Esta función sólo se aplica<br />

al modo de color indexado.<br />

• Parámetros:<br />

mascara<br />

GLuint: especifica la máscara binaria que activa o desactiva la escritura en los<br />

bits individuales del buffer de color indexado.<br />

• Retornos: Ninguno.<br />

glIsEnabled<br />

• Propósito: Verifica si una función de OpenGL está activada.<br />

• Fichero de inclusión: <br />

• Sintaxis: Glboolean glIsEnabled(GLenum caract);<br />

• Descripción: Devuelve GL_TRUE si la función especificada ha sido activada,<br />

GL_FALSE en otro caso.<br />

• Parámetros:<br />

caract<br />

GLenum: la función a verificar (ver glEnable).<br />

• Retornos: GLboolean: GL_TRUE si la función está activada, GL_FALSE si<br />

no.<br />

glLogicOp<br />

• Propósito: Selecciona la operación lógica para el modo de color indexado.<br />

• Fichero de inclusión: <br />

• Sintaxis: void glLogicOp( GLenum opcode);<br />

• Descripción: La operación lógica de píxel define la combinación de valores<br />

de píxel. Cuando se especifica un nuevo valor de índice de color para una<br />

90


Colores y <strong>sombras</strong><br />

localización de píxel, se combina lógicamente con el valor del índice de color<br />

actual de ese píxel.<br />

• Parámetros:<br />

opcode<br />

GLenum: especifica el modo lógico de píxel que hay que usar. Son válidos:<br />

GL_CLEAR, GL_SET, GL_COPY, GL_COPY_INVERTED, GL_NOOP,<br />

GL_INVERT, GL_AND, GL_NAND, GL_OR, GL_NOR, GL_XOR, GL_ EQUIV,<br />

GL_AND_REVERSE, GL_AND_INVERTED, GL_OR_REVERSE y<br />

GL_OR_INVERTED.<br />

• Retornos: Ninguno.<br />

glPolygonMode<br />

• Propósito: Selecciona el modo en que se generan los polígonos.<br />

• Fichero de inclusión: <br />

• Sintaxis: void glPolygonMode(Glenum cara, GLenum modo);<br />

• Descripción: Esta función nos permite cambiar la forma en que se generan<br />

los polígonos. Por defecto, los polígonos se rellenan o sombrean con el color<br />

o las propiedades de material actuales. Sin embargo, podemos especificar<br />

que se dibujen sólo los perfiles o los vértices.<br />

• Parámetros:<br />

cara<br />

GLenum: especifica a qué cara de los polígonos afecta el cambio de modo:<br />

GL_FRONT, GL_BACK, GL_FRONT_AND_BACK.<br />

modo<br />

GLenum: especifica el nuevo modo de dibujo. El valor por defecto es GL_FILL,<br />

que produce polígonos sólidos. GL_LINE produce perfiles de polígonos y<br />

GL_POINT sólo traza los puntos de los vértices. La bandera de borde activada<br />

por glEdgeFlag afecta a las líneas y puntos dibujados con GL_LINE y<br />

GL_POINT.<br />

• Retornos: Ninguno.<br />

91


Colores y <strong>sombras</strong><br />

7.14 Bibliografia<br />

"Gráficas por Computador"<br />

Autor: Hearn, Baker<br />

Ed: Prentice Hall<br />

"Computer Graphics: Systems&Concepts"<br />

Autor: Salmon, Slater<br />

Ed: Addison<br />

"Introduction to the GKS"<br />

Autor: Hopgood, Duce<br />

Ed: Academic Press, 86<br />

“Introduction to Computer Graphics”<br />

Autor: Foley, Van Dam<br />

Ed: Addison-Wesley<br />

“Visual Cues”<br />

Autor: Keller<br />

Ed: IEEE, 1993<br />

"Three Dimensional Computer Graphics"<br />

Autor: Watt<br />

Ed: Addison<br />

"Mathematical Elements for Computer Graphics"<br />

Autor: Rogers, Adams<br />

Ed: McGraw<br />

"Curves and Surfaces in Computer Aided Geometric Design"<br />

Autor: Yamaguchi<br />

Ed: Springer<br />

“Interactive Computer Graphics: A Top-Down Approach with OpenGL”<br />

Autor: Angel<br />

Ed: Addison Wesley, 1997<br />

“Computer Graphics 2/e”<br />

Autor: Hearn<br />

Ed: Prentice Hall<br />

“3D Computer Graphics, 2/e”<br />

Autor: Watt<br />

Ed: Addison Wesley<br />

92


Colores y <strong>sombras</strong><br />

“Introduction to Computer Graphics”<br />

Autor: Foley<br />

Ed: Addison Wesley<br />

“OpenGL Programming Guide & Reference Manual”<br />

Autor: Varios<br />

Ed: Addison Wesley<br />

“Inventor Mentor & Toolmaker”<br />

Autor: Varios<br />

Ed: Addison Wesley<br />

“SIGGRAPH '98 Conference Proceedings”<br />

Autor: Varios<br />

Ed: Addison Wesley<br />

Opengl Architecture Review Board, “OpenGL Reference Manual, The Official<br />

Reference Document to OpenGL, Version 1.2 “<br />

Autor: Dave Shreiner<br />

“OpenGL SuperBible, Second Edition (SuperBible)”<br />

Autor: Richard S. Wright Jr., Richard S., Jr. Wright<br />

“OpenGL Programming for the X Window System”<br />

Autor: Mark J. Kilgard<br />

“Computer Graphics : Principles and Practice, Second Edition in C by”<br />

Autor: James D. Foley<br />

OpenGL Architecture Review Board, “OpenGL(r) 1.2 Programming Guide<br />

Autor: Mason Woo, Jackie Neider, Tom Davis, Dave Shreiner<br />

OpenGL Architecture Review Board, “OpenGL(r) 1.2 Programming Guide<br />

Autor: Mason Woo, Jackie Neider, Tom Davis, Dave Shreiner<br />

"COMPUTER GRAPHICS: An object-oriented approach to the art and science"<br />

Autor: Cornel Pokorny<br />

Ed: Franklin, Beedle & Associates Incorporated<br />

93


Colores y <strong>sombras</strong><br />

"COMPUTER GRAPHICS: C version" (2nd. ed. o posterior)<br />

Autores: Donald Hearn and M. Pauline Baker<br />

Ed: Prentice Hall<br />

"COMPUTER GRAPHICS: Principles and practice (C version)"<br />

Autores: J. Foley, A. van Dam, S.K. Feiner and J.F. Hughes<br />

Ed: Addison-Wesley Publishing Company<br />

"COMPUTER GRAPHICS"<br />

Autor: F.S. Hill Jr.<br />

Ed: Macmillan Publishing Co.<br />

"Interactive Computer Graphics: a top-down approach with OpenGL"<br />

Autor: E. Angel<br />

Ed: Addison-Wesley Publishing Company, 1997<br />

"Mathematical Elements for Computer Graphics"<br />

Autores: D.F.Rogers and J.A.Adams<br />

Ed: McGraw Hill, 1.976.<br />

"Principles of Interactive Computer Graphics"<br />

Autores: W. Newman and R. Sproull<br />

Ed: McGraw Hill, 1979.<br />

"Raster Graphics Handbook, Conrac Division, 2nd edition"<br />

Ed: Van Nostrand Reinhold Co., 1.984.<br />

"The Mathematical Structure of Raster Graphics"<br />

Autores: Eugene L. Fiume<br />

Ed: Academic Press, Inc., 1986.<br />

"Windows NT OpenGL: Getting Started."<br />

Autores: Crain, Dennis<br />

Ed: MSDN Library, Technical Articles<br />

OpenGL Programming Guide: The Official Guide to Learning OpenGL, Release 1<br />

Autores: Neider, Jackie, Tom Davis, and Mason Woo<br />

Ed: Addison-Wesley<br />

“Principles of Digital Image Synthesis”<br />

Autores: Glassner<br />

Ed: Morgan Kaufmann Publisher, 1995.<br />

94


Colores y <strong>sombras</strong><br />

Computer Graphics: Principles and Practice (2nd. Ed. in C)<br />

Autores: Foley, van Dam, Feiner, Hughes<br />

Ed: Addison-Wesley Publishing Company, 1993.<br />

Radiosity and Realistic Image Synthesis<br />

Autores: Cohen, Wallace<br />

Ed: Academic Press, 1993.<br />

Computer Graphics Proceedings. Annual Conference Series.<br />

Autores: Varios<br />

Ed: ACM SIGGRAPH (ACM Special Interest Group on Computer Graphics).<br />

Rendering Techniques (Proceedings del EG Workshop on Rendering)<br />

Autores: Varios<br />

Ed: Springer Verlag, años 1994 hasta 1999<br />

OpenGL Architecture Review Board. OpenGL Reference Manual: The Official<br />

Reference Document for OpenGL, Release 1. Reading, MA<br />

Autores: Varios<br />

Ed: Addison-Wesley, 1992<br />

"Advanced 3-D Graphics for Windows NT 3.5: Introducing the OpenGL Interface, Part<br />

I." Microsoft Systems Journal 9 (October 1994)<br />

Autores: Prosise, Jeff<br />

Ed: MSDN Library Archive Edition, Books and Periodicals)<br />

"Advanced 3-D Graphics for Windows NT 3.5: The OpenGL Interface, Part II."<br />

Microsoft Systems Journal 9 (November 1994)<br />

Autores: Prosise, Jeff<br />

Ed: MSDN Library Archive Edition, Books and Periodicals)<br />

"OpenGL I: Quick Start."<br />

Autores: Rogerson, Dale<br />

Ed: (MSDN Library, Technical Articles)<br />

95


Colores y <strong>sombras</strong><br />

"OpenGL II: Windows Palettes in RGBA Mode."<br />

Autores: Rogerson, Dale<br />

Ed: (MSDN Library, Technical Articles)<br />

"OpenGL III: Building an OpenGL C++ Class."<br />

Autores: Rogerson, Dale<br />

Ed: (MSDN Library, Technical Articles)<br />

Using DIBs with Palettes.<br />

Autores: Gery, Ron<br />

Ed: (MSDN Library, Technical Articles)<br />

7.15 Enlaces de interés<br />

http://cannes.itam.mx/Alfredo/Espaniol/Cursos/Grafica/Sombreado.pdf<br />

http://en.wikipedia.org/<br />

http://www.opengl.org/<br />

http://www.dsic.upv.es/users/sig/personales/ramon/esp/GrafInternet.html<br />

http://www.ii.uam.es/~pedro/graficos/teoria/index.html<br />

http://m3d.uib.es/grafica2/Ejemplos.html<br />

http://serdis.dis.ulpgc.es/~atrujill/iga/Practicas2000.htm<br />

http://sgio2.cem.itesm.mx/rudomin/graf99/curso.htm<br />

http://victoryrocio.datablocks.net/i/opengl/<br />

http://www.codexmx.com/macedonia/opengl2.htm<br />

http://www.ldc.usb.ve/~jhony/graficasII/p1/informe1.html<br />

http://www.salleurl.edu/CITeM/grafics/recursos/arxius/cap3.pdf<br />

http://www2.ing.puc.cl/~iic1222/glex<br />

http://giig.ugr.es/~cadii/Doc/Articulo<br />

http://trant.sgi.com/opengl/examples/redbook/redbook.html<br />

96


Colores y <strong>sombras</strong><br />

http://www.eecs.tulane.edu/www/graphics/doc/OpenGL-Man-Pages/index.html<br />

http://giig.ugr.es/~curena/doce/docto/<br />

http://odra.dcs.fi.uva.es/area2/opengl/colorysombra.html<br />

http://odra.dcs.fi.uva.es/area2/opengl/refgl.html<br />

http://giig.ugr.es/~curena/doce/vr/transparencias/<br />

97

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!