Go bindings for SFML, the Simple and Fast Multimedia Library, version 2.5.1
Originally made by teh-cmc
These bindings are entirely generated using SWIG and the official C bindings of SFML.
Hence they should be fairly easy to maintain & keep in sync with future releases from upstream
- Portability
- Usage
- Building go-sfml
I have only tested these on Windows 10
Feel free to open issues and/or PRs if you're running into problems on other platforms
I'll cover Windows in this section (I build go-sfml using WSL, but build my go apps on Windows)
- Download CSFML 2.5.1 and extract it wherever you like (assuming
C:\CSFML_2.5.1
for the next steps). I'm downloading the 64 bits version since I'm on a 64 bits Windows - Download and install the GCC compiler (in my case, the mingw x86_64-win32-sjlj one)
- We now need to define the
CGO_CFLAGS
andCGO_LDFLAGS
environment variables so the linker knows where the CSFML headers and compiled libraries are at
Assuming CSFML is extracted at C:\CSFML_2.5.1
, we can run the following in a command line :
set CGO_CFLAGS="-IC:\CSFML_2.5.1\include"
set CGO_LDFLAGS="-LC:\CSFML_2.5.1\lib\gcc"
Feel free to set those variables system-wide so you don't have to define them on the fly everytime
Notice the -I and -L before the paths, with no whitespace in between
- Build the example to ensure your setup is working
cd examples/basic_window
go get && go build
- Copy the CSFML DLLs next to your executable, for the basic example we only need
csfml-window-2.dll
andcsfml-graphics-2.dll
that you'll find intoC:\CSFML_2.5.1\bin
- Run the exe, a red window should appear!
For future projects, simply run
go get github.com/telroshan/go-sfml/v2
And import the modules you need
import (
"github.com/telroshan/go-sfml/v2/graphics"
"github.com/telroshan/go-sfml/v2/window"
"github.com/telroshan/go-sfml/v2/system"
"github.com/telroshan/go-sfml/v2/audio"
)
→ Make sure you have downloaded the CSFML version that matches your system (don't download the 32 bits one if you're on a 64 bits Windows)
→ Make sure you included the subfolder matching your compiler (gcc here) for CGO_LDFLAGS
, and didn't make it point to the lib
root folder itself
→ Make sure you defined the environment variables in the same command line that you ran go build
into (the variables defined with the set
command won't exist outside of the command line they've been set into)
→ Make sure you typed the variable names correctly, i.e CGO_CFLAGS
and CGO_LDFLAGS
→ Make sure you didn't invert the paths between the two variables. CGO_CFLAGS
should point to the include
folder whereas CGO_LDFLAGS
should point to the libs
→ Make sure you made no typo with the syntax of -I and -L for those variables
Error: imports github.com/telroshan/go-sfml/v2/window: build constraints exclude all Go files in [...]
→ You need to define the environment variable CGO_ENABLED
. As the doc says:
The cgo tool is enabled by default for native builds on systems where it is expected to work. It is disabled by default when cross-compiling. You can control this by setting the CGO_ENABLED environment variable when running the go tool: set it to 1 to enable the use of cgo, and to 0 to disable it.
set CGO_ENABLED=1
→ You probably didn't copy CSFML DLLs next to your executable, as mentioned in step 5
Alternatively to steps 3 to 5 from the previous section, you could use a bat script to automate that process for you, such as the one in the basic window example
@ECHO OFF
rem This script sets the environment variables to be able to build the app, and copies the CSFML DLLs over if there aren't any in the folder
rem Edit the CSFML_PATH variable to match the path of your CSFML installation
set CSFML_PATH=C:\CSFML_2.5.1
rem Edit the COMPILER_NAME variable if you're not using gcc
set COMPILER_NAME=gcc
set CGO_CFLAGS="-I%CSFML_PATH%\include"
set CGO_LDFLAGS="-L%CSFML_PATH%\lib\%COMPILER_NAME%"
go get
if %ERRORLEVEL% NEQ 0 (echo go get failed && exit /b %ERRORLEVEL%)
go build
if %ERRORLEVEL% NEQ 0 (echo go build failed && exit /b %ERRORLEVEL%)
echo Build complete
if not exist "%~dp0*.dll" (
echo No DLLs in folder, getting them from CSFML folder
xcopy /s "%CSFML_PATH%\bin" "%~dp0"
if %ERRORLEVEL% NEQ 0 (echo failed to copy DLLs && exit /b %ERRORLEVEL%)
)
The generated APIs very closely follow those of SFML's C bindings: the tutorials & documentation available for the official C++ implementation, as well as an editor with a well configured Go-autocompletion, will get you a long way
The original C & C++ implementations of SFML come with 5 modules: Audio, Graphics, Network, System and Window
Of these 5 modules:
- Audio, Graphics & Window come with complete Go packages counterparts
- System also has a dedicated Go package, but only contains the
sfVector2
&sfVector3
classes; everything else is already available in one form or another in Go's standard library - Network has been entirely discard, use Go's standard library instead
Here's a straightforward example of creating a window and handling events:
package main
import (
"runtime"
"github.com/telroshan/go-sfml/v2/graphics"
"github.com/telroshan/go-sfml/v2/window"
)
func init() { runtime.LockOSThread() }
func main() {
vm := window.NewSfVideoMode()
defer window.DeleteSfVideoMode(vm)
vm.SetWidth(800)
vm.SetHeight(600)
vm.SetBitsPerPixel(32)
/* Create the main window */
cs := window.NewSfContextSettings()
defer window.DeleteSfContextSettings(cs)
w := graphics.SfRenderWindow_create(vm, "SFML window", uint(window.SfResize|window.SfClose), cs)
defer window.SfWindow_destroy(w)
ev := window.NewSfEvent()
defer window.DeleteSfEvent(ev)
/* Start the game loop */
for window.SfWindow_isOpen(w) > 0 {
/* Process events */
for window.SfWindow_pollEvent(w, ev) > 0 {
/* Close window: exit */
if ev.GetEvType() == window.SfEventType(window.SfEvtClosed) {
return
}
}
graphics.SfRenderWindow_clear(w, graphics.GetSfRed())
graphics.SfRenderWindow_display(w)
}
}
For comparison's sake, the exact same thing in C:
#include <SFML/Window.h>
#include <SFML/Graphics.h>
int main() {
sfVideoMode mode = {800, 600, 32};
sfRenderWindow* window;
sfEvent event;
/* Create the main window */
window = sfRenderWindow_create(mode, "SFML window", sfResize | sfClose, NULL);
if (!window)
return 1;
/* Start the game loop */
while (sfRenderWindow_isOpen(window)) {
/* Process events */
while (sfRenderWindow_pollEvent(window, &event)) {
/* Close window : exit */
if (event.type == sfEvtClosed)
sfRenderWindow_close(window);
}
/* Clear the screen */
sfRenderWindow_clear(window, sfRed);
sfRenderWindow_display(window);
}
/* Cleanup resources */
sfRenderWindow_destroy(window);
}
You'll find other examples in the examples folder
- Basic window : just the same as above
- Tennis : go version of SFML's tennis example
Feel free to open PRs if you have any example you'd like to share!
If you just want to use go-sfml for SFML 2.5.1 into your go project, you may want to read the Usage section instead
If you want to build your own bindings for a different version of SFML, then this section is for you!
Note: the following steps were realized in Windows' Ubuntu bash. Feel free to open issues and/or PRs if you're running into problems on other Unix-based platforms
- Install SFML dependencies first
- Run the
sfml.sh
script to handle the process of downloading SFML/CSFML and compiling them for you
→ You're probably having CRLF issues (happened to me when cloning the repo on Windows initially before switching to WSL)
→ Use dos2unix
(install it if you don't have the command) on the 3 scripts : dos2unix sfml.sh swig.sh build.sh
Error: CMake Error [...] Could not find X11
(or a similar error with just another name instead of X11
)
Could not find X11 Call Stack (most recent call first): src/SFML/Window/CMakeLists.txt (find_package)
→ You probably didn't install every SFML dependency. Don't forget the development headers as well! For example on Ubuntu, you'll want to install libx11-dev
, xorg-dev
, libudev-dev
, and so on
- Depending on your platform, you may simply download the available package. For example on Ubuntu,
sudo apt install swig
- Run
sudo apt install libpcre3-dev
(swig requires this package) - Run the
swig.sh
script - Check where swig thinks its lib is, by running
./swig/swig -swiglib
. It should output${path/to/go-sfml}/swig/Lib
- If the output doesn't match, fix that by overriding the
SWIG_LIB
environment variable. You may runexport SWIG_LIB=${path/to/go-sfml}/swig/Lib
to override the var just for your current session, or make it persistent - Run
./swig/swig -swiglib
again to ensure swig has the correct path to its own lib - Update the
build.sh
script and change the line 23 : the script is looking for a global commandswig
, you must replace that path by./swig/swig
to use the local build instead
→ You're probably having CRLF issues (happened to me when cloning the repo on Windows initially before switching to WSL)
→ Use dos2unix
(install it if you don't have the command) on the 3 scripts : dos2unix sfml.sh swig.sh build.sh
→ You probably didn't install libpcre3-dev as mentioned in step 1. Run sudo apt install libpcre3-dev
and try again
- Run
sudo apt install patchelf
(the build script uses this package to fix the missing links from the built CSFML libraries to the SFML ones) - Run
build.sh
→ You're probably having CRLF issues (happened to me when cloning the repo on Windows initially before switching to WSL)
→ Use dos2unix
(install it if you don't have the command) on the 3 scripts : dos2unix sfml.sh swig.sh build.sh
→ You probably either did not install the swig
package, or built it locally but forgot to follow the step 6 to update the path used by the build.sh
script
→ You probably went for the swig local build, but didn't check for its lib path. Please follow steps 3 to 5 of that section
→ You probably didn't install patchelf
as mentioned in step 1
You're now ready to go!
Feel free to open issues and/or PRs if you're running into problems that are not mentioned in the troubleshooting sub-sections