Webassembly, OpenGL y Qt - Un cubo interactivo en la web
Hace mucho tiempo publiqué un tweet que tuvo cierta tracción, en él mostraba un cubo interactivo en el navegador que había hecho con C++. La magia detrás de ese cubo era una aplicación de Qt compilada para Webassembly utilizando un visor de OpenGL.
Here it is, a little @conan_io/@jfrog/@isocpp cube running in Chrome compiled to #webassembly using #Qt 🤠. Just a couple of steps thanks to the packages and recipes provided by @bincrafters 🤟 I'll write a making of, promise. pic.twitter.com/0XPbifrant
— jgsogo (@jgsogo) January 27, 2019
En aquel momento dije que documentaría el proceso, pero no lo hice. Hoy, casualidades del destino, me siento en deuda con esto de nuevo y ha llegado el momento de comentar cómo se hizo... aunque haya que hacerlo de nuevo porque perdí el código fuente 😅.
He conseguido reproducir el proyecto de una manera más ordenada y quizá algunas de las cosas que se utlizan aquí podrían incorporarse a los paquetes correspondientes de ConanCenter, aunque ése no es el objetivo de este post ni condición para publicarlo.
Las tecnologías que he utilizado, como ya avanzaba, han sido el conocido framework Qt y Emscripten para compilar el código a Webassembly. Con Qt es muy sencillo hacer una aplicación de escritorio con un canvas de OpenGL en el que mostrar un cubo, con Emscripten resulta trivial compilar un proyecto para Webassembly y utilizar el navegador para renderizarlo. ¿Será muy complicado juntar ambos?
Emscripten
El primer paso consiste en preparar Emscripten para compilar código C++ a Webassembly. El proceso es muy sencillo y basta con seguir la documentación disponible en la web:
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
git pull
./emsdk install 1.39.8
./emsdk activate 1.39.8
Esta versión de Emscripten utiliza también Python3 aunque no lo instala, versiones más
nuevas lo incluyen vendorizado. Suponemos que el lector si no lo tiene ya disponible en
el PATH
sabe cómo conseguirlo.
En este proceso es importante notar el fichero emsdk_env.sh
que ha sido generado
anteriormente. Este fichero es un script para activar Emscripten como entorno de
desarrollo, añadirá al PATH
algunos directorios y variables de entorno para utlizar
los compiladores y herramientas que nos permitirán generan Webassembly.
Se recomienda al lector que pruebe algunos ejemplos básicos del getting started para verificar que el compilador funciona y tener una primera experiencia con el proceso.
Qt
El siguiente paso es compilar Qt para Webassembly. En realidad lo que haremos es compilar
para nuestro sistema operativo el build-system qmake
configurado como cross-compilador
que utiliza Webassembly como target. Suena más complicado de lo que es, podemos seguir
los pasos este tutorial.
En primer lugar deberemos activar Emscripten como indicamos anteriormente:
source emsdk/emsdk_env.sh
emcc -v
Y descargar y compilar Qt para Webassembly:
wget http://download.qt.io/official_releases/qt/5.15/5.15.2/single/qt-everywhere-src-5.15.2.tar.xz
xz -d qt-everywhere-src-5.15.2.tar.xz
tar xopf qt-everywhere-src-5.15.2.tar
cd qt-everywhere-src-5.15.2
./configure -xplatform wasm-emscripten -nomake examples -nomake tests -prefix $(pwd)/qtbase
make -j16 module-qtbase module-qtdeclarative
El proceso anterior tomará su tiempo, aprovecha para repasar algún ejemplo con Emscripten o refrescar
tus conocimientos de Qt. Tal vez sea un buen momento para buscar un Hello World!
sencillo y ver cómo
funciona qmake
con los ficheros .pro
para generar las aplicaciones de Qt. Será útil en lo que viene
a continuación.
Una vez terminado el proceso anterior debería haberse generado el ejecutable qtbase/bin/qmake
, éste
es nuestro build-system preparado para cross-compilar utilizando Emscripten.
Si creaste ese pequeño Hello world!
, ahora es el momento de comprobar que todo funciona. Dentro de su
directorio sólo tienes que ejecutar:
cd hello-world
.../qtbase/bin/qmake
make
Ahora no tienes más que abrir el fichero .html
con tu navegador de cabecera. ¡Voilá! Lo que antes
era una aplicación de escritorio se ha convertido en una applicación web. El mismo código en C++ lo
hemos utilizado para generar una aplicación para dos plataformas totalmente diferentes... esto abre
un horizonte de posibilidades muy interesante para explorar.
El cubo
Ya tenemos todas las piezas disponibles y únicamente nos falta el cubo. El cubo no es más que una aplicación de Qt con una ventana de OpenGL. Yo utilicé como base el ejemplo de OpenGL ES 2.0, cambié la textura e hice unos ajustes.
En este repositorio
podéis encontrar el código fuente que yo utilicé. Utilizando los pasos
anteriores debería compilarse una aplicación para Webassembly que podéis abrir en vuestro
navegador:
Example of Qt application using OpenGL
git clone https://github.com/jgsogo/qt-opengl-cube.git
cd qt-opengl-cube/qt-opengl-example
.../qtbase/bin/qmake
make