canvas icon indicating copy to clipboard operation
canvas copied to clipboard

Flickering when using glfwcanvas

Open deluan opened this issue 6 years ago • 3 comments

Hi there, thanks for your awesome library! It is refreshingly easy to use!

I'm trying to use it to render a sequence of images in a glfwcanvas, but when I update the image with a new one, it keeps switching between the new and the old image. Here's a snippet of my code:

	win, cv, err := glfwcanvas.CreateWindow(defaultWidth, defaultHeight, windowTitle)
	if err != nil {
		panic(err)
	}
        var lastRefresh int64
	win.MainLoop(func() {
                // This call returns a new image and the last timestamp it was updated
		img, lastUpdate := client.Screen()

		imgWidth := img.Bounds().Max.X
		imgHeight := img.Bounds().Max.Y

		// If the image is empty, terminate loop
		if imgWidth == 0 || imgHeight == 0 {
			return
		}

		// If there were no changes, terminate loop
		if lastRefresh == lastUpdate {
			return
		}

		// Process screen updates
		cv.PutImageData(img.(*image.RGBA), 0, 0)
		lastRefresh = lastUpdate
	})

I tried to use cv.DrawImage() but then it does not show anything. What am I doing wrong?

deluan avatar Oct 03 '19 03:10 deluan

Hi! Thanks for the nice comments!

I don't see anything wrong with the code, and cv.DrawImage should also work. I tried writing a test function for client.Screen to test it out, but it seems to work fine for me. Can you try this and see if that works? If not, it may be an OpenGL or driver issue maybe...

package main

import (
	"image"
	"image/color"
	"math/rand"
	"time"

	"github.com/tfriedel6/canvas/glfwcanvas"
)

var (
	first = true
	bla   = time.Now()
	limg  *image.RGBA
)

func clientScreen() (image.Image, int64) {
	if !first && rand.Float64() < 0.99 {
		return limg, bla.UnixNano()
	}
	first = false
	rgba := image.NewRGBA(image.Rect(0, 0, 800, 800))
	for y := 0; y < 800; y++ {
		for x := 0; x < 800; x++ {
			rgba.Set(x, y, color.RGBA{
				R: byte(rand.Intn(256)),
				G: byte(rand.Intn(256)),
				B: byte(rand.Intn(256)),
				A: 255,
			})
		}
	}
	bla = time.Now()
	limg = rgba
	return rgba, bla.UnixNano()
}

func main() {
	win, cv, err := glfwcanvas.CreateWindow(800, 800, "hello")
	if err != nil {
		panic(err)
	}
	var lastRefresh int64
	win.MainLoop(func() {
		// This call returns a new image and the last timestamp it was updated
		img, lastUpdate := clientScreen()

		imgWidth := img.Bounds().Max.X
		imgHeight := img.Bounds().Max.Y

		// If the image is empty, terminate loop
		if imgWidth == 0 || imgHeight == 0 {
			return
		}

		// If there were no changes, terminate loop
		if lastRefresh == lastUpdate {
			return
		}

		// Process screen updates
		// cv.PutImageData(img.(*image.RGBA), 0, 0)
		cv.DrawImage(img, 0, 0)
		lastRefresh = lastUpdate
	})
}

tfriedel6 avatar Oct 03 '19 08:10 tfriedel6

This is definitely an issue with OpenGL, as it works flawless with SDL. I tried my code with SDL and it worked. I also tried your code and it still flicks (and scales down the image, weird), but when I try it with SDL it also works perfectly.

I think it is worth to note that OpenGL is working in my machine. I'm actually trying to port my code from using Pixel to your library, and with Pixel it works ok.

My system is macOS Mojave, I don't have an easy way to test this in other systems, but I'm willing to help in anyway I can to make this work, as I rather not have to install extra dependencies (SDL2) for my code to work.

deluan avatar Oct 03 '19 14:10 deluan

This will be difficult for me to test, as I don't have a Mac available to test on. I do have a VM running macOS, but it is an old version and I can't even install the latest Xcode on it. I tried running the GLFW example on that, but it just crashes immediately (SDL works though).

One thing worth trying might be to get it running on the latest versions GLFW. In case you want to do this you could just copy the glfwcanvas package into a package of your own and use that, then go get the latest github.com/go-gl/glfw version. If that helps, let me know and I will update the dependency here. If not, you can try the 3.3-beta branch (run go get github.com/go-gl/[email protected]) and see if you can get it to run with GLFW 3.3.

tfriedel6 avatar Oct 04 '19 12:10 tfriedel6