Welcome. This is a C99 codebase which will let you get started with creating
native OpenGL demos on Linux. The repository is structured so that
data/
contains binary files (assets such as music),
shaders/
contains shaders,
src/
contains source code,
scripts/
contains scripts
that are required for building the demo and
lib/
contains third-party libraries (git submodules).
The result is an executable which shows some GLSL shaders with music, sync and post processing, and won't depend on any other files. We've chosen to compile and statically link all libraries except for libc, so that the released production depends on least possible stuff.
Warning! This project fails to build if it is stored in a path with spaces.
For example /home/user/My Projects/linux_demo
won't work. This is due to
fundamental limitations in SDL2's build process.
First we need to fetch some third-party libraries:
git submodule update --init
You will need a C compiler (gcc
or clang
recommended) and some library
headers. This repository does not use a fancy build system, opting to use just
GNU make
for simplicity.
sudo apt install build-essential xxd libsdl2-dev
sudo pacman -S base-devel vim sdl2
Just run
make -j $(nproc)
This will use all CPU cores you have available.
- Put your
music.ogg
file intodata
directory. - Edit
src/config.h
to match your desired resolution and your music track's BPM! Don't skip this. Then runmake
once more. - Open your rocket editor. I prefer the default Qt-based rocket editor.
- Start
./build/demo
- Open
shaders/shader.frag
in your editor. - Hack on shaders! Uniforms prefixed with
r_
will automatically show up in rocket. - Reload shaders and uniforms by pressing R. No
make
or restart needed.
It can be encoded with the following command:
ffmpeg -i YOUR_MUSIC_FILE -c:a libvorbis data/music.ogg
The default shaders/shader.frag
includes a "look at"
-style camera for SDF raymarching. It's variables will show up in Rocket as
tracks, and before you set reasonable values to them, nothing will render.
A good starting point is to set Fov to some value between 45 and 90, Pos.z to 3, leave Target as all zeroes (the origin). Also try and see what other rocket tracks do.
Your demo is getting ready and you want to build a release build? Just run
make -j $(nproc) DEBUG=0 SELF_CONTAINED=1
This builds a release/demo
which can be copied anywhere and won't need the
rocket editor to run.
For example: if you build a release build on an Arch Linux which has glibc 2.37
,
the demo cannot run on an Ubuntu 22.04 because it ships with glibc 2.35
!
To avoid this gotcha, you must build your release on the same (or possibly older) distribution release as the intended target platform (compo machine). One way to do that is to use a container system like docker or podman to build your release.
Example run for podman
, as your normal user:
make clean
podman run -it --rm -v.:/build ubuntu:20.04
apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install build-essential xxd libsdl2-dev
cd /build
make -j $(nproc) DEBUG=0 SELF_CONTAINED=1
mv release/demo .
make clean
exit
Instructions for installing podman on Arch Linux can be found on the Arch Wiki.
The Makefile also supports release builds without the SELF_CONTAINED
feature.
These builds read files from the host filesystem directories data/
and shaders/
.
If you build without SELF_CONTAINED=1
, you will have to distribute all data and
shader files along with the executable.
OpenGL ES 3.1 build on Linux can be enabled with the make option GLES=1
.
Experimental MinGW-w64 support also exists. Install mingw-w64-sdl2
and
mingw-w64-make
from the AUR on Arch Linux, and run x86_64-w64-mingw32-make
instead of make
.
Always remember to run make clean
before changing build options or plaforms!
scripts/
has a shell-dropping
packer. This can reduce about 10% from filesize (ymmv).
However, this may reduce compatibility as it requires xz-utils
to be installed and /tmp
directory to allow executables.
scripts/pack.sh release/demo
We use the industry-standard SDL2 library as a base for audio output, keyboard (quit-button), windowing and OpenGL context creation.
OpenGL along with your graphics card drivers does the heavy lifting for rendering your demo.
stb_vorbis is a single C source file audio codec library for OGG Vorbis, which we use to avoid having to release a huge file with uncompressed audio.
And finally, rocket is a sync tracker along with a library to edit your demo's synchronization with music without having to change code and recompile.
The src/
directory contains about 1000 lines of commented C99 code,
which you can read starting from any file.
Here is is a list of the source units in (subjectively) decreasing order of importance:
main.c
: Initializes window, OpenGL context, audio, music player, rocket. Contains demo's main loop.demo.c
/demo.h
: Most OpenGL calls happen in this unit.shader.c
/shader.h
: Loading and compiling shaders.preprocessor.c
/preprocessor.h
: A limited GLSL preprocessor.uniforms.c
/uniforms.h
: Contains code for querying uniforms in shader programs.music_player.c
/music_player.h
: Music player with OGG Vorbis streaming, seeking and timing support for sync editor.filesystem.c
/filesystem.h
: Includesdata.c
whichscripts/mkfs.sh
generates at build time. Has functions for reading embedded files.rand.c
/rand.h
: A xoshiro PRNG implementation, mostly used for post processing noise.