# Fast, simple graphics?

**URL:** <https://discourse.julialang.org/t/fast-simple-graphics/84694>\
**Category:** Visualization\
**Created:** [July 24, 2022, 1:26am UTC](https://discourse.julialang.org/t/fast-simple-graphics/84694 "2022-07-24T01:26:36Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nathaniel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathaniel/32/37854_2.png) [@Nathaniel](https://discourse.julialang.org/u/Nathaniel)\
**Post date:** [July 24, 2022, 1:26am UTC](https://discourse.julialang.org/t/fast-simple-graphics/84694/1 "2022-07-24T01:26:36Z")

</div>

I’m running a simulation and would like to watch my agents moving around as the simulation runs. Currently, I’m using Plots, just running `plot(...)` in a loop. However, this is very slow - plotting each frame takes at least as much time as running the simulation for one frame.

So I’m looking for a faster option. I don’t need to make nice antialiased print-quality plots - I’m just looking to draw a few hundreds or thousands of simple 2D polygons to the screen as quickly as possible. It’s important that I can do this on the screen in a while loop while my simulation runs, rather than first making an animation and then displaying it.

I know that OpenGL is an option, and I’ll use that if I have to, but I’m hoping to avoid going quite that low level. Is there an existing package that would be an easier option?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [July 24, 2022, 1:39am UTC](https://discourse.julialang.org/t/fast-simple-graphics/84694/2 "2022-07-24T01:39:38Z")

</div>

> [@Nathaniel](#):
>
> I know that OpenGL is an option, and I’ll use that if I have to,

Makie.jl

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [July 24, 2022, 1:54am UTC](https://discourse.julialang.org/t/fast-simple-graphics/84694/3 "2022-07-24T01:54:11Z")

</div>

In particular, take a look at this page of the Makie documentation:

[https://makie.juliaplots.org/stable/documentation/nodes/index.html#observables\_interaction](https://makie.juliaplots.org/stable/documentation/nodes/index.html#observables_interaction)

---

<div class="post-metadata">

**Author:** ![Nathaniel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathaniel/32/37854_2.png) [@Nathaniel](https://discourse.julialang.org/u/Nathaniel)\
**Post date:** [July 24, 2022, 1:58am UTC](https://discourse.julialang.org/t/fast-simple-graphics/84694/4 "2022-07-24T01:58:27Z")

</div>

How does Makie fare speed-wise? I was aware of it but at first glance it seemed more geared towards publishable quality images than fast animation.

---

<div class="post-metadata">

**Author:** ![photor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/photor/32/14343_2.png) [@photor](https://discourse.julialang.org/u/photor)\
**Post date:** [July 24, 2022, 2:03am UTC](https://discourse.julialang.org/t/fast-simple-graphics/84694/5 "2022-07-24T02:03:57Z")

</div>

The GR backend is farely fast for such purposes.

---

<div class="post-metadata">

**Author:** ![Nathaniel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathaniel/32/37854_2.png) [@Nathaniel](https://discourse.julialang.org/u/Nathaniel)\
**Post date:** [July 24, 2022, 2:19am UTC](https://discourse.julialang.org/t/fast-simple-graphics/84694/7 "2022-07-24T02:19:33Z")

</div>

I guess that was meant to be GL backend? I’ll give it a try.

---

<div class="post-metadata">

**Author:** ![sjkelly](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sjkelly/32/9280_2.png) [@sjkelly](https://discourse.julialang.org/u/sjkelly)\
**Post date:** [July 24, 2022, 2:39am UTC](https://discourse.julialang.org/t/fast-simple-graphics/84694/8 "2022-07-24T02:39:31Z")

</div>

GLMakie is very fast. One of the reasons why the compile time is high, is due to aggressive use of Observables which allow for fast updates to the scene.

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [July 24, 2022, 3:18am UTC](https://discourse.julialang.org/t/fast-simple-graphics/84694/9 "2022-07-24T03:18:50Z")

</div>

Can you make your work compatible with [InteractiveDynamics](https://juliadynamics.github.io/InteractiveDynamics.jl/dev/)?

---

<div class="post-metadata">

**Author:** ![Nathaniel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathaniel/32/37854_2.png) [@Nathaniel](https://discourse.julialang.org/u/Nathaniel)\
**Post date:** [July 24, 2022, 3:40am UTC](https://discourse.julialang.org/t/fast-simple-graphics/84694/10 "2022-07-24T03:40:04Z")

</div>

I’m going to try GLMakie, but just in case, I’m really hoping for something with more of a graphics/drawing API rather than a plotting API. Ideally, on each frame I’d like to just clear the screen, draw a bunch of triangles and then swap the buffers. My code already keeps track of everything that needs to be drawn, so I’d be happiest with a package that just focuses on drawing and otherwise keeps out of the way. If there’s something that simple that exists, while also being fast, I’d be really happy to know about it.  
.

---

<div class="post-metadata">

**Author:** ![drvi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drvi/32/13236_2.png) [@drvi](https://discourse.julialang.org/u/drvi)\
**Post date:** [July 24, 2022, 4:46am UTC](https://discourse.julialang.org/t/fast-simple-graphics/84694/11 "2022-07-24T04:46:50Z")

</div>

You can try SDL2, there is Julia wrapper [GitHub - JuliaMultimedia/SimpleDirectMediaLayer.jl: SDL2](https://github.com/JuliaMultimedia/SimpleDirectMediaLayer.jl). Should be reasonably fast; in Julia I’ve only used it in very simple [example](https://github.com/Drvi/toy_dla) which builds and renders one big texture.

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [July 24, 2022, 7:57am UTC](https://discourse.julialang.org/t/fast-simple-graphics/84694/12 "2022-07-24T07:57:41Z")

</div>

> [@Nathaniel](#):
>
> Ideally, on each frame I’d like to just clear the screen, draw a bunch of triangles and then swap the buffers. My code already keeps track of everything that needs to be drawn, so I’d be happiest with a package that just focuses on drawing and otherwise keeps out of the way. If there’s something that simple that exists, while also being fast, I’d be really happy to know about it.

I am currently doing this using Luxor + MiniFB.  
I played around a bit and made some improvements for Luxor, which is currently a PR waiting to be accepted. Have a look at this example, there is a video if you scroll down. I think the code isn’t working anymore as given. What you see is 60 FPS, live rendering, not just creating the video. I recorded the video from the screen, so that it can be shown without installing my branch at this time:

> <https://github.com/JuliaGraphics/Luxor.jl/issues/235>
>
> This opens two windows which can be used as drawing canvas independently:
> \`\`\`
> …(@v1.7) pkg\> add https://github.com/oheil/Luxor.jl#multi\_drawing
> \`\`\`
> 
> \`\`\`
> using MiniFB, Luxor, Colors
> 
> WIDTH=800
> HEIGHT=600
> 
> mutable struct MfbState
> state::mfb\_update\_state
> mousePressed::Int	
> end
> 
> stateArray=\[
> MfbState( MiniFB.STATE\_OK, 0 ),
> MfbState( MiniFB.STATE\_OK, 0 ),
> \]
> 
> function windowUpdateTask(window,windowIndex,buffer,stateArray)
> stateArray\[windowIndex\].state=mfb\_update(window,buffer)
> while stateArray\[windowIndex\].state == MiniFB.STATE\_OK
> stateArray\[windowIndex\].state=mfb\_update(window,buffer)
> sleep(1.0/120.0)
> end
> println("\\nWindow closed\\n")
> end
> 
> window1 = mfb\_open\_ex("MiniFB", WIDTH, HEIGHT, MiniFB.WF\_RESIZABLE)
> buffer1 = zeros(ARGB32, WIDTH, HEIGHT)
> d1=Drawing(buffer1)
> @async windowUpdateTask(window1,1,buffer1,stateArray)
> 
> window2 = mfb\_open\_ex("MiniFB", WIDTH, HEIGHT, MiniFB.WF\_RESIZABLE)
> buffer2 = zeros(ARGB32, WIDTH, HEIGHT)
> Luxor.CURRENTDRAWINGINDEX\[1\]=2
> d2=Drawing(buffer2)
> @async windowUpdateTask(window2,2,buffer2,stateArray)
> 
> origin()
> setcolor("red")
> circle(0,0,150,:fill)
> 
> Luxor.CURRENTDRAWINGINDEX\[1\]=1
> origin()
> setcolor("green")
> circle(0,0,150,:fill)
> \`\`\`
> Just a proof of concept.
> Except for a ignorable error message from Cairo this works pretty well.

Here is working code with one window. It’s already in Luxor at [Interactive graphics and Threads · Luxor](https://juliagraphics.github.io/Luxor.jl/dev/howto/livegraphics/#Clock) if you scroll down a bit below the clock example. To stop the live graphics press “q” and “return”, not ctrl-c, as this can stop the window update @task by chance:

```julia
(@v1.7) pkg> add Luxor#master

```

```julia
using Colors
using Luxor
using MiniFB

const WIDTH = 800
const HEIGHT = 600

function window_update_task(window, buffer, showFPS=false)
	sb = buffer[1:105, 1:55]
    state = mfb_update(window, buffer)
	updateCount = 0
	startTime = floor(Int, time())
	fps = "0"
	while state == MiniFB.STATE_OK
		if showFPS
			elapsedTime = floor(Int, time()) - startTime
			if elapsedTime > 1
				fps = string(round(Int, updateCount/elapsedTime))
				startTime = floor(Int, time())
				updateCount = 0
			end
			sb .= buffer[1:105, 1:55]
			@layer begin
				(dx,dy) = Point(0.0, 0.0) - getworldposition(Point(0.0, 0.0); centered=false)
				setcolor((1.0, 0, 0, 0.5))
				fontsize(50)
				text(fps, Point(5+dx, 5+dy), halign=:left, valign=:top)
			end
		end
		state = mfb_update(window, buffer)
		if showFPS
			buffer[1:105, 1:55] .= sb
		end
        sleep(1.0/120.0)
		updateCount += 1
    end
	println("\nWindow closed\n")
end

buffer = zeros(ARGB32, WIDTH, HEIGHT)
d = Drawing(buffer)

window = mfb_open_ex("MiniFB", WIDTH, HEIGHT, MiniFB.WF_RESIZABLE)
@async window_update_task(window, buffer, true)

mutable struct Ball
    position::Point
    velocity::Point
end
function sticks(w, h)
    channel = Channel(10)
    #enter "q" and "return" to stop the while loop
    @async while true
        kb = readline(stdin)
        if contains(kb, "q")
            put!(channel, 1)
            break
        end
    end
	colors = [rand(1:255), rand(1:255), rand(1:255)]
	newcolors = [rand(1:255), rand(1:255), rand(1:255)]
	c = ARGB(colors[1]/255, colors[2]/255, colors[3]/255, 1.0)
	balls = [Ball( rand(BoundingBox(Point(-w/2, -h/2), Point(w/2, h/2))), rand(BoundingBox(Point(-10, -10), Point(10, 10))) ) for _ in 1:2] 
	while true
		background(0, 0, 0, 0.05)
		if colors == newcolors
			newcolors = [rand(1:255), rand(1:255), rand(1:255)]
		end
		for (index, (col, newcol)) in enumerate(zip(colors, newcolors))
			if col != newcol
				col > newcol ? col -= 1 : col += 1
				colors[index] = col
			end
		end
		c = ARGB(colors[1]/255, colors[2]/255, colors[3]/255, 1.0)
		for ball in balls
			if !(-w/2 < ball.position.x < w/2)
				ball.velocity = Point(-ball.velocity.x, ball.velocity.y)
			end
			if !(-h/2 < ball.position.y < h/2)
				ball.velocity = Point(ball.velocity.x, -ball.velocity.y)
			end
			ball.position = ball.position + ball.velocity
		end
		setcolor(c)
		line(balls[1].position, balls[2].position, :stroke)
		sleep(1.0/120.0)
        if isready(channel)
            break
        end
	end
end

origin()
sticks(WIDTH, HEIGHT)

```

So, what you want to do is currently work in progress on Luxor.

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [July 24, 2022, 8:05am UTC](https://discourse.julialang.org/t/fast-simple-graphics/84694/13 "2022-07-24T08:05:24Z")

</div>

Sorry, you need Luxor#master for my code example!

```julia
(@v1.7) pkg> add Luxor#master

```

---

<div class="post-metadata">

**Author:** ![TheLateKronos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thelatekronos/32/12824_2.png) [@TheLateKronos](https://discourse.julialang.org/u/TheLateKronos)\
**Post date:** [July 24, 2022, 8:09am UTC](https://discourse.julialang.org/t/fast-simple-graphics/84694/14 "2022-07-24T08:09:47Z")

</div>

Could UnicodePlots.jl be sufficient for your usecase?
