123 lines
2.4 KiB
Go
123 lines
2.4 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"math/rand"
|
||
|
"os"
|
||
|
"sync"
|
||
|
|
||
|
"github.com/veandco/go-sdl2/sdl"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
WindowTitle = "Go-SDL2 Render"
|
||
|
WindowWidth = 800
|
||
|
WindowHeight = 600
|
||
|
FrameRate = 60
|
||
|
|
||
|
RectWidth = 20
|
||
|
RectHeight = 20
|
||
|
NumRects = WindowHeight / RectHeight
|
||
|
)
|
||
|
|
||
|
var rects [NumRects]sdl.Rect
|
||
|
var runningMutex sync.Mutex
|
||
|
|
||
|
func run() int {
|
||
|
var window *sdl.Window
|
||
|
var renderer *sdl.Renderer
|
||
|
var err error
|
||
|
|
||
|
sdl.Do(func() {
|
||
|
window, err = sdl.CreateWindow(WindowTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, WindowWidth, WindowHeight, sdl.WINDOW_OPENGL)
|
||
|
})
|
||
|
if err != nil {
|
||
|
fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err)
|
||
|
return 1
|
||
|
}
|
||
|
defer func() {
|
||
|
sdl.Do(func() {
|
||
|
window.Destroy()
|
||
|
})
|
||
|
}()
|
||
|
|
||
|
sdl.Do(func() {
|
||
|
renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED)
|
||
|
})
|
||
|
if err != nil {
|
||
|
fmt.Fprint(os.Stderr, "Failed to create renderer: %s\n", err)
|
||
|
return 2
|
||
|
}
|
||
|
defer func() {
|
||
|
sdl.Do(func() {
|
||
|
renderer.Destroy()
|
||
|
})
|
||
|
}()
|
||
|
|
||
|
sdl.Do(func() {
|
||
|
renderer.Clear()
|
||
|
})
|
||
|
|
||
|
for i := range rects {
|
||
|
rects[i] = sdl.Rect{
|
||
|
X: int32(rand.Int() % WindowWidth),
|
||
|
Y: int32(i * WindowHeight / len(rects)),
|
||
|
W: RectWidth,
|
||
|
H: RectHeight,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
running := true
|
||
|
for running {
|
||
|
sdl.Do(func() {
|
||
|
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
|
||
|
switch event.(type) {
|
||
|
case *sdl.QuitEvent:
|
||
|
runningMutex.Lock()
|
||
|
running = false
|
||
|
runningMutex.Unlock()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
renderer.Clear()
|
||
|
renderer.SetDrawColor(0, 0, 0, 0x20)
|
||
|
renderer.FillRect(&sdl.Rect{0, 0, WindowWidth, WindowHeight})
|
||
|
})
|
||
|
|
||
|
// Do expensive stuff using goroutines
|
||
|
wg := sync.WaitGroup{}
|
||
|
for i := range rects {
|
||
|
wg.Add(1)
|
||
|
go func(i int) {
|
||
|
rects[i].X = (rects[i].X + 10) % WindowWidth
|
||
|
sdl.Do(func() {
|
||
|
renderer.SetDrawColor(0xff, 0xff, 0xff, 0xff)
|
||
|
renderer.DrawRect(&rects[i])
|
||
|
})
|
||
|
wg.Done()
|
||
|
}(i)
|
||
|
}
|
||
|
wg.Wait()
|
||
|
|
||
|
sdl.Do(func() {
|
||
|
renderer.Present()
|
||
|
sdl.Delay(1000 / FrameRate)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
// os.Exit(..) must run AFTER sdl.Main(..) below; so keep track of exit
|
||
|
// status manually outside the closure passed into sdl.Main(..) below
|
||
|
var exitcode int
|
||
|
sdl.Main(func() {
|
||
|
exitcode = run()
|
||
|
})
|
||
|
// os.Exit(..) must run here! If run in sdl.Main(..) above, it will cause
|
||
|
// premature quitting of sdl.Main(..) function; resource cleaning deferred
|
||
|
// calls/closing of channels may never run
|
||
|
os.Exit(exitcode)
|
||
|
}
|