modified | Tuesday 28 January 2025 |
---|
SDL_VIDEODRIVER=wayland
needs to be set.Adapted from SDL2 tutorial. It opens a window, color it light red and wait for 3 seconds before closing.
1package main
2
3import (
4 "log/slog"
5 "os"
6 "time"
7
8 "github.com/veandco/go-sdl2/sdl"
9)
10
11func main() {
12 slog.Info("Initializing...")
13 ErrAndExit("Failed to initialize SDL", sdl.Init(sdl.INIT_EVERYTHING))
14 defer sdl.Quit()
15
16 w, err := sdl.CreateWindow("Example", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, 1280, 720, sdl.WINDOWEVENT_SHOWN)
17 ErrAndExit("Failed to create a window", err)
18 defer w.Destroy()
19
20 s, err := w.GetSurface()
21 ErrAndExit("Failed to get window surface", err)
22
23 ErrAndExit("Failed to fill rect", s.FillRect(nil, sdl.MapRGB(s.Format, 255, 90, 120)))
24 ErrAndExit("Failed to update surface", w.UpdateSurface())
25
26 time.Sleep(time.Second * 3)
27}
28
29func ErrAndExit(msg string, err error) {
30 if err != nil {
31 slog.Error("Failed to update surface", "error", err)
32 os.Exit(1)
33 }
34}
It needs to run using the following command otherwise the window appears black:
1SDL_VIDEODRIVER=wayland go run main.go
The output looks like the following
2025/01/26 12:40:32 INFO Initializing...
Replace time.Sleep
with the following, will exit when q
is pressed or the program gets a quit signal from the system
1for {
2 switch e := sdl.PollEvent().(type) {
3 case *sdl.QuitEvent:
4 os.Exit(0)
5 case *sdl.KeyboardEvent:
6 if e.Keysym.Sym == sdl.K_q {
7 os.Exit(0)
8 }
9 }
10}
Before updating the surface we can load an image and draw it
1i, err := sdl.LoadBMP("image.bmp")
2ErrAndExit("Failed to load image", err)
3defer i.Free()
4
5ErrAndExit("Failed to draw image", i.Blit(nil, s, &sdl.Rect{X: 0, Y: 0}))
We need to change our approach. replace the part from creating the window until we update the surface with the following
1w, r, err := sdl.CreateWindowAndRenderer(1280, 720, sdl.WINDOWEVENT_SHOWN)
2ErrAndExit("Failed to create a window", err)
3defer w.Destroy()
4defer r.Destroy()
5
6r.SetDrawColor(255, 90, 120, 0)
7ErrAndExit("Failed to fill rect", r.FillRect(nil))
8
9i, err := sdl.LoadBMP("image.bmp")
10ErrAndExit("Failed to load image", err)
11defer i.Free()
12
13t, err := r.CreateTextureFromSurface(i)
14ErrAndExit("Failed to create texture", err)
15
16r.Copy(t, nil, nil)
17r.Present()
This function loads an image and convert it to SDL surface. It can be used instead of sdl.LoadBMP
so there is no need for SDL image
1func loadImageAsSurface(filePath string) (*sdl.Surface, error) {
2 file, err := os.Open(filePath)
3 ErrAndExit("Failed to open image", err)
4 defer file.Close()
5
6 img, _, err := image.Decode(file)
7 ErrAndExit("Failed to decode image", err)
8
9 bounds := img.Bounds()
10 width, height := bounds.Dx(), bounds.Dy()
11
12 surface, err := sdl.CreateRGBSurfaceWithFormat(0, int32(width), int32(height), 32, sdl.PIXELFORMAT_ABGR8888)
13 ErrAndExit("Failed to create surface", err)
14
15 surface.Lock()
16
17 for y := 0; y < height; y++ {
18 for x := 0; x < width; x++ {
19 surface.Set(x, y, img.At(x, y))
20 }
21 }
22
23 surface.Unlock()
24
25 return surface, nil
26}
Init TTF, Load a font, print hello world to a surface, convert it to texture and draw it
1ErrAndExit("Failed to initialize TTF", ttf.Init())
2defer ttf.Quit()
3
4f, err := ttf.OpenFont("/usr/share/fonts/inter/InterVariable.ttf", 32)
5ErrAndExit("Failed to open fond", err)
6defer f.Close()
7
8txt, err := f.RenderUTF8Solid("Hello world", sdl.Color{R: 255, G: 255, B: 255})
9ErrAndExit("Failed to render text", err)
10defer txt.Free()
11
12txtt, err := r.CreateTextureFromSurface(txt)
13ErrAndExit("Failed to convert text surface to texture", err)
14defer txtt.Destroy()
15
16r.Copy(txtt, nil, &sdl.Rect{X: 10, Y: 10, W: txt.W, H: txt.H})
Split creating the window and renderer to be able to pass flags for VSYNC
1w, err := sdl.CreateWindow("Example", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, 1280, 720, sdl.WINDOWEVENT_SHOWN)
2ErrAndExit("Failed to create a window", err)
3defer w.Destroy()
4
5r, err := sdl.CreateRenderer(w, -1, sdl.RENDERER_ACCELERATED|sdl.RENDERER_PRESENTVSYNC)
6ErrAndExit("Failed to create renderer", err)
7defer r.Destroy()