La librería BGI

Artículos con Clase Anterior Siguiente Descargar SVGABGI

La librería BGI: Modos de vídeo y colores

Nota previa: para utilizar cualquiera de estas funciones, primero deberá incluirse el correspondiente fichero de cabecera 'graphics.h'. Además, esta librería no se enlaza automáticamente si no se lo especificas así, para lo que hay que hacer una de las dos cosas siguientes:

  1. Si tienes un Borland C con entorno de programación, en las opciones de compilación, concretamente,
    OPTIONS -> LINKER -> LIBRARIES, debes marcar la casilla que pone 'Graphics Library' para que enlace con la librería de gráficos al compilar el programa.
  2. Para enlazar desde línea de comandos, tendrás que escribir:
    TC -L GRAPHICS.LIB PROGRAMA.C

Como comentábamos en el capítulo anterior, lo primero que había que hacer era detectar el hardware para después inicializar el modo de vídeo. Para hacer esto tenemos dos posibilidades. Podemos asignar directamente el tipo de tarjeta de vídeo y el modo que usaremos de los soportados por esa tarjeta, para lo cual necesitamos saber qué codigos asignar a unas variables que llamaremos 'driver' y 'modo', que deben ser de tipo entero, o bien podemos dejar que sea una función de la librería la que detecte el modo gráfico máximo que soporta nuestro hardware, y esa función se encargue de realizar las asignaciones de los valores correspondientes a las variables 'driver' y 'modo', para después pasarlas nosotros a la función que inicializa el modo gráfico.

Para consultar los modos disponibles, tenemos la función:

   void detectgraph(int *driver, int *modo);

que almacenará en 'driver' el código del fichero driver requerido y en 'modo' el código de la máxima resolución disponible con ese driver. Si preferimos asignar directamente esos modos, a continuación vemos qué valores tenemos disponibles.

Valores para driver=CODIGO_DRIVER:

   DETECT
   CGA
   MCGA
   EGA
   EGA64
   EGAMONO
   IBM8514
   VGA

El driver DETECT lo que significará es que se escogerá el modo más alto soportado por nuestra tarjeta, de entre todos los disponibles. Los valores para modo=CODIGO_MODO:

   CGA         CGAC0
               CGAC1
               CGAC2
               CGAC3
               CGAHI
   MCGA        MCGAC0
               MCGAC1
               MCGAC2
               MCGAC3
               MCGAMED
               MCGAHI
   EGA         EGALO
               EGAHI
   EGA64       EGA64LO
               EGA64HI
   EGAMONO     EGAMONOHI
   VGA         VGALO
               VGAMED
               VGAHI
   IBM8514     IBM8514LO
               IBM8514HI

Hoy en día, únicamente usaremos (casi seguro) el driver VGA con el modo VGAHI, puesto que el resto se trata de modos de vídeo con resoluciones bajas y pocos colores que ahora no tienen sentido por las capacidades de las tarjetas gráficas, pero que hace unos años era lo único que se podía hacer. Incluso el driver VGA sabrá a poco en muchas ocasiones, para lo que existe una librería llamada SVGABGI que implementa las mismas funciones que la BGI de Borland, pero no está desarrollada por Borland, y nos da facilidades para usar modos de vídeo con más colores y mayor resolución. Puedes bajarla de aquí y usarla de la misma manera que explicaremos aquí el uso de la BGI. De todas formas, consulta la documentación de la librería, en ella verás más detalles.

Tras la consulta de los modos de vídeo (bien por llamar a la función detectgraph, bien por asignación directa), ya podemos inicializar el modo de vídeo deseado, llamando a la función:

   void initgraph(int *driver, int *modo, char *ruta);

que utiliza los códigos de 'driver' y 'modo' para seleccionar la configuración, y la cadena de caracteres 'camino' para hallar el fichero que contiene al driver adecuado.

La librería BGI dispone de varios ficheros con extensión .BGI que tendrán que estar localizables por el programa que creemos pues, en caso contrario, no podremos inicializar el modo de video y, consecuentemente, no podremos crear gráficos. Además, si el programa no encuentra los ficheros BGI, terminará dando un error en el que dice que no ha podido inicializar el modo gráfico. Estos ficheros BGI se encuentran en el directorio BGI de la distribución correspondiente del compilador de Borland.

Suponiendo que hemos inicializado correctamente el modo gráfico, ya podemos definir el área de dibujo (también llamada viewport), que es el rectángulo que podemos modificar con nuestros gráficos, y que no tiene por qué coincidir con la totalidad de la pantalla. Esto se realiza con la función:

   void setviewport(int x0, int y0, in x1, int y1, char Corte);

que establece el rectángulo de dibujo entre un punto superior izquierdo (de coordenadas (x0, y0)) y otro inferior derecho (de coordenadas (x1, y1)). Corte es un booleano que indica si se eliminan los dibujos que salgan fuera del área o no. Si no se usa setviewport, el área de trabajo será, por defecto, toda la pantalla. Otra función de gran utilidad, que nos permite borrar todo el contenido del área de trabajo, asignándole el color de fondo (después vemos cómo especificar este color) es la siguiente:

   void clearviewport();

Una vez tenemos definida el área de trabajo deberemos entrar en la definición del contexto gráfico (recordemos lo dicho en el capítulo anterior sobre esto), es decir, de todas aquellas variables que van a determinar cómo aparecen dibujadas las cosas (si no se hacen cambios, se usan valores por defecto que son automáticamente asignados al inicializar el modo gráfico) (colores, estilo y anchura de las líneas,...). Normalmente será prioritario escoger los colores con los que se va a dibujar.

En el capítulo anterior decíamos que existen dos modos de paleta de colores: el modo paleta (propiamente dicho) y el modo true-color. El modo paleta es indexado, es decir, existe una tabla con las componentes RGB de los colores de los que se compone la paleta, y a cada color le corresponde un índice. Por ejemplo, el color negro tiene por componentes RGB (0,0,0), y suele tener el índice 0 en las paletas de color. Otro ejemplo, el color rojo tiene por componentes RGB (255,0,0), y puede tener, por ejemplo, el índice 40 en la paleta de colores. Hay unos colores por defecto, pero podemos cambiarlos. El modo true-color no es indexado, si queremos especificar un color, tenemos que decir sus componentes RGB directamente.

La librería BGI únicamente está preparada para trabajar en modo paleta. Según el modo gráfico seleccionado, la paleta será de más o menos colores. Con los BGI estándar de Borland, el modo VGA sólo tiene 16 colores. Con la librería SVGA BGI podemos definir hasta 256 colores en la paleta. El primer paso será, pues, introducir en la paleta aquellos tonos de color que queremos utilizar, a no ser que nos quedemos con los colores por defecto.

Si queremos quedarnos con los colores por defecto, cuando queramos establecer el estilo 'color', podremos pasarle como argumento el índice del color en la paleta, o podemos pasarle unas constantes predefinidas que hacen referencia al color. Estas constantes (con sus correspondientes índices entre paréntesis) son:

   BLACK (0)     BLUE (1)          GREEN (2)       CYAN (3)
   RED (4)       MAGENTA (5)       BROWN (6)       LIGHTGRAY (7)
   DARKGRAY (8)  LIGHTBLUE (9)     LIGHTGREEN (10) LIGHTCYAN (11)
   LIGHTRED (12) LIGHTMAGENTA (13) YELLOW (14)     WHITE (15)

Si preferimos definir nuestros propios colores, tenemos las funciones:

   void setpalette(int numcolor,int codigocolor);
   void setRGBcolor(int numcolor,int r,int g,int b);

que sitúa en el lugar 'numcolor' de la paleta (en una pluma) el color (tinta) definido por 'codigocolor'. En las primeras versiones, el color no se especificaba por sus componentes RGB, sino haciendo uso de una tabla de colores predefinida, donde podemos encontrar sólo determinados tonos con los correspondientes códigos. Posteriormente se añadió la posibilidad de seleccionar por RGB, pero utilizando solo 6 bits por pixel, o sea, 64 combinaciones por componente.

Tras definir la paleta de colores, tenemos que asignar un color de dibujo y un color de fondo (que se usa en las instrucciones de borrado o como fondo cuando dibujamos texto), indicando qué posiciones del mapa de color utilizamos para cada uno. Esto se hace con las funciones respectivas:

   void setcolor(int numcolor);
   void setbkcolor(int numcolor);

Seguimos en el próximo capítulo, viendo qué sintaxis tienen las primitivas de dibujo.