Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

:copy-pixels t flickers between 2 canvases with incorrect backgrounds #75

Open
swapneils opened this issue May 20, 2023 · 6 comments
Open
Labels

Comments

@swapneils
Copy link

When running the brownian example, the canvas was flickering wildly between 2 separate colors and the line was dotted instead of continuous.

Editing the "background" value in the setup method and adding (sleep 0.5) to the end of the defsketch showed that one color was always black, while the other took the provided color's rgb values and turned them up to 255 (i.e. (rgb 20 0 1) would make a vivid purple background equivalent to (rgb 255 0 255)). The foreground pen was alternating between these two canvases, resulting in each one having a different set of dotted lines which together would make the actual brownian path.

Incidentally, I also noticed that execution of multiple simultaneous instances seemed to be single-threaded. Even if the make-instance calls were enclosed in bt:make-thread, the rendering would sleep for the specified time and then choose one of them to update, rather than updating both at the specified rate independently of each other. I'm uncertain if this is a separate issue, or indicative of an erroneous setup causing the above problem.

Reproduced with MSYS, Git Bash over MINGW, and Windows Powershell on Windows. libffi-6.dll copied from a working Coq installation, SDL installed as specified in the README.

Code for the above, with colors and the (sleep 0.5) being the only differences from the original brownian example sketch (I ran this in the REPL, but to my knowledge it should work as a .lisp file too):

(in-package :sketch-examples)
(defsketch brownian
    ((title "Brownian")
     (copy-pixels t)
     (pos (cons (/ width 2) (/ height 2))) (dir '(1 . 0))
     (pen (make-pen :stroke (rgb 255 255 255) :fill (gray 0.5) :weight 1))
     (line-length 3)
     (points (make-array 256 :initial-element (cons 400 300)))
     (points-pointer 0))
  (flet ((draw (paces)
	   (dotimes (i paces)
	     (let ((new-pos (cons (+ (car pos) (car dir))
				  (+ (cdr pos) (cdr dir)))))
	       (with-pen pen
		 (line (car pos) (cdr pos) (car new-pos) (cdr new-pos)))
	       (setf pos new-pos))))
	 (rotate (a)
	   (let ((a (+ a (degrees (atan (cdr dir) (car dir))))))
	     (setf dir (cons (cos (radians a))
			     (sin (radians a)))))))
    (rotate (- (random 180) 90))
    (draw (+ (random line-length) line-length))
    (setf (car pos) (alexandria:clamp (car pos) -10 810)
	  (cdr pos) (alexandria:clamp (cdr pos) -10 610))
(sleep 0.5)))

(defmethod setup ((instance brownian) &key &allow-other-keys)
  (background (rgb 20 0 5)))

(make-instance 'brownian :width 600 :w 600)
(make-instance 'brownian :width 600 :w 600)
@aykaramba
Copy link

aykaramba commented Sep 11, 2023

How do we get bots banned here? If the post above is our future, dear lord it is going to be horrific.

@aykaramba
Copy link

to the OP, I have not seen that issue at all. I was playing with the brownian example and testing it out and it draws exactly as it is supposed to. I increased the weight of the stroke to see what is going on and it is as expected. I am running Linux so I assume that the issue is:

  1. It is either Windows

  2. Or it is the last statement in your copy / paste:

(make-instance 'brownian :width 600 :w 600)
(make-instance 'brownian :width 600 :w 600)

That starts up two copies of brownian and what you might be seeing is two windows overlapping and some weirdness with how things are rendered under that scenario. In fact, you should have those two lines there.

Your brownian example should look like this: https://github.com/vydd/sketch/blob/master/examples/brownian.lisp

@iamFIREcracker
Copy link
Contributor

iamFIREcracker commented Oct 31, 2023

I am running into the exact same issue described by @swapneils; I don't even need the double call to MAKE-INSTANCE: one is enough to make it flicker.

Here is another minimal repro example (tested on a M2 Mac): run the below command, and you should get a window alternating between a full-black canvas (???), and one with white background and random circles drawn on it:

(defsketch bug
    ((copy-pixels t)
     (pen (make-pen :fill +black+)))
  (with-pen pen
    (circle (random width) (random height) (random 10)))
  (sleep 0.5))

(defmethod setup ((instance bug) &key &allow-other-keys)
  (background +white+))

(make-instance 'bug)

Does anyone have any clue where that second canvas might be coming from? I am just getting started with Sketch, but if there is anything else I should do to aid the investigation, please let me know.

@aykaramba
Copy link

Just to help you with the debugging process, I just updated everything, ran sketch and your code and there is no flicker on my machine. I am running an Intel i5 cpu + AMD video card with open source drivers on Debian Linux.

Not terribly helpful but it will help eliminate some variables. I don't have one of the new macs to test on.

@Gleefre
Copy link
Contributor

Gleefre commented Nov 1, 2023

This is most probably due to double buffering. As it was mentioned in #7, the proper fix would be implementing copy-pixels via rendering to FBOs.

@vydd vydd added the bug label Nov 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants
@iamFIREcracker @vydd @aykaramba @swapneils @Gleefre and others