faiface / pixel

A hand-crafted 2D game library in Go
MIT License
4.46k stars 245 forks source link

Multiple windows bug: sprite on one window deletes shapes on other window #314

Open mlange-42 opened 1 year ago

mlange-42 commented 1 year ago

When using multiple windows, I get glitches when using imdraw shapes on one window and a sprite on another one. Below is some code that reproduces the issue: Window W1 only briefly shows the drawn white rectangle. Almost instantly, or after a short while, it disappears. When commenting out the line that draws the sprite, everything workd fine.

OS: Windows 10

Minimal reproducing example:

package main

import (
    "image/color"

    "github.com/faiface/pixel"
    "github.com/faiface/pixel/imdraw"
    "github.com/faiface/pixel/pixelgl"
    "golang.org/x/image/colornames"
)

func main() {
    pixelgl.Run(run)
}

func run() {
    w1 := createWindow("W1")
    w2 := createWindow("W2")

    draw := *imdraw.New(nil)

    for !w1.Closed() && !w2.Closed() {
        // Draw shapes on window 1
        w1.Clear(colornames.Black)
        draw.Color = colornames.White
        draw.Push(pixel.V(10, 10), pixel.V(700, 500))
        draw.Rectangle(0)
        draw.Draw(w1)
        draw.Reset()
        draw.Clear()
        w1.Update()

        // Draw a sprite on window 2
        w2.Clear(colornames.Black)
        picture := pixel.MakePictureData(pixel.R(0, 0, 100, 100))
        for i := 0; i < len(picture.Pix); i++ {
            picture.Pix[i] = color.RGBA{R: 255, G: 255, B: 255, A: 200}
        }
        sprite := pixel.NewSprite(picture, picture.Bounds())
        // This call seems to be the problem
        sprite.Draw(w2, pixel.IM)
        w2.Update()
    }
}

func createWindow(title string) *pixelgl.Window {
    cfg := pixelgl.WindowConfig{
        Title:  title,
        Bounds: pixel.R(0, 0, 800, 600),
    }

    window, err := pixelgl.NewWindow(cfg)
    if err != nil {
        panic(err)
    }
    return window
}
mlange-42 commented 1 year ago

Looks like a workaround is to update both/all windows at the end of the loop, instead of draw1 -> update1, draw2 -> update2, ...