Skip to content

Instantly share code, notes, and snippets.

@nakagami
Created May 31, 2025 01:08
Show Gist options
  • Save nakagami/fdcb449d53e270d9ddd09356163851e5 to your computer and use it in GitHub Desktop.
Save nakagami/fdcb449d53e270d9ddd09356163851e5 to your computer and use it in GitHub Desktop.
go-sdl2 example. Paint RGBA image
package main
import (
"fmt"
"github.com/veandco/go-sdl2/sdl"
"image"
"image/color"
"math/rand"
"unsafe"
)
func paintImage(img *image.RGBA, window *sdl.Window, destX, destY int) {
surface, _ := window.GetSurface()
surface.Lock()
defer surface.Unlock()
w, h := img.Bounds().Dx(), img.Bounds().Dy()
surfW, surfH := int(surface.W), int(surface.H)
for y := 0; y < h; y++ {
for x := 0; x < w; x++ {
sx, sy := destX+x, destY+y
if sx < 0 || sy < 0 || sx >= surfW || sy >= surfH {
continue
}
offset := img.PixOffset(x, y)
r := img.Pix[offset+0]
g := img.Pix[offset+1]
b := img.Pix[offset+2]
a := img.Pix[offset+3]
color := sdl.MapRGBA(surface.Format, r, g, b, a)
pixels := surface.Pixels()
ptr := uintptr(unsafe.Pointer(&pixels[0]))
pitch := int(surface.Pitch)
pxOffset := sy*pitch + sx*4 // RGBA32bit
*(*uint32)(unsafe.Pointer(ptr + uintptr(pxOffset))) = color
}
}
window.UpdateSurface()
}
func main() {
var (
winTitle string = "Surface Example"
winWidth int32 = 800
winHeight int32 = 600
window *sdl.Window
event sdl.Event
running bool = true
)
img := image.NewRGBA(image.Rect(0, 0, 200, 200))
for y := 0; y < 200; y++ {
for x := 0; x < 200; x++ {
img.Set(x, y, color.RGBA{R: uint8(x), G: uint8(y), B: 128, A: 255})
}
}
if err := sdl.Init(sdl.INIT_VIDEO); err != nil {
fmt.Println("Failed to initialize SDL:", err)
return
}
defer sdl.Quit()
window, err := sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, winWidth, winHeight, sdl.WINDOW_SHOWN)
if err != nil {
fmt.Println("Failed to create window:", err)
return
}
defer window.Destroy()
paintImage(img, window, 0, 0)
// Event loop
for running {
for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
switch event.(type) {
case *sdl.QuitEvent:
running = false
break
}
}
sdl.Delay(16) // ~60 FPS
x := rand.Intn(600)
y := rand.Intn(400)
paintImage(img, window, x, y)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment