GLMakie
GLMakie is the native, desktop-based backend, and is the most feature-complete. It requires an OpenGL enabled graphics card with OpenGL version 3.3 or higher.
Activation and screen config
Activate the backend by calling GLMakie.activate!()
:
GLMakie.activate!(; screen_config...)
Sets GLMakie as the currently active backend and also optionally modifies the screen configuration using screen_config
keyword arguments. Note that the screen_config
can also be set permanently via Makie.set_theme!(GLMakie=(screen_config...,))
.
Arguments one can pass via screen_config
:
Renderloop
renderloop = GLMakie.renderloop
: Sets a functionrenderloop(::GLMakie.Screen)
which starts a renderloop for the screen.
Warning
The keyword arguments below are not effective if renderloop
isn't set to GLMakie.renderloop
, unless implemented in a custom renderloop function:
pause_renderloop = false
: Iftrue
, creates a screen with a paused renderloop. The renderloop can be started withGLMakie.start_renderloop!(screen)
and paused again withGLMakie.pause_renderloop!(screen)
.vsync = false
: Whether to enable vsync for the window.render_on_demand = true
: Iftrue
, the scene will only be rendered if something has changed in it.framerate = 30.0
: Sets the currently rendered frames per second.px_per_unit = automatic
: Sets the ratio between the number of rendered pixels and theMakie
resolution. It defaults to the value ofscalefactor
but may be any positive real number.
GLFW window attributes
float = false
: Whether the window should float above other windows.focus_on_show = false
: Iftrue
, focuses the window when newly opened.decorated = true
: Whether or not to show window decorations.title::String = "Makie"
: Sets the window title.fullscreen = false
: Whether to start the window in fullscreen mode.debugging = false
: Iftrue
, starts the GLFW.Window/OpenGL context with debug output.monitor::Union{Nothing, GLFW.Monitor} = nothing
: Sets the monitor on which the window should be opened. If set tonothing
, GLFW will decide which monitor to use.visible = true
: Whether or not the window should be visible when first created.scalefactor = automatic
: Sets the window scaling factor, such as2.0
on HiDPI/Retina displays. It is set automatically based on the display, but may be any positive real number.
Rendering constants & Postprocessor
oit = false
: Whether to enable order independent transparency for the window.fxaa = true
: Whether to enable fxaa (anti-aliasing) for the window.ssao = true
: Whether to enable screen space ambient occlusion, which simulates natural shadowing at inner edges and crevices.transparency_weight_scale = 1000f0
: Adjusts a factor in the rendering shaders for order independent transparency. This should be the same for all of them (within one rendering pipeline) otherwise depth "order" will be broken.max_lights = 64
: The maximum number of lights withshading = MultiLightShading
max_light_parameters = 5 * N_lights
: The maximum number of light parameters that can be uploaded. These include everything other than the light color (i.e. position, direction, attenuation, angles) in terms of scalar floats.
Window Scaling
The sizes of figures are given in display-independent "logical" dimensions, and the GLMakie backend will scale the size of the displayed window on HiDPI/Retina displays automatically. For example, the default size = (800, 600)
will be shown in a 1600 × 1200 window on a HiDPI display which is configured with a 200% scaling factor.
The scaling factor may be overridden by displaying the figure with a different scalefactor
value:
fig = Figure(size = (800, 600))
# ...
display(fig, scalefactor = 1.5)
If the scale factor is not changed from its default automatic configuration, the window will be resized to maintain its apparent size when moved across displays with different scaling factors on Windows and OSX. (Independent scaling factors are not supported by X11, and at this time the underlying GLFW library is not compiled with Wayland support.)
Resolution Scaling
Related to the window scaling factor, the mapping from figure sizes and positions to pixels can be scaled to achieve HiDPI/Retina resolution renderings. The resolution scaling defaults to the same factor as the window scaling, but it may be independently overridden with the px_per_unit
argument when showing a figure:
fig = Figure(size = (800, 600))
# ...
display(fig, px_per_unit = 2)
The resolution scale factor may also be changed when saving pngs:
save("hires.png", fig, px_per_unit = 2) # 1600 × 1200 px png
save("lores.png", fig, px_per_unit = 0.5) # 400 × 300 px png
If a script may run in interactive environments where the native screen DPI can vary, you may want to explicitly set px_per_unit = 1
when saving figures to ensure consistency of results.
Multiple Windows
GLMakie has experimental support for displaying multiple independent figures (or scenes). To open a new window, use display(GLMakie.Screen(), figure_or_scene)
. To close all windows, use GLMakie.closeall()
.
Embedding
There's experimental support for embedding GLMakie by creating a custom 'window' type (analagous to the GLFW OS-level window) and grabbing GLMakie's framebuffers to display in your own GUI. Here's a high-level overview of what you'd need to do:
Create a
MyWindow
type, which might represent a widget in your chosen GUI framework. Pass an instance of this type toGLMakie.Screen(; window=my_window, start_renderloop=false)
to get aScreen{MyWindow}
object without the renderloop running in the background (optional, depends on your application). This is the main object you'll need to work with.Define method specializations for the
MyWindow
type. Here's a non-exhaustive list:
Base.isopen(::MyWindow)
ShaderAbstractions.native_switch_context!(::MyWindow)
(switch to the OpenGL context of the window)ShaderAbstractions.native_context_alive(::MyWindow)
(check if the window OpenGL context is still valid)GLMakie.framebuffer_size(::MyWindow)
(get the size of the windows framebuffer)GLMakie.connect_screen(::Scene, Screen{MyWindow})
(connect input signals for e.g. the keyboard and mouse; you may want to implement the individual connection methods instead).
The actual implementation of all these depends entirely on how you want to embed GLMakie.
A
Figure
can now be displayed in the new screen by callingdisplay(screen, f)
. If you're not using GLMakie's own renderloop you'll need to take care of callingGLMakie.render_frame(screen)
whenever necessary (you can useGLMakie.requires_update(screen)
).display(screen, f)
will only draw the figure to a framebuffer. You can get the color texture attachement of the framebuffer withscreen.framebuffer.buffers[:color]
, and display that color texture as an image in your chosen GUI framework.If interactivity is desired, you will need to pass input events from the keyboard and mouse to the events in
Makie.get_scene(f).events
(The Events struct).
Forcing Dedicated GPU Use In Linux
Normally the dedicated GPU is used for rendering. If instead an integrated GPU is used, one can tell Julia to use the dedicated GPU while launching julia as $ sudo DRI_PRIME=1 julia
in the bash terminal. To have it permanently used, add the line export DRI_PRIME=1
in your .bashrc
or .zshrc
file.
Troubleshooting OpenGL
If you get any error loading GLMakie, it likely means you don't have an OpenGL capable graphics card, or you don't have an OpenGL 3.3 capable driver installed. Note that most GPUs, even 8 year old integrated ones, support OpenGL 3.3.
On Linux, you can find out your OpenGL version with: glxinfo | grep "OpenGL version"
If you're using an AMD or Intel gpu on linux, you may run into GLFW#198.
If you're on a headless server, you still need to install x-server and proper graphics drivers.
You can find a demo on how to set that up in this nextjournal article.
GLMakie's CI has no GPU, so you can also look at .github/workflows/glmakie.yaml for a working setup.
If none of these work for you, take a look at the other backends, which all work without a GPU.
If you get an error pointing to GLFW.jl, please look into the existing GLFW issues, and also google for those errors. This is then very likely something that needs fixing in the glfw c library or in the GPU drivers.
Warning
GLMakie is not thread-safe! Makie functions to display in GLMakie or updates to Observable
displayed in GLMakie windows from other threads may not work as expected or cause a segmentation fault.
WSL setup or X-forwarding
From: Microsoft/WSL/issues/2855
WSL runs OpenGL alright, but it is not a supported scenario. From a clean Ubuntu install from the store do:
sudo apt install ubuntu-desktop mesa-utils
export DISPLAY=localhost:0
glxgears
On the Windows side:
install VcXsrv
choose multiple windows -> display 0 -> start no client -> disable native opengl
Troubleshooting:
1.) install: sudo apt-get install -y xorg-dev mesa-utils xvfb libgl1 freeglut3-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxext-dev
2.) WSL has some problems with passing through localhost, so one may need to use: export DISPLAY=192.168.178.31:0
, with the local ip of the pcs network adapter, which runs VcXsrv
3.) One may need mv /opt/julia-1.5.2/lib/julia/libstdc++.so.6 /opt/julia-1.5.2/lib/julia/libcpp.backup
, another form of GLFW#198
GLMakie does not show Figure or crashes on full screen mode on macOS
MacOS gives a warning if a graphical user interface (GUI) is not started from an AppBundle and this exception can crash the Julia process that initiated the GUI. This warning only occurs if macOS Settings->Desktop & Dock->Menu Bar->Automatically hide and show the menu bar is not set to Never. Therefore make sure this setting is set to Never
to enable the use of GLMakie on macOS.