Instalando las librerias de OpenGL y glut en Ubuntu


Pues desde hace tiempo quería reescribir este how to, sucede que estoy actualmente escribiendo mi tesis y para ello necesitaba poder compilar programas básicos de OpenGL. Una de las cosas que quería lograr era escribir mi tesis 100% con Software libre, ya tenia experiencia trabajando con OpenGL y glut, en distribuciones Red Hat-like (por ejemplo Red Hat, Fedora, WhiteBox y Mandrivia) y sabia con rpms como instalarme las librerías necesarias, sin embargo cuando cambie a distribuciones Debian-like (ahora uso Ubuntu) no sabia como lograr mi cometido, asi que después de investigarlo un poco me dí a la tarea de escribir este How-to.

Paso 1

Instalar el compilador de C.

Una de las cosas que mas me sorprendió es que Ubuntu, no viene con el compilador de C, en su instalación de default (hasta ahora es el único Gnu/Linux donde me ha pasado esto), así que tienes que instalarlo desde los repositorios.

En Ubuntu solo es cuestión de instalarte los paquetes ya sea vía apt-get o via synaptic lo que te acomode mejor, al caso debes de instalar los siguientes paquetes:

  • build-essential
  • g++
  • g77
  • gcc
  • make

Estos paquetes no vienen solos, es decir probablemente necesites descargar muchos paquetes mas para satisfacer las dependencias de estos, sin embargo dado que tanto synaptic como apt-get, pueden satisfacer sus dependencia de manera automática solo debemos indicarle estos paquetes. tanto de gcc, como de g++ y g77, hay varias versiones de los paquetes, sin embargo el paquete sin números siempre es un paquete con la versión mas actual.

En resumen lo único que un usuario novato debe de teclear es:

 	$sudo apt-get install build-essential g++ g77 gcc make

Paso 1.5 Probamos la instalación del compilador de C

En nuestro editor de textos plano favorito tecleamos un programa de C, básico por ejemplo un clásico hola mundo: hello.c Lo guardamos por ejemplo con el nombre de hello.c y vamos a compilarlo.

Con la siguiente instrucción:

$gcc hello.c -o hello

Podemos observa que la sintaxis para compilar un programa en C, es la siguiente:

$gcc [archivo fuente.c] -o [nombre de mi ejeculable]

En realidad el gcc es mucho mas completo, un tutorial de como compilar programas con C lo puedes encontrar aqui.

2 Instalamos las librerias necesarias para OpenGL

Ahora necesitaremos instalar los siguientes paquetes:

freeglut3 freeglut3-dbg freeglut3-dev ftgl-dev gle-doc glut-doc glutg3 glutg3-dev libglu1-mesa libglu1-mesa-dev libgl1-mesa libgl1-mesa-dev libgl1-mesa-dri libglut3 libglut3-dev mesa-common-dev mesa-demos mesa-swrast-source mesa-utils

No se cuales sean los esenciales, yo siempre he instalado con todos, pero se que así funciona, muchos de ellos son dependencias, así que no igual lo único que debes de tener en cuenta es tratar de instalar freeglut-dev.

Importante: Si piensas tener tu computadora con Aceleración Gráfica (por ejemplo para tener Beryl), es decir instalar los drivers propietarios de ATI o de nVidia, debes hacerlo antes de hacer esta instalación, se pueden tener ambas funcionando pero poner el driver gráfico debe ser anterior a la instalación de OpenGL. De la contrario nuestros programas de OpenGL no tendrán aceleración

Para saber si nuestra computadora tiene o no aceleración Gráfica puedes ejecutar el comando glxinfo y ver la salida, en el renglón donde dice direct rendering: un “Yes”, significa que tenemos Aceleración gráfica. Una forma de filtrarlo es:

 	 $glxinfo | grep rendering

Por supuesto que tener o no Aceleración Gráfica es totalmente dependiente de tu hardware. Por lo que no se puede escribir una guía general, sin embargo hay muchísima información en la red sobre esto, mi experiencia es que si tu computadora tiene tarjeta de vídeo Intel o nVidia, no debes tener ningún problema, las ATI, en cambio debes de investigar un poco antes de hacerlas funcionar.

2.5Probar la instalación de OpenGL y glut

Nos tecleamos un programa sencillo de glut y OpenGL, por ejemplo este: ventana.c

Y ahora vamos intentar la compilación:

$gcc ventana.c -o ventana -lglut

Y debemos ver una ventana negra.
Si en al linea de comandos ven un warning que dice algo así como:

libGL warning: 3D driver claims to not support visual 0x5b

Pero la ejecución de el programa continua, no deben de preocuparse, este warning solo significa que no esta correctamente configurado su driver de la tarjeta de vídeo, pero es algo que no debe de afectar sus programas escritos en OpenGL, mas que en el performance, y no es un problema de su programa si no del driver de la computadora.

Obviamente el caso ideal es tener tanto el OpenGL como la aceleración gráfica funcionando al mismo tiempo, si ya tenían la aceleración gráfica y siguen este método no deben de tener ningún problema y ni siquiera les debe marcar ese molesto warning.

Usuarios de Red Hat y similares la receta es la misma, solo que deberán de tratar de instalar el freeglut-devel***.rpm, donde *** usualmente son la distribución, la arquitectura y versión del paquete, se recomienda que instalen el paquete que viene en sus discos, usualmente este paquete tiene muchas dependencias, así que la ayuda de un gestor de paquetes como yump o synaptic sin duda les ayudara.

En un post posterior hablare de como tener un IDE funcional que nos de mas ayuda a compilar programas de OpenGL en Linux, en particular en Ubuntu la idea es que el final de mi serie de post del tema se pueda tener un entorno de programación cómodo y funcional en Ubuntu, como para que puedan con ayuda de algún libro como el libro rojo autoaprender a programar con OpenGL

Share on Facebook

, , , ,

  1. #1 by Eduardo on 16 febrero 2008 - 6:57 am

    Hola oye segui los pasos que marcaste pero no me funcionaron, a la hora de compilar decia que no se encontraban archivos,

    /usr/include/GL/gl.h y otros mas, que en realidad no existen cuando instale todo lo que dices.

    a ti te funciono asi todo bein sin problemas????
    y tmapoco peuod instalr desde ela rchivo qeu baje de la pgina de opengl

  2. #2 by nemediano on 18 febrero 2008 - 1:59 am

    Hola, te recomiendo que instales por los repositorios mas que por la pagina de OpenGL, a mi me ha funcionado sin problemas, acabo de instalar y desinstalar y comprobé que instala en /usr/lib las bibliotecas y en /usr/include/GL las cabezeras. Realmente no se por que no te funciona.
    De hecho en la descripción del paquete (la estoy viendo en synaptic) mesa-commons-dev, que el instala el archivo que no tienes.
    Se me ocurre que podrías tratar instalando libglui-dev y libglui2c2 que es una librería que depende de OpenGl y de glut, asi que debería de instalarte todo para satisfacer dependencias.

  3. #3 by oaga552 on 2 marzo 2008 - 10:43 am

    Hola
    llevo dias intentando instalar las librerias necesarias para opengl y glut y aun tengo problemas

    Siguiendo tus especificaciones me quedo en el paso 1 al hacer el sudo apt-get build-essential g++ g77 gcc make

    y da lo siguiente:

    oriana@oriana-laptop:~$ sudo apt-get build-essential g++ g77 gcc make
    E: L’opération build-essential n’est pas valable

    el ubuntu esta configurado en frances, pero lo que dice es
    E: la operacion build-essential no es valida

    Necesito Ayuda porfis es urgente
    muchas gracias

  4. #4 by nemediano on 2 marzo 2008 - 19:30 pm

    Hola mi error lo que quería decir es que instalaras los paquetes ahí marcados y cometí un error al escribír el comando le faltaba un install (ya lo corregí en el texto)
    El paquete build-essential no es necesario, tan solo es una recomendación. De hecho el único paquete necesario realmente es freeglut y sus dependencias. Y al compilar puedes omitir todos los parámetros a linker siempre y cuando lo ligues con freeglut. Yo lo pongo completo por que es mas correcto y ademas te aseguras que funcione en cualquier otra distribución de GNU/Linux.
    En resumen:
    sudo apt-get install gcc freeglut3-dev
    Y para compilar
    gcc -Wall ventana.c -o ventana -lglut
    Y debería funcionar, recalco estos son los pasos mínimos sigo recomendando que te instales siguiendo las recomendaciones del post por que así te aseguras que sea mas portable el make y mas importante que estés mas cómodo al programar.
    Saludos y cuenta que tal te fue

  5. #5 by David on 29 junio 2009 - 16:58 pm

    Exelente post, solo tengo una duda yo, uso el glut en dev-C pero lo odio por ser en windows; bueno en si mi duda es si el codigo de la libreria es similar a la de windows y si para usarla tengo que tener activados mis efectos de escritorio…..por cierto soy usser de debian

  6. #6 by nemediano on 29 junio 2009 - 20:14 pm

    Hola David.
    La biblioteca es exactamente igual a su uso en Windows, es la misma biblioteca, solo que implementada en otro S.O.
    De hecho yo programo en Ubuntu, pero para la clase que daba tenia que compilar en Windows con Dev-C++. Mis códigos funcionaban sin necesidad de hacer ningún cambio.
    Respecto a los efectos de escritorio, no es necesario. Solo lo menciono en el post, por si deseas tener aceleración gráfica es una manera de darte cuenta si la tienes. Pero un programa de glut funciona con o sin compiz.
    En debian debe funcionar igual, que en Ubuntu.

  7. #7 by virginia on 29 octubre 2009 - 4:26 am

    Hola! muchas gracias por el pequeño tutorial! ahora puedo empezar a programar con opengl!
    :D

  8. #8 by nemediano on 29 octubre 2009 - 8:24 am

    Hola!!
    Me alegra mucho que te haya servido.
    Saludos

  9. #9 by shadow on 24 noviembre 2009 - 12:51 pm

    q tal oye
    muy buen material
    pero me gustaria integrar opengl y cuda
    solo q no se por donde empezar

  10. #10 by Salvador on 5 julio 2010 - 14:10 pm

    Hola, tengo un problemita.
    Veras a mi me bota el siguiente mensaje:

    error: ‘glutLookAt’ was not declared in this scope

    Y quisiera saber si tengo que incluir alguna librería además de GL/glut para mi código.

    De antemano gracias.

  11. #11 by nemediano on 7 julio 2010 - 10:51 am

    ¡Hola!
    Fíjate que en la ultima versión de ubuntu en la 10.4 cuando se quiere compilar un programa de glut, es necesario ligar con las demás librerías (GL y GLU)

    gcc -Wall miprograma.c -o miprograma -lGL -lGLU -lglut

    Prueba así y espero que te funcione. La GL y GLU van con mayúscula y la glut con minúsculas

  12. #12 by kurenn on 19 agosto 2010 - 17:28 pm

    Amazing tutorial dude….u rock my graphics world!!

  13. #13 by nemediano on 30 agosto 2010 - 13:38 pm

    It’s nice that someone find this stuff useful.

  14. #14 by jaguarg on 22 marzo 2011 - 19:17 pm

    Para comenzar compile el ejemplo y no tuve ningun problema. Me funcionó tal cual lo esperado, pero lo pase por el valgrind y me presento unas problemas aca paso el resultado para ver si me pueden ayudar.

    valgrind –leak-check=yes ventana.cpp
    ==2566== Memcheck, a memory error detector
    ==2566== Copyright (C) 2002-2009, and GNU GPL’d, by Julian Seward et al.
    ==2566== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
    ==2566== Command: ./OpenGL
    ==2566==
    ==2566==
    ==2566== HEAP SUMMARY:
    ==2566== in use at exit: 8,184,770 bytes in 779 blocks
    ==2566== total heap usage: 1,727 allocs, 948 frees, 11,786,537 bytes allocated
    ==2566==
    ==2566== 265 (4 direct, 261 indirect) bytes in 1 blocks are definitely lost in loss record 70 of 146
    ==2566== at 0x4024F20: malloc (vg_replace_malloc.c:236)
    ==2566== by 0x404F2A2: fgHintPresent (freeglut_init.c:217)
    ==2566== by 0x404F959: glutInit (freeglut_init.c:291)
    ==2566== by 0x80487DE: main (ventana.cpp:16)
    ==2566==
    ==2566== 265 (4 direct, 261 indirect) bytes in 1 blocks are definitely lost in loss record 71 of 146
    ==2566== at 0x4024F20: malloc (vg_replace_malloc.c:236)
    ==2566== by 0x404F2A2: fgHintPresent (freeglut_init.c:217)
    ==2566== by 0x404F98A: glutInit (freeglut_init.c:299)
    ==2566== by 0x80487DE: main (ventana.cpp:16)
    ==2566==
    ==2566== 48,400 bytes in 1 blocks are possibly lost in loss record 123 of 146
    ==2566== at 0×4024106: memalign (vg_replace_malloc.c:581)
    ==2566== by 0×4024163: posix_memalign (vg_replace_malloc.c:709)
    ==2566== by 0x4A52C2A: _mesa_align_malloc (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x4B718C1: _mesa_vector4f_alloc (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x4AAB1F0: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x4A9D75C: _tnl_install_pipeline (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49BF559: i915CreateContext (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49D3E0B: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49A413A: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49A41D5: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x40B043C: ??? (in /usr/lib/mesa/libGL.so.1.2)
    ==2566== by 0x4088E6A: ??? (in /usr/lib/mesa/libGL.so.1.2)
    ==2566==
    ==2566== 48,400 bytes in 1 blocks are possibly lost in loss record 124 of 146
    ==2566== at 0×4024106: memalign (vg_replace_malloc.c:581)
    ==2566== by 0×4024163: posix_memalign (vg_replace_malloc.c:709)
    ==2566== by 0x4A52C2A: _mesa_align_malloc (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x4B718C1: _mesa_vector4f_alloc (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x4AAB20F: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x4A9D75C: _tnl_install_pipeline (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49BF559: i915CreateContext (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49D3E0B: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49A413A: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49A41D5: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x40B043C: ??? (in /usr/lib/mesa/libGL.so.1.2)
    ==2566== by 0x4088E6A: ??? (in /usr/lib/mesa/libGL.so.1.2)
    ==2566==
    ==2566== 145,200 bytes in 3 blocks are possibly lost in loss record 139 of 146
    ==2566== at 0×4024106: memalign (vg_replace_malloc.c:581)
    ==2566== by 0×4024163: posix_memalign (vg_replace_malloc.c:709)
    ==2566== by 0x4A52C2A: _mesa_align_malloc (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x4B718C1: _mesa_vector4f_alloc (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x4AA0A09: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x4A9D75C: _tnl_install_pipeline (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49BF559: i915CreateContext (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49D3E0B: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49A413A: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49A41D5: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x40B043C: ??? (in /usr/lib/mesa/libGL.so.1.2)
    ==2566== by 0x4088E6A: ??? (in /usr/lib/mesa/libGL.so.1.2)
    ==2566==
    ==2566== 1,469,856 bytes in 1 blocks are possibly lost in loss record 144 of 146
    ==2566== at 0×4024106: memalign (vg_replace_malloc.c:581)
    ==2566== by 0×4024163: posix_memalign (vg_replace_malloc.c:709)
    ==2566== by 0x4A52C2A: _mesa_align_malloc (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x4A52CFB: _mesa_align_calloc (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x4AB38CF: _tnl_init_vertices (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x4B0F5DC: _swsetup_CreateContext (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49CB9AD: intelInitContext (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49BF519: i915CreateContext (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49D3E0B: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49A413A: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49A41D5: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x40B043C: ??? (in /usr/lib/mesa/libGL.so.1.2)
    ==2566==
    ==2566== 2,232,328 bytes in 1 blocks are possibly lost in loss record 145 of 146
    ==2566== at 0x4024F20: malloc (vg_replace_malloc.c:236)
    ==2566== by 0x4A52D7C: _mesa_malloc (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x4ADC476: _swrast_CreateContext (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49CB995: intelInitContext (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49BF519: i915CreateContext (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49D3E0B: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49A413A: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x49A41D5: ??? (in /usr/lib/dri/i915_dri.so)
    ==2566== by 0x40B043C: ??? (in /usr/lib/mesa/libGL.so.1.2)
    ==2566== by 0x4088E6A: ??? (in /usr/lib/mesa/libGL.so.1.2)
    ==2566== by 0x40892CA: glXCreateNewContext (in /usr/lib/mesa/libGL.so.1.2)
    ==2566== by 0×4057416: fghCreateNewContext (freeglut_window.c:718)
    ==2566==
    ==2566== 4,237,099 (20 direct, 4,237,079 indirect) bytes in 1 blocks are definitely lost in loss record 146 of 146
    ==2566== at 0x4024F20: malloc (vg_replace_malloc.c:236)
    ==2566== by 0x40B040D: ??? (in /usr/lib/mesa/libGL.so.1.2)
    ==2566== by 0x4088E6A: ??? (in /usr/lib/mesa/libGL.so.1.2)
    ==2566== by 0x40892CA: glXCreateNewContext (in /usr/lib/mesa/libGL.so.1.2)
    ==2566== by 0×4057416: fghCreateNewContext (freeglut_window.c:718)
    ==2566== by 0x4057B9C: fgOpenWindow (freeglut_window.c:878)
    ==2566== by 0x4055C3C: fgCreateWindow (freeglut_structure.c:106)
    ==2566== by 0x40571A4: glutCreateWindow (freeglut_window.c:1183)
    ==2566== by 0x804881E: main (ventana.cpp:20)
    ==2566==
    ==2566== LEAK SUMMARY:
    ==2566== definitely lost: 28 bytes in 3 blocks
    ==2566== indirectly lost: 4,237,601 bytes in 747 blocks
    ==2566== possibly lost: 3,944,184 bytes in 7 blocks
    ==2566== still reachable: 2,957 bytes in 22 blocks
    ==2566== suppressed: 0 bytes in 0 blocks
    ==2566== Reachable blocks (those to which a pointer was found) are not shown.
    ==2566== To see them, rerun with: –leak-check=full –show-reachable=yes
    ==2566==
    ==2566== For counts of detected and suppressed errors, rerun with: -v
    ==2566== ERROR SUMMARY: 8 errors from 8 contexts (suppressed: 65 from 12)

    Gracias

  15. #15 by jaguarg on 22 marzo 2011 - 19:25 pm

    Perdon.. falto el código para que observen los números de línea. Gracias

    1 /*
    2 * ventana.cpp
    3 *
    4 * Created on: 22/03/2011
    5 * Author: gianni
    6 */
    7
    8 #include
    9 #include
    10
    11 void Dibuja (void); //la funcion de callback principal,
    12 //dibuja lo que hay en pantalla
    13
    14 int main(int argc, char **argv)
    15 {
    16 glutInit(&argc,argv); //Inicia el toolkit
    17 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //Despliega unsando un solo buffer, y colores R GB
    18 glutInitWindowSize(640, 480); //Tamaño de la ventana en pixeles
    19 glutInitWindowPosition(100, 150); //Posicion en la pantalla
    20 glutCreateWindow(“Ventana”); //Crear la ventana
    21 glutDisplayFunc(Dibuja); //Registra la funcion de redibujado
    22 glutMainLoop(); //Loop sin fin
    23
    24 return 0;
    25 }
    26
    27 //================== Dibuja =========================
    28
    29 void Dibuja (void)
    30 {
    31 glClear(GL_COLOR_BUFFER_BIT); //Limpia la pantalla
    32 glFlush(); //Envia el contenido del buffer a pantalla
    33 }

  16. #16 by nemediano on 22 marzo 2011 - 19:38 pm

    Hola, parece un error en el manejo de memoria de la biblioteca freglut al momento de crear la ventana. Este es un tutorial básico para aprender a usar glut. No es un programa de producción por lo que herramientas de validación muy precisas como Valgrid quedan fuera de mi alcanze,
    Mi recomendación es que te pases por el sitio de freglut y preguntes por allá, que son los programadores expertos en su propia biblioteca y preguntes que hay de malo en usar la biblioteca como se hace en este ejemplo.
    Aunque en general dado que las bibliotecas de glut y freeglut están pensadas no en un ambiente de producción si no en un ambiente de desarrollo de prototipos, es posible que ni ellos estén al tanto de ese leak de memoria (no lo se solo estoy adivinando).
    Mi segunda recomendación es que si a ti, por el tipo de aplicación que quieres hacer te preocupa mucho el manejo de memoria (tanto como para checar tu programa en Valgrind) uses mejor una biblioteca mas estable como Qt o GTK y utilices OpenGL desde sus bindings y no desde (free)glut.
    Gracias por comentar y espero te sirva de ayuda.

  17. #17 by phantom on 2 abril 2011 - 18:32 pm

    Buen dia, segui tus pasos para instalar opengl, pero el momento de correr el programa que pusiste como ejemplo, me sale un error, te lo dejo para que los veas:

    freeglut (./ventana): ERROR: Internal error in function fgOpenWindow
    X Error of failed request: BadWindow (invalid Window parameter)
    Major opcode of failed request: 4 (X_DestroyWindow)
    Resource id in failed request: 0×0
    Serial number of failed request: 30
    Current serial number in output stream: 33

    De antemano, Gracias.

  18. #18 by &23 on 15 agosto 2011 - 14:01 pm

    gracias muy bueno el post…no sabes donde puedo descargar las librerias, esq no me aparecen todas en google

  19. #19 by nemediano on 15 agosto 2011 - 14:17 pm

    Si estas usando cualquier distribución de GNU/Linux desde tus repositorios. Si estas usando MacOS en tu disco de instalación hay herramientas de desarrollo con un equivalente. Si usas Windows pues compila e instala desde la pagina de freglut .
    Ahí puedes encontrar instrucciones. :-P

  20. #20 by tello on 18 septiembre 2011 - 0:54 am

    una pregunta, como lo ejecuto, lo intento de desta forma:

    ./ventana

    pero me tira un error:

    Violacion de segmento

    Gracias

(No será publicado)