ofxLaser is a core library for sending laser frames to supported laser controllers (DACs) (Ether Dream, Helios, LaserCube, AVB, etc).
It's built on libera-laser which provides all the low level discovery, communication, and frame queuing functionality, while ofxLaser adds an openFrameworks wrapper, along with complex point stream generation, colour correction and zone handling.
This library is intended for developers, educators, and hobbyists who want to experiment with laser control in openFrameworks.
It is licensed for non-commercial use only (see LICENSE).
If you want a standalone application for designing and running laser shows, take a look at Liberation.
Liberation is built on the same foundation as ofxLaser and adds:
- A 3D visualiser and editing tools
- Node-based tools for creating laser graphics and beam effects
- Clip deck, timeline, and FX systems
- MIDI/DMX/Art-Net integration
- PONK support, so you can send paths to it via ofxPonk, or from TouchDesigner or MadLaser
ofxLaser remains the lower-level openFrameworks toolkit, while Liberation is the application built on top of the same backend.
LASERS ARE DANGEROUS - USE THIS SOFTWARE AT YOUR OWN RISK. NEVER LOOK INTO THE BEAM. Always have an emergency stop button at hand and do not let anyone enter the laser exposure area. Check the exposure area for reflective surfaces. Take laser safety training and get licenced to use high power lasers in your location. In the UK I can recommend this one.
Seriously, don't mess around with this stuff. You can really damage your eyes / burn your house down.
The current main branch includes the libera-based refactor:
- Pure ofxGui interface (ImGui dependency removed)
- Poco dependency removed
- DAC communication handled by libera-laser backend
- All lasers, zones and masks are set up within the app's UI and saved to config files
- Automatic discovery of laser controllers (DACs)
- Much simpler set up in code, see examples
The system is primarily designed to render graphics to one or more lasers. Conceptually we have an input canvas, and we draw everything into that. Within the canvas we can define one or more input zones that can be assigned to one or more lasers. The output for the zones can be adjusted for size and perspective.
- Can draw any vector shape to lasers with simple function calls
- Shapes are sorted to find the optimal path for the laser
- Automatic laser controller detection (using libera)
- Masking system to provide blank areas within the laser output
- Many calibration options for blanking - colour change shift, pre/post blanks, pre/post on points
- Specify laser speed and acceleration for each shape using "render profiles"
- Output zone transformation for projection mapping and to compensate for perspective distortion
- Multiple zones can be sent to multiple projectors and individually warped for mapping onto separate planes
- Colour calibration system to compensate for laser power to brightness curves
- Shapes take into account the current transformation matrix, so works with ofTransform, ofRotate, and ofScale
- Works with 3D co-ordinates and shapes
- Cross platform - developed on OSX, but also tested on Windows and Linux
All API calls are via the ofxLaser::Manager object. Declare one in ofApp.h and it will be automatically initialised.
ofxLaser::Manager::update() - update and prepare the system to receive new laser graphics - call this in ofApp::update()
In ofApp::draw() you call all your ofxLaser draw methods (see below). Once you're finished call ofxLaser::Manager::send() to send everything to the laser(s).
ofxLaser::Manager::send() - send everything drawn this time to the lasers ofxLaser::Manager::drawUI() - draw the laser UI system
Note that all drawing methods must be called after update() and before send().
We have three render profiles for each laser, default, fast and detailed, referenced using the following compiler definitions: OFXLASER_PROFILE_DEFAULT OFXLASER_PROFILE_FAST OFXLASER_PROFILE_DETAIL
Use the default profile for most things, use fast for any smooth lines where accuracy doesn't matter, and detail for anything intricate. Bear in mind that the output will get flickery the more detailed you get.
These three profiles can be edited within the app's GUI, and can be defined differently for each laser. You can also save and load scanner presets.
**NB you can use ofTranslate, ofScale and any of the built-in transformations with all of the draw methods **
Draws a line to the laser(s). returns : void
- start : glm::vec2, glm::vec3 or ofPoint - the start position of the line
- end : glm::vec2, glm::vec3 or ofPoint - the end position of the line
- colour : ofColor the colour of the line
- profile : (optional) the render profile, use one of the profile definitions (defaults to the default profile)
As above but with separate float values for the start and end coordinates of the line.
Draws a dot to the laser(s). This can also be used to make beam effects. Use the intensity to change the brightness - this changes how long the laser lingers to make the point so is more efficient than darkening the colour.
- position : glm::vec2, glm::vec3 or ofPoint - the position of the dot
- colour : ofColor the colour of the dot
- intensity : (optional) float a unit value (0-1) defining the brightness of the dot.
- profile : (optional) the render profile, use one of the profile defintions (defaults to the default profile)
As above but with separate x and y values instead of a point object.
Draws a circle.
- position : glm::vec2, glm::vec3 or ofPoint - the position of the circle
- radius : float radius of the circle
- colour : ofColor the colour of the circle
- profile : (optional) the render profile, use one of the profile defintions (defaults to the default profile)
As above but with separate x and y float values.
Draws an ofPolyline to the laser
- polyline : ofPolyline& - the polyline to draw
- colour : ofColor the colour of the polyline
- profile : (optional) the render profile, use one of the profile defintions (defaults to the default profile)
The ofxLaser::Graphic class can be used to store multiple polylines and can also handle shape occlusion. It can also be used to load and render SVGs. To send the graphic to the laser use the drawLaserGraphic function.
Draws an ofxLaser::Graphic
- graphic : ofxLaser::Graphic& - the Graphic to draw
- brightness : float a unit value (0-1) to specify brightness
- profile : (optional) the render profile, use one of the profile defintions (defaults to the default profile)
USB :
- HeliosDAC
- LaserCube USB
Network :
- Ether Dream
- LaserCube (WiFi)
- IDN (ILDA Digital Network)
- AVB (Audio Video Bridging)
This project is licensed under the ofxLaser License (Non-Commercial Share-Alike). It may be used and modified for non-commercial purposes only. Commercial use requires a separate licence - contact [seb at seblee.co]. See the LICENSE file for details. Copyright (c) 2012-2026 Seb Lee-Delisle seblee.me seblee.co
The main branch targets openFrameworks 0.12.x.
Once you have downloaded the openFrameworks source code, add the ofxLaser folder to the addons folder. Clone the source code with submodules:
> cd openFrameworks/addons/
> git clone --recurse-submodules https://github.com/sebleedelisle/ofxLaser.git
If you already cloned without submodules, run:
> cd openFrameworks/addons/ofxLaser
> git submodule update --init --recursive
The repo depends on the libs/libera-laser submodule, so a plain git clone is not enough.
Downloading the GitHub ZIP is not recommended because it will not fetch submodule contents automatically.
To run the examples, import them into the project generator, create a new project, and open the project file in your IDE.
addons :
ofxGui (comes with oF)
ofxSvg (comes with oF)
Open source libraries (included in source) : libera-laser (git submodule) clipper libusb
To compile every example without relying on checked-in project files, run:
./scripts/build-examples.shThe script builds openFrameworks once in Release, generates temporary
makefile-based wrappers for each example_* folder, and then compiles each
example in turn.
openFrameworks 0.12.x
