Kinect and OpenFrameworks
Introduction to OpenFrameworks
OpenFrameworks was developed by Zach Lieberman, Theo Watson, Arthur Castro, and Chris O'Shea, along with help from collaborators at Parsons, MediaLabMadrid and Hanger
Center for the Arts. OpenFrameworks, or
oF, is a framework, which is a collection of code created to help you do something in particular. Some frameworks are designed to work with databases, others are designed for working with internet traffic. Frameworks don't provide you with an environment, but with the code that you can use to create your own programs. openFrameworks handles tasks that use C++ and OpenGL. C++ is the low-level functional programming language and OpenGL is the language that processes and renders 2D and 3D graphics.
Since openFrameworks is just a collection of code, it is platform independent. Supported IDEs for OpenFrameworks are Code::Blocks on all platforms, Visual C++ 2008 and Visual C++ 2010 on Windows and XCode on the Mac. To use OpenFrameworks, download the latest release from
www.openframeworks.cc
Be aware that OpenFrameworks uses relative addressing to call files and frameworks so you must follow the installation instructions to get your files compiled and up and running.
oF is a framework for artists and designers working with interactive design and media art. Because the underlying language is so flexible and low level, you can create features with oF that you can't with Processing.
When to use oF
- To make a project that renders a lot of 3D graphics
- To make a project that uses a computer vision library like OpenCV
- To make a project with Arduino
openFrameworks does not have an IDE. To use it, you must use an IDE that is platform dependent. The openFrameworks website (www.openframeworks.cc) will have the most up to date information about setting up on different platforms.
Mac OSX
To use openFrameworks on the Mac, you can work within XCode.
oF is a C++ library that was built with the intention of making C++ easier to use.
C++ (Basic Variable Types)
The basic variable types in C++ are similar to the basic types used in Arduino, except where Arduino uses
byte, C++ uses
char.A char stores 1 byte of information (a B, a small number up to 32,647 or a pixel in a JPEG).
Type | definition |
bool |
For storing true/false values |
int |
For storing integer numbers with a maximum value of 32767 |
long |
For storing large integer numbers with a maximum value of 2147483647 |
float |
For storing floating point numbers |
char |
For storing character values |
string |
For storing strings of characters |
Arrays
To create an array you need to state the type of object the array will store and the length of the array:
int array[5]={5,10,15,20,25};
You cannot initialize an array like this in the header file. You need to declare the array first
int array[5]; and then assign values to it in the setup() method of your application.
Methods
Methods have signatures:
returnType methodName(parameters){}
Methods can be overloaded:
String overloadedMethod(bool b);
String overloadedMethod(char c);
String overloadedMethod(String s);
Methods can be scoped to an object or be static. Sometimes methods or vaariables are scoped to a class. This means you can't call the method without an instance of a class. For instance, an oF program has a draw() method. You can't call draw() without having a program in which to draw.
ofBaseApp myApp;
myApp.draw();
When you want to call a method without creating an object, you use static methods. You can use a static method to get the time witout creating a date object
ApplicationTime::staticTimeMethod();
Classes and Objects
A class is stored in two separate files: the interface (.h) and the implementation file (.cpp).
The header file
class NameOfClass{
public:
void publicMethod(int);
private:
int privateMethod();
}
The implementation file
#include "NameOfClass.h"
void NameOfClass::publicMethod(int i){
//stuff
}
int NameOfClass::privateMethod(){
//other stuff
}
/ / An Application
The core of an oF program is the main application class,
ofBaseApp.
All the methods in the
ofBaseApp class are event-handling methods. This means they are triggered in response to events that happen within the program.
At its simplest, working with oF is adding new code to the appropriate method and waiting for the program to call your methods. The core oF framework handles creating the window and adding the appropriate code behind the scenes. To do something when these events occur, you just need to create a class that extends
ofBaseApp and add the appropriate methods.
setup()
The
setup() method is called when the program first starts up, the same as in Arduino or Processing. If something has to run only once or it is important to run at the beginning of your program, put it in the
setup() method. Also, if you are defining variables in your
.h file, you should initialize them. So if you have this in your header file:
In your
setup() method, you should initialize that if you are going to need it once your program starts running
update()
The
update() method is called just before the
draw() method. When using oF, you generally want to put any data processing you need to do in the
update() method so you're drawing with new data. For example, if you need to check and see whether any new sound is coming from a microphone before you draw the sound wave, you want to do that in the
update() method.
draw()
The
draw() method is called when the program draws its graphics.
exit()
The
exit() method is called when the program exits and closes down. If you want to do any final processing or data logging in your program, or to free memory this is the place to do it.
key events
The
keyPressed(int key) and
keyReleased(int key) methods are callbacks that handle any key actions that the user makes.
mouse events
The
mouseMoved(int x, int y),
mouseDragged(int x, int y, int button),
mousePressed(int x, int y, int button) and
mouseReleased() methods are callbacks that handle any mouse actions that the user makes.
audio events
The
audioRequested(float * output, int bufferSize, int nChannels) and
audioRequested(float * input, int bufferSize, int nChannels) are a little bit more complicated than the other methods as they use pointers to the stream of audi data. When you get an audio callback, the data represents the waveform of the sound that the computer's microphone has captured in a list of floating-point numbers, maybe something like 0.000688 or -0.000688 for a loud noise, or 0 for silence. The numbers represent the waveform of the sound. Instead of sending all the data to
ofBaseApp, the program sends just a single value: the location in memory where all this data is stored.
When you use these methods you are passing a pointer to an array of data for sound processing.
/ / Hello World
Your first oF application will be comprised of 3 files
- TestApp.h
- TestApp.cpp
- main.cpp
- Create a oF folder in your work folder
- Copy your downloaded folder into your oF folder
- Open XCode
- Create a new project new project (⌘+ ⇧+N). Select Other from the left side and select openframeworks
- Name and save this project inside the of_preRelease_v0061_osxSL_FAT:apps:examples folder
- All oF programs extend ofBaseApp class. Any methods you want your program to use will be defined in the .h file of your application class. In this example, you need to use setup() and draw() methods. Any method that you don't extend are left alone
Twirl open the src folder
- Double click on testApp.h
- Add the following:
- To use this font it must be stored in your data folder. Download and move this font frabk.ttf into the of_preRelease_v0061_osxSL_FAT:apps:examples:your_app:bin:data
- Double click on the TestApp.cpp
- Navigate to the the setup() method.
- Add the following:
franklin.loadFont("frabk.ttf",32);
ofBackground(255,255,255);
- Navigate to the the draw() method.
- Add the following:
ofSetColor(0x0000FF);
franklin.drawString("hello world",100,100);
- Save, Build and Run
- To close the application press escape
/ / Debugging
Errors are an inevitable part of the process of writing programs.Fortunately,
there are tools to help you figure out what went wrong and how to fix it.
Using printf
Anywhere you have code that might by executing in an unexpected way or a wayward variable, you can use
printf and pass it the variable name to determine the value of the variable at a given point in time.
printf can take an unlimited number of parameters. It takes a string that includes holders for the values you want to print, followed by those values.
int widthOfSomething=5;
printf(" this is the width of something: %i",widthOfSomething);
printf(" video is %i by %i",player.width, player.height);
string s="I'm a string";
printf("The string says:%s",s.c_str());
printf flags:
%c character a
%d, %i signed int -392
%u unsigned int 7235
%f float/double 392.65
%x hexadecimal int 7fa
%p pointer address 0xbffffa18
%e float/double (in scientific notation)
%g float/double (as %f or %e, depending on value)
%s C string sample
Using GNU Debugger
The GNU Debugger allows you to pause your program in the middle of the program, examine values, and move to the next line of code.
To use the debugger, you need to
- set a breakpoint. To do that, double-click a line number to the left of your code in your code view:
- set the project to Debug
- Initiate debugging by clicking on Build and Debug
- Open the Debugger Window (found under the Run menu)
- Use the Step Over button to step through the code