An openFrameworks addon for controlling multiple lasers.
README

ofxLaser
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).
---
Need a full show application?
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
Safety Notice
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.
Current status
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
Summary
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.
ofxLaser features
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 LinuxUsage
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().
Drawing to the laser
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_DETAILUse 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
Drawing methods
drawLine(start, end, colour, profile);
Draws a line to the laser(s). returns : void## parameters :
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)drawLine( x1, y1, x2, y2, colour, profile);
As above but with separate float values for the start and end coordinates of the line.drawDot(position, colour, intensity, profile);
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.## parameters :
- 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)
drawDot( x, y, colour, intensity, profile);
As above but with separate x and y values instead of a point object.drawCircle(position, radius, colour, profile);
Draws a circle.## parameters :
- 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)
drawCircle(x, y, radius, colour, profile);
As above but with separate x and y float values.drawPoly(polyline, colour, profile);
Draws an ofPolyline to the laser## parameters :
- 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)
Laser Graphic object
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.drawLaserGraphic(graphic, brightness, profile);
Draws an ofxLaser::Graphic## parameters :
- 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)
Supported Laser controllers
USB : HeliosDAC LaserCube USBNetwork : Ether Dream LaserCube (WiFi) IDN (ILDA Digital Network) AVB (Audio Video Bridging)
Licence
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.coInstallation
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/If you already cloned without submodules, run:
git clone --recurse-submodules https://github.com/sebleedelisle/ofxLaser.git
cd openFrameworks/addons/ofxLaserThe repo depends on the
git submodule update --init --recursive
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.
Dependencies
addons : ofxGui (comes with oF) ofxSvg (comes with oF)Open source libraries (included in source) : libera-laser (git submodule) clipper libusb
Example build check
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.Compatibility
openFrameworks 0.12.x
ofxAddons