A C++ framework that makes creating cross-platform games and other interactive applications easier and faster https://shampoo.ooo
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
frank f47c080d72 box demo android support, android file to string for reading files inside APK 3 months ago
demo box demo android support, android file to string for reading files inside APK 3 months ago
icon box demo android support, android file to string for reading files inside APK 3 months ago
lib changed get_configuration to configuration; added option to return the larger ratio to box aspect; changed default window size to 16:9; changed get_window to window; added SDL_RENDERER_PRESENTVSYNC; removed clear renderer to black on emscripten builds to prevent mouse bug; 8 months ago
src box demo android support, android file to string for reading files inside APK 3 months ago
.gitignore added ability to set some GL properties with config, added some more GL properties to log 4 months ago
BPmono.ttf - framerate indicator sprite added to Game class 3 years ago
LICENSE.txt box demo android support, android file to string for reading files inside APK 3 months ago
LICENSE_BPmono.txt added licensing info 2 years ago
README.md box demo android support, android file to string for reading files inside APK 3 months ago




       /\         +------------------------------------------------------+ 
  ____/  \____   /| - Open source game framework licensed to freely use, |
  \          /  / |   copy, modify and sell without restriction          |
+--\ ^__^   /--+  |                                                      |
| ~/        \~ |  | - created for              |
| ~~~~~~~~~~~~ |  +------------------------------------------------------+
| SPACE ~~~~~  | /
|  ~~~~~~~ BOX |/

SPACEBOX is a C++ framework that makes creating cross-platform games and other interactive applications easier and faster by providing an added layer of abstraction between SDL + OpenGL and the project.

Users can start a project by extending only a single function, the Game class's update function. Using a standard Makefile that can be taken from the examples, the framework can export the same code to multiple platforms like, in order of current stability, Linux, Web, Android, OS X, Windows, and Raspberry Pi.

It is in an early, untested state. It comes with a few simple examples that demonstrate how to use it.


The repository includes some external libraries in lib/ that the default Makefile included with the demo shows how to compile, but there are other requirements, including external libraries that must be linked to a project in order to compile it.

  • libSDL2 (developed against v2.0.22)
  • libSDL2-image
  • libSDL2-ttf
  • libSDL2-mixer
  • compiler that supports C++17

Installing Requirements

libSDL2, libSDL2-image, libSDL2-ttf, and libSDL2-mixer must be available to link with your project, so you can try your package manager's libSDL2 dev packages or build from source. The included sdl2-config utility program can be used to generate flags for linking to SDL2 when it is installed outside of your platform's usual library location.


  • Download the SDL source package
  • Run ./configure --prefix=[YOUR LIBRARIES PATH] (for example, $HOME/local/sdl)
  • Run make && make install

libSDL2-image, libSDL2-ttf, libSDL2-mixer


  • Install GL/GLES according to your platform and link to it during compilation. GLEW is included in the lib/ folder of this framework and should find GL on your platform if it is installed.


Building a SPACEBOX project is currently best accomplished by duplicating and adapting the fill_screen demo included in this repository or an in-progress game like Gunkiss or Pepy. The library requirements described above (SDL and OpenGL), a copy of this repository, and a Makefile based on the one in the project being duplicated are necessary for compilation.

SPACEBOX itself currently needs to be compiled along with the project's source, since there aren't any library builds of it.


This is the platform SPACEBOX is built on, so it has the most straightforward build process. Copy the Makefile from the fill_screen demo, which demonstrates how to compile SPACEBOX and link to required libraries, adapt it to fit a new project, and build a Linux executable with GNU make.


Exporting a browser build with Emscripten and its built-in version of SDL has worked well on a few projects. The general process is to create a separate make target that uses Emscripten's C++ to WebAssembly compiler. See the browser webcam demo below for an example.


The fill_screen demo has a working example of how to build for Android. It may be worthwhile to read the SDL wiki Android page and SDL docs Android README and compile an SDL example for Linux before doing a SPACEBOX Android build. The source distributions for SDL, SDL image, SDL ttf, and SDL mixer, and the Android SDK are required.

Building an SDL example for Linux

  • Install Java packages

      apt install openjdk-17-jdk ant
  • Make a folder for Android to store the SDK, NDK, emulator, tools, etc.

      mkdir -p ~/local/Android/
  • Download Android command line tools to that folder, extract them, and install an NDK (the gradle tool included with SDL defaults to NDK 21.4.7075529). Note that the gradle tool may download Android tools, but this step seems to be necessary for signing the license, which gets created in licenses

      $ cd ~/local/Android/
      $ unzip commandlinetools-linux-8512546_latest.zip
      $ cmdline-tools/bin/sdkmanager --sdk_root=$HOME/local/Android/ "ndk;21.4.7075529"
  • Download and extract SDL source

      $ wget "https://github.com/libsdl-org/SDL/releases/download/release-2.24.0/SDL2-2.24.0.tar.gz"
      $ tar -xf SDL2-2.24.0.tar.gz
      $ cd SDL2-2.24.0/
  • Copy android-project/ to another folder, symlink the SDL source,

      $ cp -r android-project org.my.testgles
      $ cd org.my.testgles/app/jni
      $ ln -s ../../.. SDL
  • Edit the line with YourSourcehere.c in org.my.testgles/app/jni/src/Android.mk to point to an SDL example

      $ cd src/ && sed -i s#YourSourceHere.c#../SDL/test/testgles.c# Android.mk
  • Build with gradlew in the root of the project, specifying where to find the Android folder

      $ ANDROID_SDK_ROOT=$HOME/local/Android ./gradlew build
  • The APK should be output to app/build/outputs/apk/debug/app-debug.apk. It can be uploaded to the phone for testing or run on an emulator. To create an emulator, use the Android SDK's tools. For example, to create an Android emulator for API level 31 (Android 12.0) with ABI x86_64.

      # Install a version of command line tools with support for later versions of Java
      $ cmdline-tools/bin/sdkmanager --sdk_root=$HOME/local/Android "cmdline-tools;latest"
      # Install a system image
      $ cmdline-tools/bin/sdkmanager --sdk_root=$HOME/local/Android "system-images;android-31;default;x86_64"
      # Create emulator
      $ cmdline-tools/latest/bin/avdmanager create avd -n android_31_x86_64 -k "system-images;android-31;default;x86_64"
      # Launch in the background
      $ ~/local/Android/tools/emulator -avd android_31_x86_64 &
      # Install the APK to the running emulator
      $ ~/local/Android/platform-tools/adb -e install -r app/build/outputs/apk/debug/app-debug.apk

fill_screen demo

The fill_screen demo has a Makefile that should work for building for Android if the paths in the file are adjusted to match the project. Edit the Makefile and run make build/android/[org.my.app]. If that isn't working, see below for notes on how the build was originally done manually.

Creating the fill_screen Android build

These steps were taken to build the fill_screen demo for Android. The Android SDK is assumed to be installed as explained above in the SDL test example. The instructions are based on SDL 2.24.0. There is also a Makefile target that scripts this process in [demo/fill_screen/Makefile][].

  • Copy the included Android project in the SDL source into the root of the fill_screen project folder.

      $ cp -r path/to/SDL2-2.24.0/android-project [fill_screen root]/ooo.shampoo.fill_screen
      $ cd [fill_screen root]/ooo.shampoo.fill_screen
  • Edit the application ID

      $ sed -i s/org.libsdl.app/ooo.shampoo.fill_screen/ app/build.gradle app/src/main/AndroidManifest.xml
  • Enable C++ STL

      $ sed -i "s/^#.*\(APP_STL\)/\1/" app/jni/Application.mk
  • Enable C++ 17 features and exceptions

      $ echo "APP_CPPFLAGS := -std=c++17 -fexceptions -frtti" >> app/jni/Application.mk
  • Modify rules to allow OpenGL ES 3.0 (necessary for example for using GL_RGBA8)

      $ sed -i -e 's/^LOCAL_LDLIBS.*/& -lGLESv3/' app/jni/src/Android.mk
      $ sed -i 's/0x0002/0x0003/' app/src/main/AndroidManifest.xml
      $ sed -i 's/\(minSdkVersion\).*16/\1 18/' app/build.gradle
      $ sed -i 's/\(android\)-16/\1-18/' app/build.gradle app/jni/Application.mk
  • std::filesystem is only available in NDK 22+, so install NDK version 22 and set the project to use it

      $ ~/local/Android/cmdline-tools/bin/sdkmanager --sdk_root=$HOME/local/Android --install "ndk;22.1.7171670"
      $ sed -i '11i\    ndkVersion "22.1.7171670"' app/build.gradle
  • Link to SDL source packages (versions other than the listed ones may work)

      $ ln -s path/to/SDL2-2.24.0 app/jni/SDL
      $ ln -s path/to/SDL2_image-2.6.2 app/jni/SDL2_image
      $ ln -s path/to/SDL2_mixer-2.6.2 app/jni/SDL2_mixer
      $ ln -s path/to/SDL2_ttf-2.20.1 app/jni/SDL2_ttf
  • Add SDL packages as libraries in the Makefile

      $ sed -i 's/^LOCAL_SHARED_LIBRARIES.*/& SDL2_image SDL2_mixer SDL2_ttf/' app/jni/src/Android.mk
  • Add SPACEBOX lib/ and src/ to include search path. In this command, the paths are relative to the path of Android.mk and based on the location of fill_screen as included in the SPACEBOX repository, but they can be edited to other paths if necessary.

      $ sed -i 's#^LOCAL_C_INCLUDES.*#& $(LOCAL_PATH)/../../../../../../lib $(LOCAL_PATH)/../../../../../../src#' \
  • Add SPACEBOX source files from lib/ src/ and source files for fill_screen

      $ sed -i 's#YourSourceHere.c#$(LOCAL_PATH)/../../../../fill_screen.cpp#' app/jni/src/Android.mk
      $ sed -i 's#^LOCAL_SRC_FILES.*#& $(wildcard $(LOCAL_PATH)/../../../../../../src/*.cpp)#' app/jni/src/Android.mk
      $ sed -i 's#^LOCAL_SRC_FILES.*#& $(wildcard $(LOCAL_PATH)/../../../../../../lib/sdl2-gfx/*.c)#' app/jni/src/Android.mk
  • Create a file at app/src/main/java/ooo/shampoo/fill_screen/FillScreen.java with the following contents

      package ooo.shampoo.fill_screen;
      import org.libsdl.app.SDLActivity;
      public class FillScreen extends SDLActivity {
          protected String getMainFunction() {
              return "main";
  • Edit the manifest to point to that class

      $ sed -i 's/\(name=\)"SDLActivity"/\1"FillScreen"/' app/src/main/AndroidManifest.xml
  • Run gradle

      $ ANDROID_SDK_ROOT=$HOME/local/Android ./gradlew build

OS X, Windows, Raspberry Pi

Builds for these platforms have only passed the proof of concept phase. An early version of SPACEBOX was compiled for each of them, but none of the demos have been compiled for them in their current form, so there is only some broken code available in the cube demo Makefile.


The demo/ folder contains programs that demonstrate and test the capabilities of the framework. In order to compile each, you should edit the definitions in the Makefile.


This is intended to be a bare minimum test of the framework which loads the framework and fills the screen with a new color each frame. It currently only builds to Linux but will be ported to every platform in order to test each platform's build process.

browser webcam

An example for using a C++ program to display a webcam stream in the browser using Emscripten to translate the code from C++ to WebAssembly. Get the frame pixel data from a canvas element, read it into a SPACEBOX object, write the pixel data to an OpenGL texture, and use Emscripten to display the video.


Switch between GL and SDL contexts by pressing spacebar. The GL context draws a textured, rotating cube, and the SDL context draws basic geometric shapes and a moving 2D sprite. (Note: support for SDL context is being removed in favor of GL context as even SDL recommends for new projects)


Test collision detection between a 2D sprite and other 2D sprites and boxes. Per-pixel collision can be tested. (Note: as support for SDL context is being removed in favor of GL context, the Sprite class will be either changing drastically or possibly removed entirely in favor of using a Model class)


Map an image from a rectangle to a circle or from a circle to a rectangle using a shader program. Based on a blog post about elliptical grid mapping equations.

Other libraries

These are other libraries that have been used in projects that use this framework but aren't required by the framework



Download from https://opencv.org/releases/ and create a build directory, then configure and make. This example uses a custom installation path:

$ mkdir build_linux/ && cd build_linux/
$ cmake -DCMAKE_INSTALL_PREFIX=$HOME/local/opencv ..
$ make && make install

The core, imgproc, videoio, and highgui modules can then be linked to by adding the following to the linker flags:

-L$(HOME)/local/opencv/lib -Wl,-rpath,$(HOME)/local/opencv/lib -lopencv_videoio -lopencv_core -lopencv_highgui \ 

The specific modules needed may vary depending on the project. There are detailed instructions for building OpenCV on Linux available at [https://docs.opencv.org/4.6.0/d7/d9f/tutorial_linux_install.html]. There are also contributed modules available, which can be downloaded separately and compiled with the core modules. For example, this command builds all the modules in ../../opencv_contrib-4.x/modules, except python3, along with the core modules.

$ cmake -D CMAKE_INSTALL_PREFIX=$HOME/local/opencv -D OPENCV_EXTRA_MODULES_PATH="../../opencv_contrib-4.x/modules" -D \ 
    BUILD_opencv_python3=OFF ..


To build the WASM libraries necessary to include OpenCV in an Emscripten build of a SPACEBOX project, set up the Emscripten environment and run OpenCV's build_js.py script with the WASM output option. Note that OpenCV's cv::VideoCapture object will not be available in the libraries built this way because OpenCV emulates that object in its JS implementation.

$ source [EMSDK_PATH]/emsdk_env.sh
$ python3 [OPENCV_PATH]/platforms/js/build_js.py --emscripten_dir [EMSCRIPTEN_PATH] build_wasm --build_wasm

There is a detailed explanation of this process at [https://docs.opencv.org/4.6.0/d4/da1/tutorial_js_setup.html]. And useful information for getting around the absence of cv::VideoCapture at [https://docs.opencv.org/4.6.0/dd/d00/tutorial_js_video_display.html]. Check out a minimal example of using OpenCV with C++ and Emscripten at [https://github.com/mpizenberg/emscripten-opencv]. There is also information on how to build the contributed modules as WASM libraries in the first link.

At the time of writing this, the contributed module for barcode scanning needs -DBUILD_PROTOBUF=ON added to the build_js.py script and needs js added to its list of wrapper languages in its CMakeLists.txt file to compile successfully.

To link to the WASM libraries, add the *.a files from the build directory to Emscripten's linker flags. Add both lib/*.a and 3rdparty/lib/*.a. For GNU Make, this might look like the following.

$(wildcard $(addprefix $(WASM_BUILD_DIR)/lib/,*.a)) $(wildcard $(addprefix $(WASM_BUILD_DIR)/3rdparty/lib/,*.a))



Download from http://zbar.sourceforge.net/download.html and configure to only use image processing features (requires the imagemagickwand library, available from, for example apt get libmagickwand-dev) and choose your installation directory:

./configure --without-gtk --without-python --without-qt --without-xshm --without-xv --without-jpeg \
    --disable-video --prefix=$HOME/local/zbar


make && make install


To build a WASM library that can be used to build an Emscripten version of a SPACEBOX project, set up the Emscripten environment and configure using emconfigure with the same disable flags as above.

$ source emsdk_env.sh
$ emconfigure ./configure --without-gtk --without-python --without-qt --without-xshm --without-xv --without-jpeg \
$ emmake make
$ find . -iname *.a

There is a detailed tutorial on using Zbar with WebAssembly at https://barkeywolf.consulting/posts/barcode-scanner-webassembly/


When initializing a Game object, the framework will attempt to load the font file "BPmono.ttf" from the project root (where the compiled executable is located). If this file isn't found, the program can still run successfully, but the framerate indicator (mapped to CTRL+f by default) will be disabled. The repository contains "BPmono.ttf", so you can create a symlink to the file in the project root if you want to use the framerate indicator.


[SPACEBOX] is released under the zlib license. It is free to use, copy, modify and sell. See LICENSE.txt for details.

Included libraries are included under various permissive licenses compatible with the zlib license:

  • BPmono.ttf is licensed under the Creative Commons Attribution * No Derivative Works 3.0 license. See LICENSE_BPmono.txt
  • gif-h is unlicensed, public domain code released under the The Unlicense. See lib/gif-h/LICENSE
  • GLEW is included under the license in lib/glew/LICENSE.txt
  • GLM is included under the MIT license in lib/glm/LICENSE
  • nlohmann's json library is included under the MIT license in lib/json/LICENSE.MIT
  • SDL2 GFX is included under the license in lib/sdl2-gfx/LICENSE
  • superxbr.cpp is included under the license at the top of lib/superxbr.cpp