Skip to content

Instantly share code, notes, and snippets.

@adenine
Created December 5, 2025 11:17
Show Gist options
  • Select an option

  • Save adenine/56b25067608cd61a085f7d66212bf5a4 to your computer and use it in GitHub Desktop.

Select an option

Save adenine/56b25067608cd61a085f7d66212bf5a4 to your computer and use it in GitHub Desktop.
MQTT_VJ_ProjectionMap
/**
* This is a simple example of how to use the Keystone library.
*
* To use this example in the real world, you need a projector
* and a surface you want to project your Processing sketch onto.
*
* Simply drag the corners of the CornerPinSurface so that they
* match the physical surface's corners. The result will be an
* undistorted projection, regardless of projector position or
* orientation.
*
* You can also create more than one Surface object, and project
* onto multiple flat surfaces using a single projector.
*
* This extra flexbility can comes at the sacrifice of more or
* less pixel resolution, depending on your projector and how
* many surfaces you want to map.
*/
import deadpixel.keystone.*;
import mqtt.*;
MQTTClient client;
String incomingData;
Keystone ks; // the Keystone object
CornerPinSurface surfaceOne; // our first surface
CornerPinSurface surfaceTwo; // the second surface
PGraphics offscreenOne; // offscreen buffer one
PGraphics offscreenTwo; // offscreen buffer two
// this is just for having something on the surfaces
int x = 0;
int y = 150;
int size = 20;
void setup() {
client = new MQTTClient(this);
client.connect("mqtt://10.35.30.35:1883");
// Keystone will only work with P3D or OPENGL renderers,
// since it relies on texture mapping to deform
size(800, 600, P3D);
ks = new Keystone(this); // init the Keystone library
surfaceOne = ks.createCornerPinSurface(400, 300, 20); // create the first surface
surfaceTwo = ks.createCornerPinSurface(400, 300, 20); // and the second
// We need an offscreen buffer to draw the surface we
// want projected
// note that we're matching the resolution of the
// CornerPinSurface.
// (The offscreen buffer can be P2D or P3D)
offscreenOne = createGraphics(400, 300, P3D);
offscreenTwo = createGraphics(400, 300, P3D);
}
void draw() {
// Draw the scene, on offscreen buffer one
drawScreen1();
// Draw the scene, on offscreen buffer two
drawScreen2();
// most likely, you'll want a black background to minimize
// bleeding around your projection area
background(0);
// render the scene, transformed using the corner pin surface
surfaceOne.render(offscreenOne);
surfaceTwo.render(offscreenTwo);
// this is just for having the ellipse wander over the surfaces
x++;
if (x >= 800) {
x = 0;
}
}
void drawScreen1() {
offscreenOne.beginDraw();
offscreenOne.background(255);
offscreenOne.fill(0, 255, 0);
offscreenOne.ellipse(x, y, size, size);
offscreenOne.endDraw();
}
void drawScreen2() {
offscreenTwo.beginDraw();
offscreenTwo.background(255);
offscreenTwo.fill(0, 255, 0);
offscreenTwo.ellipse(x - 400, y, size, size);
offscreenTwo.endDraw();
}
void drawMQTTEvent() {
size = round(20+random(300));
}
void keyPressed() {
switch(key) {
case 'c':
// enter/leave calibration mode, where surfaces can be warped
// and moved
ks.toggleCalibration();
break;
case 'l':
// loads the saved layout
ks.load();
break;
case 's':
// saves the layout
ks.save();
break;
}
}
void clientConnected() {
println("client connected");
client.subscribe("#");
}
void messageReceived(String topic, byte[] payload) {
println("new message: " + topic + " - " + new String(payload));
drawMQTTEvent();
//incomingData = new String(payload);
//JSONObject json = parseJSONObject(incomingData);
//println(json);
//int msg = json.getInt("values");
//fill(255);
//rect(10,200, 30, 380-msg);
//println(msg);
}
void connectionLost() {
println("connection lost");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment