La librería BGI (1)

Introducción

En esta pequeña serie de capítulos vamos a estudiar, finalizando con un ejemplo más o menos completo, la librería BGI de Borland para realizar aplicaciones gráficas en lenguaje C.

Antes de tratar esta librería, vamos a exponer unos primeros conceptos teóricos que nos ayudarán a aprender más rápidamente su manejo, así como el de otras de similar funcionamiento.

Cuando vamos a realizar una aplicación gráfica, necesitamos recurrir a unos elementos llamados primitivas para poder llevar a cabo los dibujos. Las primitivas de dibujo son los elementos básicos de los que disponemos para realizar cualquier representación gráfica: puntos, líneas, círculos, ... La primera de estas primitivas es muy dependiente del hardware de la máquina, del sistema operativo, del modo de vídeo, ... y dado que siempre podemos usar la función para este fin que viene en alguna librería de gráficos, vamos a tomarla como básica-disponible, es decir, cuando queramos dibujar algo, denotaremos PIXEL(x,y,color) a una función que vamos a tener a nuestra disposición siempre que la necesitemos.

La sintaxis de esta función en las distintas librerías no es muy distinta de la que adoptamos aquí como convenio. Así, a partir de ahora, en nuestros algoritmos, PIXEL(x,y,color) significa "pintar un punto en la posición (x,y) de la pantalla del color 'color'". Hay que hacer notar que en la pantalla, la esquina superior izquierda tiene coordenadas (0, 0), y que la coordenada x crece hacia la derecha mientras que la coordenada y crece hacia abajo. En la resolución en la que trabajemos, tendremos un máximo de XMAX puntos de ancho por YMAX puntos de alto, por tanto, el rango permitido para dibujar es el rectángulo de esquina superior izquierda (0, 0) y de esquina inferior derecha (XMAX-1, YMAX-1).

Una estrategia sencilla de programación gráfica podría esquematizarse en el siguiente gráfico:

Esquema general

Vamos a explicar cada una de estas etapas:

Detección del hardware: Trata de averiguar qué tipo de máquina se usa y qué características posee, pues esto nos determina qué modos gráficos podemos usar.

Por modo gráfico se entiende una configuración que nos informa de si es modo texto o gráfico, qué resolución tiene, si es paleta o true-color, y cuántos colores podemos usar.

Inicialización del modo gráfico: En esta fase escogemos las características del modo concreto que queramos usar. En modo texto tendremos como posibles resoluciones 80x25x16, 132x43x16,... y en modo gráfico tenemos 320x200x16, 320x200x256, 320x200x64K, 640x480x16, 800x600x16M, ... (hay muchas más posibilidades). Siempre los modos de 256 o menos colores son modos de paleta, y los modos de 32K o más colores, son modos true-color.

Según la librería, la función de inicialización de modo de vídeo es distinta. Suele usarse un identificador para cada modo distinto. Cuando no hablemos de una librería concreta, escribiremos:

Inicializar_Modo(Identificador)

y como 'Identificador' escribiremos una constante que empieza por m y, a continuación, el modo concreto siguiendo la notación MMMxNNNxCC, donde MMM es la resolución horizontal, NNN es la resolución vertical y CC es el número de colores. Por ejemplo, usaremos identificadores como:

m320x200x256
m640x480x16
m80x25x16
m800x600x32768
...

Así, en nuestra notación, si queremos inicializar el modo 640x400x256, escribiremos:

Inicializar_Modo(m640x400x256)

Una vez inicializado el modo, tenemos dos posibilidades: modificar el contexto gráfico o usar alguna función de dibujo. Se entiende por contexto gráfico un conjunto de propiedades que determinan con qué estilo se van a pintar las primitivas en pantalla.

Estilo son una serie de opciones que se aplican cuando tiene sentido aplicarse (ahora vemos qué quiere decir esto).

El estilo más básico es el color, que es aplicable a todas las primitivas, pues todas ellas son susceptibles de poder ser dibujadas con algún color.

También podemos establecer la forma en que las líneas serán dibujadas: grosor y trazo continuo o discontinuo, pudiendo elegir entre varias posibilidades en este último. El estilo de trazo de líneas pone de manifiesto que cualquier estilo no es susceptible de ser aplicable a cualquier primitiva: por ejemplo, no tiene sentido aplicar un estilo de trazo de líneas a un punto. De todas formas, no hay que preocuparse por qué primitivas admiten un estilo y qué primitivas no lo admiten: el esquema general de una librería gráfica en este aspecto es, primero, fijar el estilo, para después dibujar la primitiva con ese estilo, si es posible aplicarlo, y si no es posible, la dibuja sin aplicarlo, únicamente empleará aquello aplicable a la primitiva en cuestión.

Como decíamos antes, además de tener grosores distintos, las líneas pueden tener varios tipos de trazo. A continuación mostramos unos ejemplos de trazos y los identificadores que usaremos (pues luego las librerías gráficas dan completa información y ejemplos sobre las posibilidades):

Estilos de lineas

El último estilo que vamos a ver es aplicable a figuras que pueden rellenarse, y se conoce como patrón de relleno. Posibles patrones de relleno (y sus identificadores para nosotros) son, por ejemplo, SOLIDO, que hace referencia al relleno normal, TRAMADO, que hace una trama de líneas horizontales y verticales en lugar del relleno sólido, TRAMADO_OBL, que hace una trama de líneas oblícuas, PUNTEADO, que hace una trama de puntos, TRANSPARENTE, que no rellenará la figura, etc...

Ahora que hemos estudiado los posibles estilos, vamos a ver la notación que vamos a usar para las funciones que cambian los estilos:

   Cambiar_Color(ID_COLOR);
   Cambiar_Trazo_Linea(ID_LINEA,ID_GROSOR);
   Cambiar_Patron_Relleno(ID_RELLENO);

Notar lo siguiente: si pintamos un rectángulo, su borde se pintará con el estilo del trazo de líneas, mientras que su interior se pintará con el estilo del patrón de relleno. Si no especificamos estilo alguno, las librerías toman por defecto los siguientes valores:

   ID_COLOR es el identificativo del color negro.
   ID_LINEA es el identificativo del trazo continuo.
   GROSOR es el trazo identificativo de 1 píxel de grosor.
   ID_RELLENO es el identificativo del relleno sólido.

Estudiadas las posibilidades que tenemos para dibujar primitivas, entramos ya en las primitivas que tenemos disponibles:

Pixel(x,y,color);
Pinta un pixel en la posición (x,y) de la pantalla, del color especificado en color. Es la única primitiva a la que no se le aplica estilo alguno.
Linea(x0,y0,x1,y1);
Pinta una línea que va del punto (x0,y0) al punto (x1,y1) con el estilo que se haya definido. Si no hay estilos definidos, se aplica el estilo por defecto.
Rectangulo(x0,y0,x1,y1);
Pinta un rectángulo cuya esquina superior izquierda tiene por coordenadas (x0,y0) y cuya esquina inferior derecha tiene por coordenadas (x1,y1). El trazo de las cuatro líneas será el que venga dado por el estilo de línea. Si no hay estilo de línea definido, se usará el estilo por defecto, trazo continuo.
RectanguloR(x0,y0,x1,y1);
Igual que Rectangulo, pero la figura se rellenará con el estilo de relleno que haya definido en ese momento.
Circulo(x,y,radio);
Pinta un círculo de centro (x,y) y radio 'radio'. El valor del radio debe ser un número positivo para que tenga sentido. El círculo se pinta con el estilo que haya definido en ese momento o con el estilo por defecto si no se han definido estilos.
CirculoR(x,y,radio);
Igual que Circulo, pero además se rellenará con el estilo de relleno que haya definido en ese momento.
Elipse(x,y,a,b);
Pinta una elipse de centro (x,y) y semiejes mayor y menor a y b, respectivamente. Ambos deben ser números positivos para que tenga sentido. La elipse se pinta con el estilo definido en ese momento o con el estilo or defecto si no hay ninguno definido.

Y muchas otras que concretaremos para el caso de la BGI.



suministrado por FreeFind
Valid HTML 4.0! Valid CSS!