Images, Text, and Sound

This section will demonstrate how to display images, render text, and play sounds.

Table of Contents

  1. Persistent Variables
  2. Loading Images
  3. Processing Image Pixels
  4. Simple Text
  5. Text and Fonts
  6. Playing Sounds
  7. Audio Latency

Persistent Variables

The variables we’ve dealt with so far have been function parameters and local variables, both of which go out of scope after each frame. To preserve state across frames we can add private properties to the ofApp class as defined in the ofApp.h header file.

Primitive properties will be initially assigned zero, but can be manually assigned a value in setup(). Properties that are class-based will be constructed using their default constructor, but can also be assigned an initial state in setup().

The next two sections give us the opportunity to work with some private properties.

Loading Images

openFrameworks wraps the FreeImage library allowing us to load, display, resize, and manipulate images in formats like png, jpg, gif, bmp, tiff, and others.

In your project’s ofApp.h file below the method definitions:

private:
    ofImage freakyGoatGhost;

In the associated ofApp.cpp file, within setup():

// Place image file in the "bin/data/" folder:
freakyGoatGhost.load("freaky_goat_ghost.png");
// Or load from a URL:
freakyGoatGhost.load("http://example.com/freaky_goat_ghost.png");

Draw and resize within draw():

freakyGoatGhost.draw(10, 50); // Top left corner at x = 10 and y = 50
freakyGoatGhost.draw(100, 100, 50, 90); // Drawn at (100,100) resized to 50 width and 90 heights.

Resources

Processing Image Pixels

The color and brightness of any image pixel can be retrieved:

ofColor colorAtXY = freakyGoatGhost.getColor(30, 90); // The colour at x = 30 and y = 90
float brightnessAtXY = colorAtXY.getBrightness();

Resources

Simple Text

We can draw simple debugging messages to the screen at a set font size using:

// Using the current color set by `ofSetColor()`:
ofDrawBitmapString("Hello Whirled", 100, 200); // Write text to x = 100, y = 200.
// White text on black background.
ofDrawBitmapStringHighlight("Hello Whirled", 100, 120);
// Blue text on yellow background.
ofDrawBitmapStringHighlight("Hello Whirled", 100, 140, ofColor::yellow, ofColor::blue);

Resources

Text and Fonts

To draw text of any size we need to use a TrueType font.

Grab a font from your c:\windows\fonts folder a put it in the bin\data folder. For the sake of example, let’s say you grabbed verdana.ttf.

In your project’s ofApp.h file below the method definitions:

private:
    ofTrueTypeFont verdanaText;

In the associated ofApp.cpp file, within setup():

ofTrueTypeFont::setGlobalDpi(72); // Default is 96, but results in larger than normal pt size.
verdanaText.load(ofToDataPath("verdana.ttf"), 14, true, true); // filename via ofToDataPath, point size, antialiased?, full char-set?
verdanaText.setLineHeight(18.0); // Default is based on font size.
verdanaText.setLetterSpacing(1.05); // Default is based on font size.

And then within draw():

verdanatText.drawString("Hello Squirrel", 50, 100); // Output text at x = 50, y = 100

Resources

Playing Sounds

With openFrameworks we can easily load and play .mp3 and .wav sound files. openFrameworks wraps a number of different sound libraries to provide a common interface across different operating systems.

Like with images and fonts, sound files go in the bin\data folder, or into a sub-folder within bin\data. For this example let’s assume we are using an mp3 file named ka-ching.mp3.

In your project’s ofApp.h file below the method definitions:

private:
    ofSoundPlayer kaChing;

In the associated ofApp.cpp file, within setup():

kaChing.load("ka-ching.mp3");
kaChing.play(); // You can immediately play from setup if you wish.

To trigger the sound at a later time you could do something like this:

void ofApp::keyPressed(int key){
    if (key == 'p') {
        kaChing.play();
    }
}

There are additional methods to control the volume, playback speed, left/right pan, or cause the the sound to loop.

Resources

Audio Latency

From the ofBook Sound chapter:

“No matter what, sound you produce in your app will arrive at the speakers sometime after the event that triggered the sound. The total time of this round trip, from the event to your app to the speakers is referred to as latency.”

You usually won’t notice the latency, unless you try to build something like a drum machine that requires very tight timing. In this case you’ll need to look into using ASIO drivers for your sound card. You’ll also want to use an ofSoundStream along with the ofMaxim addon instead of the ofSoundPlayer used above.

Resources