Getting started
The shape of every sketch, the coordinate system, math helpers, and reacting to the mouse and keyboard.
Umfeld is a C++ environment with a Processing-style API. A program is built from the same three functions you know from Processing — only the language underneath is C++.
The sketch skeleton
settings() configures the window, setup() runs once, draw() runs every frame.
#include "Umfeld.h"
using namespace umfeld;
void settings() {
size(1024, 768); // set the window size here, not in setup()
}
void setup() {
// runs once
}
void draw() {
background(216); // clear to light grey each frame
circle(mouseX, mouseY, 80);
}
Two lines do the bridging: #include "Umfeld.h" pulls in the API, and using namespace umfeld;
lets you write circle() instead of umfeld::circle(). Build it with CMake — see
Build and run at the end, or the
install guide.
Note for Processing users: there is no PDE and no “modes”. You edit
.cppfiles in any editor (VS Code, CLion, …) and build with CMake. Because this is C++, types are explicit — you writeint,float, andconstwhere a sketch language would let you leave them out.
The coordinate system
The origin (0, 0) is the top-left corner. X grows right, Y grows down. width and height
hold the window size, so the centre is always (width / 2, height / 2).
line(0, 0, width, height); // corner to corner
circle(width / 2, height / 2, 100); // centred
Printing to the console
println() and console() both take several comma-separated values:
println("frame:", frameCount, " mouse:", mouseX, mouseY);
Math functions
The Processing math helpers are all here:
float m = map(mouseX, 0, width, 0, 100); // remap one range to another
float c = constrain(m, 0, 50); // clamp into [0, 50]
float r = random(width); // 0 .. width
float r2 = random(-1, 1); // a range
float d = dist(x1, y1, x2, y2); // distance
float a = atan2(dy, dx); // angle of a vector
float n = noise(xoff); // Perlin noise (1D / 2D / 3D)
Angles are radians. Convert with radians() / degrees(), and reach for the constants
PI, HALF_PI, QUARTER_PI, TWO_PI.
Responding to the mouse
mouseX / mouseY track the cursor; isMousePressed is true while a button is held. Override
the callbacks for one-off events — the names match Processing:
void mousePressed() { /* a button went down */ }
void mouseReleased() { /* came back up */ }
void mouseDragged() { /* moved while pressed */ }
Responding to the keyboard
void keyPressed() {
println("pressed:", (char) key);
if (key == ' ') saveFrame();
if (key == '1') background(255);
}
void keyReleased() {
println("released:", (char) key);
}
The global key holds the character; isKeyPressed is true while any key is down. To stop the
OS auto-repeating a held key, set this in settings():
void settings() {
size(1024, 768);
config.ignore_key_repeat(true);
}
Build and run
Each sketch is a folder with one application.cpp and a CMakeLists.txt. The only line you
change is the path to the Umfeld library:
cmake_minimum_required(VERSION 3.12)
project(my_sketch) # your app name
set(UMFELD_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../umfeld") # path to the umfeld library
# --------- no need to change anything below this line ---------
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include_directories(".")
file(GLOB SOURCE_FILES "*.cpp")
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
add_subdirectory(${UMFELD_PATH} ${CMAKE_BINARY_DIR}/umfeld-lib-${PROJECT_NAME})
add_umfeld_libs()
cmake -B build # configure (once, or after editing CMakeLists.txt)
cmake --build build # compile
./build/my_sketch # run