6.3 Cambios de contexto para múltiples áreas gráficas.

    El punto que trataremos a continuación tiene que ver con el empleo de la librería gráfica OpenGL dentro del ambiente de ventanas que crea xforms.

    La librería xforms permite emplear áreas especiales dentro de las formas o ventanas llamadas 'canvas'. Estas áreas relegan al programador la tarea de manejar la interacción. Existe un tipo de área en particular llamado glcanvas que permite el despliegue de gráficas a partir de la librería OpenGL.

    OpenGL es una libería portable que hace uso de los recursos de hardware para crear gráficas de alto rendimiento. Consiste de un conjunto de funciones que permiten desplegar 'primitivas' gráficas, tales como puntos, líneas, poligonos y también permite iluminar y mover una cámara. Se trata, al igual que xforms, de una librería de funciones en lenguaje C.

    El problema con el que nos enfrentamos al utilizar estas dos librerías juntas fue en el momento en que quisimos tener varias áreas gráficas dentro de una misma forma. El problema ocurre pues cada área gráfica tiene un 'rendering context' y es necesario activar cada contexto antes de dibujar algo en el. Para mayor información sobre los contextos en openGL, véase "OpenGL graphics with the X window system. Version 1.3 por Paula Womack y John Leech".

    La solución fue tener una operación llamada Activa() dentro del área gráfica.

bool C_AreaGrafica::Activa(Display *dpy,GLXDrawable draw,void *ctx)
{
 return glXMakeCurrent(dpy,draw,(GLXContext) ctx);
 
}

    Del lado de las ventanas que tienen el área gráfica, se tiene que llamar a esta función desde RecibeEvento(), la función que aparte de DespachaCallback() se declara 'static' y que es el callback asignado a los eventos que ocurren en el área gráfica. (Ejemplo tomado de C_VentanaPrincipal)

 
int C_VentanaPrincipal::RecibeEvento(FL_OBJECT *ob, Window win,int w,int h, XEvent *xev,void *ud)
{
 C_VentanaPrincipal *ApTemp;                            // Apuntador temporal
 ApTemp=(C_VentanaPrincipal *)ob->form->u_vdata;        // Rescata el this

 ApTemp->Pantalla.Activa(fl_display,win,ApTemp->forma->canvas->u_vdata);
 ApTemp->Pantalla.CambiaTamano(w,h);                    // Envia actualizaciones a la pantalla
 ApTemp->RefrescaAreaGrafica();

 return 0;
}

Es necesario llamar a la operación Activa desde aqui, ya que sólo RecibeEvento() recibe los parámetros necesarios.

Si se tienen múltiples áreas gráficas, se resuelve teniendo dentro de la clase un atributo que indique cual de las tres áreas debe ser activada.

6.4 Desplegando imágenes con OpenGL.

    La aplicación que hemos desarrollado consiste principalmente del despliegue de imágenes en areas de dos dimensiones. Aunque la librería OpenGL permite dibujar en 3D, hemos trabajado con formato de enteros (OpenGL permite trabajar múltiples formatos), con la esquina superior izquierda como origen (0,0).

    Sin embargo, al querer desplegar imágenes, OpenGL resulto no ser tán rapido como se esperaba. Aunque dispone de funciones que permiten desplegar un arreglo de puntos (en particular glDrawPixels()), estas funciones resultaron ser identicas en velocidad que el despliegue de la imagen 'punto por punto'.

    Finalmente fue más útil el despliegue punto a punto pues permitio el uso de funciones de escalado de imágenes.

6.5 Implementación de itoa en una clase de funciones externas.

    Al querer mostrar un número en xforms, muchas veces es necesario desplegarlo como cadena. Sin embargo, la función 'itoa()' que cambia un entero a caracteres ASCII, no es una función 'estándar'. Para implementarla se creo una clase 'exclusiva' para ella, se llama C_Externs.

    Está declarada como sigue:

#ifndef Externs_C
#define Externs_C

class C_Externs
{
public:

 void itoa(int,char *);    // Convierte entero a ascii
};

#endif

    Así cuando se necesita llamar a la función, se hace uso de un objeto instanciado a partir de esta clase.

    Esta solución es poco elegante, sin embargo, permite respetar el modelo.

6.6 Uso de 'make' para compilar la aplicación.

    Para compilar la aplicación hemos hecho uso de la herramienta 'make'. A continuación se muestra el archivo 'makefile' que se empleo para la primera versión.

# Makefile de la aplicacion de reconstruccion 3D por
# Humberto Cervantes para el proyecto terminal 1998.

# ------------------------- MACROS ---------------------------
 

# OBJECTS es una macro que indica todos los objetos de los cuales depende
# la aplicacion para compilarse de manera exitosa.

OBJECTS=Main.o Aplicacion.o Manejador.o VentanaPrincipal.o VentanaSelAlgoritmo.o Stack.o DialogoArchivo.o Imagen.o Color.o AreaGrafica.o VentanaConfStack.o VentanaConfStackDisp.o StackConfig.o Externs_C.o Coleccion.o Procesador.o ProcSegUmbral.o VentanaConfSegUmbral.o Histograma.o VentanaReconstruccion.o ProcReconstruccion.o Punto.o ListaLigada.o Volumen.o VentanaAcercaDe.o

# A continuacion aparecen macros que indican las librerias con las cuales se
# debe ligar la aplicacion

LIBFORMS=-L ../FORMS -lforms
LIBOGL=-lX11 -lXm -lGL

# INCXFORMS es una macro que indica que directorios buscar para incluir los
# archivos de cabecera de xforms.

INCXFORMS=-I ../FORMS

# VENTANAS es una macro que indica todos los archivos de los cuales depende el
# manejador.

VENTANAS=Ventana.h VentanaPrincipal.h VentanaSelAlgoritmo.h DialogoArchivo.h VentanaConfStack.h VentanaConfSegUmbral.h VentanaReconstruccion.h VentanaAcercaDe.h

#WARNINGS si esta definido como =-w no se mostraran warnings a la hora de compilar...

WARNINGS=-fullwarn -O3
 

# ------------------------- BUILDS ---------------------------

# __ APLICACION DE MANERA GLOBAL __

Main: ${OBJECTS}
 CC -o $@ ${OBJECTS} ${LIBFORMS} ${LIBOGL} -lm

# __ INDEPENDIENTES DE SISTEMA DE VENTANA Y GRAFICOS __

Main.o: Main.cpp Aplicacion.h
 CC ${WARNINGS} -c Main.cpp

Aplicacion.o: Aplicacion.cpp Aplicacion.h ObjetoInt.h Manejador.o Stack.o Procesador.o ListaLigada.o
 CC ${WARNINGS} -c Aplicacion.cpp

Coleccion.o: Coleccion.cpp Coleccion.h ObjetoInt.h ObjetoModificable.h AreaGrafica.o
 CC ${WARNINGS} -c Coleccion.cpp

Stack.o: Stack.cpp Stack.h Coleccion.o Imagen.o StackConfig.o ListaLigada.o
 CC ${WARNINGS} -c Stack.cpp

StackConfig.o: StackConfig.h StackConfig.cpp
 CC ${WARNINGS} -c StackConfig.cpp

Imagen.o: Imagen.cpp Imagen.h General.h ListaLigada.o  DatoDeColeccion.h
 CC ${WARNINGS} -c Imagen.cpp

Color.o: Color.cpp Color.h General.h ListaLigada.o
 CC ${WARNINGS} -c Color.cpp

Procesador.o: Procesador.cpp Procesador.h Proceso.h
 CC ${WARNINGS} -c Procesador.cpp

ProcSegUmbral.o: ProcSegUmbral.cpp ProcSegUmbral.h Proceso.h
 CC ${WARNINGS} -c ProcSegUmbral.cpp

ProcReconstruccion.o: ProcReconstruccion.cpp ProcReconstruccion.h Proceso.h Volumen.o
 CC ${WARNINGS} -c ProcReconstruccion.cpp

Histograma.o : Histograma.cpp Histograma.h Imagen.o
 CC ${WARNINGS} -c Histograma.cpp

Punto.o : Punto.cpp Punto.h General.h ListaLigada.o DatoDeColeccion.h
 CC ${WARNINGS} -c Punto.cpp

ListaLigada.o : ListaLigada.cpp ListaLigada.h General.h
 CC ${WARNINGS} -c ListaLigada.cpp

Volumen.o : Volumen.cpp Volumen.h General.h Punto.o Color.o
 CC ${WARNINGS} -c Volumen.cpp

# __EXTERNOS DE C__

Externs_C.o:Externs_C.h Externs_C.cpp
 CC ${WARNINGS} -c Externs_C.cpp

# __CONTIENEN COMANDOS DE XFORMS__

Manejador.o: Manejador.cpp Manejador.h ObjetoInt.h ${VENTANAS}
 CC ${INCXFORMS} ${WARNINGS} -c Manejador.cpp

VentanaPrincipal.o: VentanaPrincipal.cpp VentanaPrincipal.h General.h Ventana.h Aplicacion.o AreaGrafica.o Color.o
 CC ${INCXFORMS} ${WARNINGS} -c VentanaPrincipal.cpp

VentanaSelAlgoritmo.o: VentanaSelAlgoritmo.cpp VentanaSelAlgoritmo.h General.h Ventana.h Aplicacion.o
 CC ${INCXFORMS} ${WARNINGS} -c VentanaSelAlgoritmo.cpp

VentanaConfStack.o: VentanaConfStack.cpp VentanaConfStack.h General.h Ventana.h Stack.h
 CC ${INCXFORMS} ${WARNINGS} -c VentanaConfStack.cpp

VentanaConfStackDisp.o: VentanaConfStackDisp.cpp VentanaConfStackDisp.h General.h Ventana.h Stack.o StackConfig.o
 CC ${INCXFORMS} ${WARNINGS} -c VentanaConfStackDisp.cpp

VentanaConfSegUmbral.o: VentanaConfSegUmbral.cpp VentanaConfSegUmbral.h General.h Ventana.h Stack.o StackConfig.o AreaGrafica.o Histograma.o
 CC ${INCXFORMS} ${WARNINGS} -c VentanaConfSegUmbral.cpp

DialogoArchivo.o: DialogoArchivo.cpp DialogoArchivo.h General.h ObjetoInt.h Ventana.h Stack.o
 CC ${INCXFORMS} ${WARNINGS} -c DialogoArchivo.cpp

VentanaReconstruccion.o: VentanaReconstruccion.cpp VentanaReconstruccion.h General.h Ventana.h AreaGrafica.o Stack.o ProcReconstruccion.o
 CC ${INCXFORMS} ${WARNINGS} -c VentanaReconstruccion.cpp

VentanaAcercaDe.o: VentanaAcercaDe.cpp VentanaAcercaDe.h General.h Stack.h
 CC ${INCXFORMS} ${WARNINGS} -c VentanaAcercaDe.cpp
 

# __CONTIENEN COMANDOS DE OPENGL__

AreaGrafica.o: AreaGrafica.cpp AreaGrafica.h General.h Color.o Imagen.o
 CC ${WARNINGS} -c AreaGrafica.cpp
 

# ------------------------------------------------------------

Notese que estan separados los archivos que se pueden compilar independientemente de las librerias, los que conciernen a xforms y finalmente aquellos que conciernen a openGL.
 
 
 


  Regresar al indice.             Ir a página siguiente.