openFrameworks: Sketch My Name

openFrameworks
MS Windows
C/C++
A simple program to showcase creative coding with openFrameworks.
Author

Dennis Chua

Published

September 19, 2023


As a way to get warmed up with openFrameworks, I created as simple demo showcasing its basic features. Here I sketch the initials of my name using geometry primitives. I then put in a simple draw-animation of circles and background colors cycling through different hues.


What the video doesn’t show is the computer mouse pointer that interacts with the application. I’ve designated a bounding rectangle around the letters D-M-C. With each frame rendering, the application checks to see if the mouse pointer is found within this area. (The pointer crosses the boundary at 00:11.) Until the mouse pointer leaves the bounding rectangle, the program changes the RGB value of the background color. (The pointer exits the bounding area at 00:27 and the background color reverts to its default.)

The changing background colors are driven by a call to openFrameworks sin(), which in turn takes data from the system clock. A fudge factor of 0.75 slows the update rate to yield a more pleasant looking animation.

#pragma once

#include "ofMain.h"

class ofApp : public ofBaseApp {

public:
    void setup();
    void update();
    void draw();

    void keyPressed(int key);
    void keyReleased(int key);
    void mouseMoved(int x, int y);
    void mouseDragged(int x, int y, int button);
    void mousePressed(int x, int y, int button);
    void mouseReleased(int x, int y, int button);
    void mouseEntered(int x, int y);
    void mouseExited(int x, int y);
    void windowResized(int w, int h);
    void dragEvent(ofDragInfo dragInfo);
    void gotMessage(ofMessage msg);

    static const int WindowWidth = 1300;
    static const int WindowHeight = 768;

    const int TextXCoord = 90;
    const int TextYCoord = 90;
    const int TextWidth = 1050 + 135 - 90;
    const int TextHeight = 250 + 135 - 90;

    bool checkTextBounds(const int x, const int y);
};

struct backgroundColor {
    int red{};
    int green{};
    int blue{};
};

Listing of ofApp.h

#include "ofApp.h"

const struct backgroundColor BGColor { 31, 30, 28 };
struct backgroundColor bgColor = BGColor;

//--------------------------------------------------------------
void ofApp::setup() {
    ofBackground(bgColor.red, bgColor.green, bgColor.blue);
}

//--------------------------------------------------------------
void ofApp::update() {
    //Set the background color depending on the mouse position
    if (checkTextBounds(ofGetMouseX(), ofGetMouseY()) == true) {
        int offset = ofMap(sin(ofGetElapsedTimef() * 0.75), -1, 1, 0, 32);

        // The 16 adjustment sets a nice brown hue
        bgColor.red = BGColor.red + offset + 16;
        bgColor.green = BGColor.green + offset;
        bgColor.blue = BGColor.blue + offset - 16;

        std::cout << bgColor.red << " " << bgColor.green << " " << bgColor.blue << std::endl;
    }
    else {
        bgColor = BGColor;
    }
}

//--------------------------------------------------------------
void ofApp::draw() {

    ofBackground(bgColor.red, bgColor.green, bgColor.blue);

    // D
    ofSetColor(165, 87, 67);
    ofDrawCircle(250, 250, 150);
    ofDrawRectangle(100, 100, 150, 300);
    ofSetColor(bgColor.red, bgColor.green, bgColor.blue);
    ofDrawCircle(250, 250, 125);
    ofDrawRectangle(120, 125, 130, 250);

    // M
    ofSetColor(168, 142, 107);
    ofDrawRectangle(500, 100, 25, 300);
    ofDrawRectangle(760, 100, 25, 300);
    ofDrawTriangle(500, 100, 643, 200, 785, 100);
    ofSetColor(bgColor.red, bgColor.green, bgColor.blue);
    ofDrawTriangle(530, 100, 643, 180, 755, 100);

    // C
    ofSetColor(209, 162, 116);
    ofDrawCircle(1050, 250, 160);
    ofSetColor(bgColor.red, bgColor.green, bgColor.blue);
    ofDrawCircle(1050, 250, 135);
    ofDrawCircle(1250, 250, 135);

    // Our nice rectangle cloud
    ofSetColor(46 + ofRandom(15), 51 + ofRandom(15), 54 + ofRandom(15));
    for (int i = 9; i < 107; ++i) {
        for (int j = 40; j < 50; ++j) {
            ofDrawCircle(i * 11, j * 12, ofRandom(5));
        }
    }

}

// Other functions left out ...

bool ofApp::checkTextBounds(const int x, const int y) {
    // Confirm whether mouse is in the text bounding box
    if ((x >= TextXCoord && x <= TextXCoord + TextWidth) &&
        (y >= TextYCoord && y <= TextYCoord + TextHeight))
        return true;
    else
        return false;
}

Listing of ofApp.cpp

#include "ofMain.h"
#include "ofApp.h"

//========================================================================
int main() {

    //Use ofGLFWWindowSettings for more options like multi-monitor fullscreen
    ofGLWindowSettings settings;
    settings.title = "Sketch My Name";
    settings.setSize(ofApp::WindowWidth, ofApp::WindowHeight);
    settings.windowMode = OF_WINDOW; //can also be OF_FULLSCREEN

    auto window = ofCreateWindow(settings);

    ofRunApp(window, make_shared<ofApp>());
    ofRunMainLoop();
}

Listing of main.cpp