I’m trying out the different creative coding frameworks - openFrameworks, Processing and p5.js in 2D/3D, and I’m surprised that Processing outperforms openFrameworks in 2D and 3D. I created a 2D sketch for all the platforms and this is the results I get:
Processing (P2D): 22 fps
openFrameworks: 13 fps
p5.js: 0.4 fps
Processing.py: 0.3 fps
Both openFrameworks and Processing are using OpenGL. It’s possible that I’m doing something wrong in C++. I am using references as much as possible instead of copying memory. I’m on a Mac. Below is my code:
ofApp.cpp:
void ofApp::setup(){
ofBackground(255, 255, 255);
for (int i = 0; i < numCircles; i++) {
float x = ofRandom(padding, width - padding);
float y = ofRandom(padding, height - padding);
float radius = ofRandom(radiusRange[0], radiusRange[1]);
ofVec2f velocity = ofVec2f(ofRandom(-velocityRange, velocityRange), ofRandom(-velocityRange, velocityRange));
circles.push_back(Circle(x, y, radius, velocity));
}
ofTrueTypeFont::setGlobalDpi(72);
font.load("verdana.ttf", 12);
}
void ofApp::update(){
for (auto &circle1 : circles) {
ofVec2f force;
int count = 0;
for (auto &circle2 : circles) {
if (&circle1 != &circle2) {
float distance = ofDist(circle1.position.x, circle1.position.y, circle2.position.x, circle2.position.y);
if (distance <= circle1.radius + circle2.radius && distance > 0) {
ofVec2f direction = circle1.position - circle2.position;
direction = direction.normalize();
float strength = forceStrength * circle2.mass * circle2.velocity.length();
force += direction * strength;
count++;
}
}
}
if (count > 0) {
force /= count;
}
circle1.applyForce(force);
ofVec2f friction = circle1.velocity;
friction *= -1;
friction = friction.getNormalized();
friction *= frictionStrength;
circle1.applyForce(friction);
}
for (auto &circle : circles) {
circle.update();
}
}
void ofApp::draw(){
// circles
for (auto &circle : circles) {
circle.draw();
}
// FPS
char frameRateStr[255];
sprintf(frameRateStr, "%f fps", ofGetFrameRate());
ofSetColor(0, 0, 0);
font.drawString(frameRateStr, 10, 15);
}
Circle::Circle(float x, float y, float pRadius, ofVec2f pVelocity) {
position = ofVec2f(x, y);
radius = pRadius;
mass = M_PI * pow(radius, 2) * massFactor;
velocity = pVelocity;
acceleration = ofVec2f(0, 0);
strokeCircle.circle(glm::vec2(0, 0), radius + (strokeWidth / 2));
strokeCircle.setStrokeWidth(strokeWidth);
strokeCircle.setColor(0);
fillCircle.circle(glm::vec2(0, 0), radius);
}
void Circle::update() {
velocity += acceleration;
if (maxVelocity != -1 && velocity.length() > maxVelocity) {
velocity.normalize();
velocity *= maxVelocity;
}
position += velocity;
acceleration *= 0;
checkEdges();
}
void Circle::draw() {
ofPushMatrix();
ofTranslate(position.x, position.y);
strokeCircle.draw();
fillCircle.setColor(ofColor(135, 138,212));
fillCircle.draw();
ofPopMatrix();
}
void Circle::checkEdges() {
if (position.x > width) {
position.x = width;
velocity.x *= -1;
} else if (position.x < 0) {
position.x = 0;
velocity.x *= -1;
}
if (position.y > height) {
position.y = height;
velocity.y *= -1;
} else if (position.y < 0) {
position.y = 0;
velocity.y *= -1;
}
}
void Circle::applyForce(ofVec2f force) {
acceleration += force / mass;
}
ofApp.h:
class Circle {
public:
ofVec2f position, velocity, acceleration;
float mass, radius;
Circle(float x, float y, float radius, ofVec2f velocity);
void draw();
void update();
void checkEdges();
void applyForce(ofVec2f force);
private:
ofPath strokeCircle;
ofPath fillCircle;
};
class ofApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
ofTrueTypeFont font;
vector<Circle> circles;
};