介绍一个非常好用的跨平台C++开源框架:openFrameworks

简介

首先需要说明的一点是: openFrameworks 设计的初衷不是为计算机专业人士准备的, 而是为艺术专业人士准备的, 就像 Processing 一样.

概述

openFrameworks 是一个功能强大, 上手超级简单的 C/C++ 开源框架. 它集成封装了很多常用的库, 诸如:

  • OpenGL、GLEW、GLUT、libtess2、cairo - 用于处理图形;
  • rtAudio、PortAudio、OpenAL、Kiss FFT、FMOD - 用于音频的输入、输出和分析;
  • FreeType - 用于字体显示;
  • FreeImage - 用于图像存储和载入;
  • Quicktime、GStreamer、videoInput - 用于视频播放和截取;
  • Poco - 用于开发网络应用;
  • OpenCV - 用于计算机视觉;
  • Assimp - 用于读入 3D 模型。

openFrameworks 为这些库提供了一个统一的接口, 使得使用它们变得异常容易.

跨平台

另外值得一提的就是 openFrameworks 的跨平台特性, 从桌面系统到移动终端, openFrameworks 目前支持:

  • Windows
  • OSX
  • Linux
  • Android
  • iOS



最新的 0.9.0 版本还支持运行 Linux 系统的 arm 开发板, 例如树莓派.

支持发布为WEB形式

openFrameworks 集成了 Emscripten 作为插件, 我们的 openFrameworks 程序可以通过它很容易地转换成 javascript 的格式, 这样非常方便就把本地项目转换成了 WEB 项目, 可以直接发布到网络上.

支持多种开发环境

openFrameworks 除了支持命令行编译外, 还支持比较常用的几种集成开发环境. 如下:

  • Visual Studio
  • XCode
  • Eclipse
  • Code::Blocks

超级简单的代码结构

其实 openFrameworks 最值得称道的是它的代码结构极其简单, 假设你的项目名为 myOF, 那么代码结构如下:

#include "myOF.h"

//--------------------------------------------------------------
void myOF::setup(){ } //--------------------------------------------------------------
void myOF::update(){ } //--------------------------------------------------------------
void myOF::draw(){ } //--------------------------------------------------------------
void myOF::keyPressed(int key){ } ...

如果你有过使用 Processing 的经验, 就会感觉非常熟悉, 没错, 这些函数跟 Processing 中的含义完全一样.

  • setup 在程序启动时执行一次;
  • draw 在程序启动后每秒执行60次(该频率可设), 用来绘制图形;
  • updatedraw 一样, 每秒执行60次, 把需要更新的代码放在这里;
  • keyPressed 处理按键事件;
  • 还有处理鼠标事件的一系列函数, 这里就不赘述了.

为什么会使用这种代码结构? 因为 openFrameworks 原本的设计目的就是要让非计算机专业的人士通过编程来创造各种计算机视觉/图像/视频/声音艺术, 就像 Processing 的设计目标一样, 所以它才会搞成这种简单易用但是功能强大的形式.

安装

openFrameworks 支持多个平台的安装, 从官网下载地址取得对应的版本, 以树莓派为例, 如下:

解压后进入目录:

pi@rpi /opt/software/openFrameworks $ cd scripts/linux/debian/
pi@rpi /opt/software/openFrameworks/scripts/linux/debian $ ls
install_codecs.sh install_dependencies.sh
pi@rpi /opt/software/openFrameworks/scripts/linux/debian $

安装依赖:

pi@rpi /opt/software/openFrameworks/scripts/linux/debian $ sudo ./install_dependencies.sh

安装编解码:

pi@rpi /opt/software/openFrameworks/scripts/linux/debian $ sudo ./install_codecs.sh

编译oF库:

pi@rpi /opt/software/openFrameworks/scripts/linux $ ls
archlinux buildAllExamples.sh cleanAllExamples.sh compileOF.sh debian removeFMOD.sh ubuntu
archlinux_armv6 buildAllRPIExamples.sh codeblocks_wizard compilePG.sh fedora testAllExamples.sh ubuntu-omap4
pi@rpi /opt/software/openFrameworks/scripts/linux $ sudo ./compileOF.sh

编译项目生成器:

pi@rpi /opt/software/openFrameworks/scripts/linux $ sudo ./compilePG.sh

编译全部例程:

pi@rpi /opt/software/openFrameworks/scripts/linux $ sudo ./buildAllRPIExamples.sh

执行所有编译好的例程:

pi@rpi /opt/software/openFrameworks/scripts/linux $ sudo ./testAllExamples.sh

也可以单独编译某个例程, 只要进入其目录操作即可.

编写自己的项目

安装好之后, 在目录 ./examples/empty/ 下有一个空项目模板 emptyExample, 我们可以基于这个空项目模板来写自己的 oF 程序, 针对不同的平台, 空项目模板的结构也不同, 例如:

  • Raspbian 平台下, 空项目模板的结构如下:
pi@rpi /opt/software/openFrameworks/examples/empty $ tree emptyExample/
emptyExample/
├── bin
│   ├── emptyExample
│   ├── libs
│   └── readMe.txt
├── config.make
├── Makefile
├── obj
│   └── linuxarmv7l
│   └── Release
│   └── src
│   ├── main.d
│   ├── main.o
│   ├── ofApp.d
│   └── ofApp.o
└── src
├── main.cpp
├── ofApp.cpp
└── ofApp.h 7 directories, 11 files
pi@rpi /opt/software/openFrameworks/examples/empty $
  • OSX 平台下, 空项目模板的结构如下:
admin@Air:~/Downloads/of_v0.9.0_osx_release/examples/empty$ tree emptyExample/ |more
emptyExample/
├── Makefile
├── Project.xcconfig
├── addons.make
├── bin
│   ├── data
│   └── emptyExample.app
│   └── Contents
│   ├── Frameworks
│   │   └── GLUT.framework
│   │   ├── GLUT -> Versions/Current/GLUT
│   │   ├── Headers -> Versions/Current/Headers
│   │   ├── Resources -> Versions/Current/Resources
│   │   └── Versions
│   │   ├── A
│   │   │   ├── GLUT
│   │   │   ├── Headers
│   │   │   │   ├── copy.h
│   │   │   │   ├── extrude.h
│   │   │   │   ├── glsmap.h
│   │   │   │   ├── glsmapint.h
│   │   │   │   ├── glut.h
│   │   │   │   ├── glutbitmap.h
│   │   │   │   ├── glutf90.h
│   │   │   │   ├── glutstroke.h
│   │   │   │   ├── gutil.h
│   │   │   │   ├── intersect.h
│   │   │   │   ├── port.h
│   │   │   │   ├── rot.h
│   │   │   │   ├── segment.h
│   │   │   │   ├── tube.h
│   │   │   │   ├── tube_gc.h
│   │   │   │   └── vvector.h
│   │   │   └── Resources
│   │   │   ├── Caution.tiff
│   │   │   ├── English.lproj
│   │   │   │   ├── GLUT.nib
│   │   │   │   │   └── objects.nib
│   │   │   │   ├── GLUTClipboard.nib
│   │   │   │   │   └── objects.nib
│   │   │   │   ├── GLUTPreferences.nib
│   │   │   │   │   └── objects.nib
│   │   │   │   ├── GLUTUI.strings
│   │   │   │   └── InfoPlist.strings
│   │   │   ├── Info.plist
│   │   │   ├── blankCursor.tiff
│   │   │   ├── bottomCursor.tiff
│   │   │   ├── bottomleftCursor.tiff
│   │   │   ├── bottomrightCursor.tiff
│   │   │   ├── crossCursor.tiff
│   │   │   ├── cycleCursor.tiff
│   │   │   ├── destroyCursor.tiff
│   │   │   ├── fingerCursor.tiff
│   │   │   ├── helpCursor.tiff
│   │   │   ├── leftCursor.tiff
│   │   │   ├── leftRightCursor.tiff
│   │   │   ├── rightArrowCursor.tiff
│   │   │   ├── rightCursor.tiff
│   │   │   ├── sprayCursor.tiff
│   │   │   ├── topCursor.tiff
│   │   │   ├── topleftCursor.tiff
│   │   │   ├── toprightCursor.tiff
│   │   │   ├── upDownCursor.tiff
│   │   │   └── waitCursor.tiff
│   │   └── Current -> A
│   ├── Info.plist
│   ├── MacOS
│   │   ├── emptyExample
│   │   └── libfmodex.dylib
│   ├── PkgInfo
│   └── Resources
│   └── icon.icns
├── build
│   └── emptyExample.build
│   └── Release
│   └── emptyExample.build
│   ├── Objects-normal
│   │   └── x86_64
│   │   ├── emptyExample.LinkFileList
│   │   ├── emptyExample_dependency_info.dat
│   │   ├── main.d
│   │   ├── main.dia
│   │   ├── main.o
│   │   ├── ofApp.d
│   │   ├── ofApp.dia
│   │   └── ofApp.o
│   ├── Script-E4B6FFFD0C3F9AB9008CF71C.sh
│   ├── dgph
│   ├── dgph~
│   └── emptyExample.hmap
├── config.make
├── emptyExample.xcodeproj
│   ├── project.pbxproj
│   └── xcshareddata
│   └── xcschemes
│   ├── emptyExample Debug.xcscheme
│   └── emptyExample Release.xcscheme
├── openFrameworks-Info.plist
└── src
├── main.cpp
├── ofApp.cpp
└── ofApp.h 29 directories, 72 files
admin@Air:~/Downloads/of_v0.9.0_osx_release/examples/empty$

这个空模板项目既可以在诸如 XCode 之类的 IDE 中打开, 也可以直接在命令行编辑, 然后在命令行编译, 下面, 我们分别在 RaspbianOSX 的命令行下新建一个项目并编译它.

在Raspbian下新建项目并编译

首先把空模板拷贝一份, 假设我们的项目叫 myOF, 那么执行下面这条命令:

pi@rpi /opt/software/openFrameworks/examples/empty $ cp -R  emptyExample/ ./myOF
pi@rpi /opt/software/openFrameworks/examples/empty $ ls
emptyExample myOF
pi@rpi /opt/software/openFrameworks/examples/empty $ cd myOF/
pi@rpi /opt/software/openFrameworks/examples/empty/myOF $ ls
bin config.make Makefile obj src
pi@rpi /opt/software/openFrameworks/examples/empty/myOF $

其中 src 目录是源代码目录, 进入查看

pi@rpi /opt/software/openFrameworks/examples/empty/myOF $ cd src
pi@rpi /opt/software/openFrameworks/examples/empty/myOF/src $ ls
main.cpp ofApp.cpp ofApp.h
pi@rpi /opt/software/openFrameworks/examples/empty/myOF/src $

总共3个文件, 分别看看内容:

  • main.cpp
pi@rpi /opt/software/openFrameworks/examples/empty/myOF/src $ cat main.cpp
#include "ofMain.h"
#include "ofApp.h" //========================================================================
int main( ){ ofSetupOpenGL(1024,768, OF_WINDOW); // <-------- setup the GL context // this kicks off the running of my app
// can be OF_WINDOW or OF_FULLSCREEN
// pass in width and height too:
ofRunApp( new ofApp()); }
pi@rpi /opt/software/openFrameworks/examples/empty/myOF/src $
  • ofApp.cpp
pi@rpi /opt/software/openFrameworks/examples/empty/myOF/src $ cat ofApp.cpp
#include "ofApp.h" //--------------------------------------------------------------
void ofApp::setup(){ } //--------------------------------------------------------------
void ofApp::update(){ } //--------------------------------------------------------------
void ofApp::draw(){ } //--------------------------------------------------------------
void ofApp::keyPressed(int key){ } //--------------------------------------------------------------
void ofApp::keyReleased(int key){ } //--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y){ } //--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){ } //--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){ }
//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){ } //--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){ } //--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){ } //--------------------------------------------------------------
void ofApp::windowResized(int w, int h){ } //--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){ } //--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){ }
pi@rpi /opt/software/openFrameworks/examples/empty/myOF/src $
  • ofApp.h
pi@rpi /opt/software/openFrameworks/examples/empty/myOF/src $ cat ofApp.h
#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);
};
pi@rpi /opt/software/openFrameworks/examples/empty/myOF/src $

容易看出, 我们要编辑的文件是 ofApp.cpp, 我们打算画两个不同颜色的圆, 代码就是下面这些:

//--------------------------------------------------------------
void ofApp::draw(){
ofSetColor(255, 0, 255);
ofCircle(200, 300, 60); ofSetColor(0, 255, 255);
ofCircle(500, 500, 100);
}

修改 ofApp.cpp 后保存, 回到上层目录, 开始编译:

pi@rpi /opt/software/openFrameworks/examples/empty/myOF $ sudo make
HOST_OS=Linux
HOST_ARCH=armv7l
checking pkg-config libraries: cairo zlib gstreamer-app-1.0 gstreamer-1.0 gstreamer-video-1.0 gstreamer-base-1.0 libudev freetype2 fontconfig sndfile openal openssl libpulse-simple alsa gtk+-3.0 libmpg123
Compiling OF library for Release
make[1]: Entering directory '/opt/software/openFrameworks/libs/openFrameworksCompiled/project'
HOST_OS=Linux
HOST_ARCH=armv7l
checking pkg-config libraries: cairo zlib gstreamer-app-1.0 gstreamer-1.0 gstreamer-video-1.0 gstreamer-base-1.0 libudev freetype2 fontconfig sndfile openal openssl libpulse-simple alsa gtk+-3.0 libmpg123
HOST_OS=Linux
HOST_ARCH=armv7l
checking pkg-config libraries: cairo zlib gstreamer-app-1.0 gstreamer-1.0 gstreamer-video-1.0 gstreamer-base-1.0 libudev freetype2 fontconfig sndfile openal openssl libpulse-simple alsa gtk+-3.0 libmpg123
Compiling /opt/software/openFrameworks/libs/openFrameworks/utils/ofSystemUtils.cpp ... HOST_OS=Linux
HOST_ARCH=armv7l
checking pkg-config libraries: cairo zlib gstreamer-app-1.0 gstreamer-1.0 gstreamer-video-1.0 gstreamer-base-1.0 libudev freetype2 fontconfig sndfile openal openssl libpulse-simple alsa gtk+-3.0 libmpg123 compiling done
to launch the application cd bin
./myOF - or - make run make[1]: Leaving directory '/opt/software/openFrameworks/examples/empty/myOF'
pi@rpi /opt/software/openFrameworks/examples/empty/myOF $

成功编译, 没有错误!

我们可以直接进入目录 bin/myOF.app/Contents/MacOS/ 下运行 ./myOF, 也可以直接在当前目录下运行 make run 来查看结果:

pi@rpi /opt/software/openFrameworks/examples/empty/myOF $ make run
HOST_OS=Linux
HOST_ARCH=armv7l
checking pkg-config libraries: cairo zlib gstreamer-app-1.0 gstreamer-1.0 gstreamer-video-1.0 gstreamer-base-1.0 libudev freetype2 fontconfig sndfile openal openssl libpulse-simple alsa gtk+-3.0 libmpg123
[notice ] ofAppEGLWindow: setupRPiNativeWindow(): screenRect: 1280x1024
[notice ] ofAppEGLWindow: setupRPiNativeWindow(): windowRect: 1024x768
[notice ] ofAppEGLWindow: createSurface(): setting up EGL Display
[notice ] ofAppEGLWindow: createSurface(): EGL Display correctly set 0x1
[notice ] ofAppEGLWindow: createSurface(): no current renderer selected
[notice ] ofAppEGLWindow: createSurface(): default renderer detected
[notice ] ofAppEGLWindow: createSurface(): surface created correctly
[notice ] ofAppEGLWindow: createSurface(): API bound correctly
[notice ] ofAppEGLWindow: createSurface(): -----EGL-----
[notice ] ofAppEGLWindow: createSurface(): EGL_VERSION_MAJOR = 1
[notice ] ofAppEGLWindow: createSurface(): EGL_VERSION_MINOR = 4
[notice ] ofAppEGLWindow: createSurface(): EGL_CLIENT_APIS = OpenGL_ES OpenVG
[notice ] ofAppEGLWindow: createSurface(): EGL_VENDOR = Broadcom
[notice ] ofAppEGLWindow: createSurface(): EGL_VERSION = 1.4
[notice ] ofAppEGLWindow: createSurface(): EGL_EXTENSIONS = EGL_KHR_image EGL_KHR_image_base EGL_KHR_image_pixmap EGL_KHR_vg_parent_image EGL_KHR_gl_texture_2D_image EGL_KHR_gl_texture_cubemap_image EGL_KHR_lock_surface
[notice ] ofAppEGLWindow: createSurface(): GL_RENDERER = VideoCore IV HW
[notice ] ofAppEGLWindow: createSurface(): GL_VERSION = OpenGL ES-CM 1.1
[notice ] ofAppEGLWindow: createSurface(): GL_VENDOR = Broadcom
[notice ] ofAppEGLWindow: createSurface(): -------------
[notice ] ofAppEGLWindow: setupPeripherals(): peripheral setup complete
[notice ] ofAppEGLWindow: setupNativeUDev(): created udev object
[notice ] ofAppEGLWindow: setupMouse(): mouse_fd= 5 devicePath=/dev/input/by-path/platform-3f980000.usb-usb-0:1.2:1.0-event-mouse
[notice ] ofAppEGLWindow: setupMouse(): mouse device name = Logitech USB Optical Mouse
[notice ] ofAppEGLWindow: setupKeyboard(): keyboard_fd= 6 devicePath=/dev/input/by-path/platform-3f980000.usb-usb-0:1.3:1.0-event-kbd
[notice ] ofAppEGLWindow: setupKeyboard(): keyboard device name = USB Keyboard
[notice ] ofAppEGLWindow: setupPeripherals(): native event setup complete

ESC 或者 Ctrl-c退出.

因为 openFrameworks 通过 framebuffer 绘图, 所以不需要 XWindows.

说明: 因为树莓派下截图比较麻烦, 所以一律从 OSX 上截图.

注意: 在树莓派上运行需要有一个直接外接的屏幕, 只通过 VNC 连接是看不到绘制出的图像的.

在OSX下新建项目并编译

OSX 准备的项目模板既可以通过命令行编译, 也可以通过 XCode 编译, 首次编译花的时间比较长, 因为要编译各种库, 之后再编译就快多了.

通过拷贝空项目模板来新建项目, 然后修改 ofApp.cpp, 再进行编译, 记录如下:

...
admin@Air:~/Downloads/of_v0.9.0_osx_release/examples/empty/myOF$ sudo make
HOST_OS=Darwin
HOST_ARCH=x86_64
Compiling OF library for Release
HOST_OS=Darwin
HOST_ARCH=x86_64
HOST_OS=Darwin
HOST_ARCH=x86_64
HOST_OS=Darwin
HOST_ARCH=x86_64
Done! Compiling myOF for Release
HOST_OS=Darwin
HOST_ARCH=x86_64
Compiling /Users/admin/Downloads/of_v0.9.0_osx_release/examples/empty/myOF/src/ofApp.cpp ... HOST_OS=Darwin
HOST_ARCH=x86_64
TARGET=bin/myOF compiling done
to launch the application cd bin/myOF.app/Contents/MacOS/
./myOF - or - make run
admin@Air:~/Downloads/of_v0.9.0_osx_release/examples/empty/myOF$

没有任何错误, 完成编译, 用跟 Raspbian 同样的方式来运行编译好的程序

admin@Air:~/Downloads/of_v0.9.0_osx_release/examples/empty/myOF$ make run
HOST_OS=Darwin
HOST_ARCH=x86_64

运行截图如下:

如果打算增加点内容, 修改 ofApp.cpp 中对应的函数即可.

显示/修改刷新频率

  • 显示刷新频率:

draw 中增加这一句:

ofDrawBitmapString(ofToString(ofGetFrameRate())+"fps", 10, 15);

可以在程序窗口左上角显示帧速率

  • 修改刷新频率

setup 中增加这一句:

ofSetFrameRate(60);

让图形边缘平滑

setup 中增加这几句:

// 修改绘制精度
ofSetCircleResolution(120);
// 开启抗锯齿
ofEnableSmoothing();
// 开启垂直同步
ofSetVerticalSync(true);

修改背景色

setup 中增加这一句:

ofBackground(0,0,0);

把背景色改为黑色.

截图如下:

绘制其他的形状

除了画圆,oF 也可以画其他的图案:

  • ofRect - 画一个矩形。参数是:(x, y, width, height) ;
  • ofTriangle - 画一个三角形。参数是三个顶点的坐标:(x1, y1, x2, y2, x3, y3)
  • ofLine - 画一条线段。参数是两个端点的坐标 (x1, y1, x2, y2)
  • ofEllipse - 画椭圆。参数是:(x, y, width, height)
  • ofCurve - 画一条从点 (x1, y1) 到 (x2, y2) 的贝塞尔曲线,曲线的形状由两个控制点 (x0, y0) 和 (x3, y3) 控制

openFrameworksAPI函数可以在它的官网文档查询, 该文档不仅包含对 openFrameworks API 说明, 也包含了对插件 API 的说明, 相当详细.

各种插件

自带插件

openFrameworks 支持第三方插件, 我们先看看这个版本自带了哪些插件:

admin@Air:~/Downloads/of_v0.9.0_osx_release/addons$ ls -al
total 16
drwxr-xr-x@ 15 admin staff 510 12 17 17:25 .
drwxr-xr-x@ 17 admin staff 578 12 16 21:19 ..
-rw-r--r--@ 1 admin staff 6148 12 17 17:30 .DS_Store
drwxr-xr-x@ 6 admin staff 204 11 8 17:30 ofxAssimpModelLoader
drwxr-xr-x@ 4 admin staff 136 11 8 17:30 ofxEmscripten
drwxr-xr-x@ 3 admin staff 102 11 8 17:30 ofxGui
drwxr-xr-x@ 8 admin staff 272 11 8 17:30 ofxKinect
drwxr-xr-x 17 admin staff 578 12 17 17:29 ofxLua
drwxr-xr-x@ 4 admin staff 136 11 8 17:30 ofxNetwork
drwxr-xr-x@ 6 admin staff 204 11 8 17:30 ofxOpenCv
drwxr-xr-x@ 5 admin staff 170 11 8 17:30 ofxOsc
drwxr-xr-x@ 4 admin staff 136 11 8 17:30 ofxSvg
drwxr-xr-x@ 3 admin staff 102 11 8 17:30 ofxThreadedImageLoader
drwxr-xr-x@ 4 admin staff 136 11 8 17:30 ofxVectorGraphics
drwxr-xr-x@ 4 admin staff 136 11 8 17:30 ofxXmlSettings
admin@Air:~/Downloads/of_v0.9.0_osx_release/addons$

想看到更多的插件可以来这里官网插件查找, 或者到 github 搜索 ofx 打头的项目.

这里列举一些比较常见的插件

  • ofxUI - 华丽丽的 UI 库。提供了很多新颖而实用的界面控件。
  • ofxCv - OpenCV 的另一套可选的 oF 插件(oF 自带一个 oFOpenCv 插件);
  • ofxLibRocket - 对 librocket 库的封装,这个库允许你使用 html 和 css 来布局 C++ 窗口;
  • ofxTrueTypeFontUC - 对 ofTrueTypeFont 类的扩展,使其支持 Unicode 字符(例如汉字);
  • ofxPCL - 对 PCL(一个专门用于处理点云的库) 的封装;
  • ofxTimeline - 一个用来绘制可编辑的 timeline 控件的插件;
  • ofxMidi - Midi 音乐的插件;
  • ofxSpeech - 语音识别插件;
  • ofxVideoRecorder - 录制视频插件;
  • ofxImageSequence - 一个用于像播放视频一样播放图像序列的插件;
  • ofxGifEncoder - 生成 Gif 动画的插件;
  • ofxVolumetrics - 简单的体绘制插件;
  • ofxFft - 对两个用于进行傅里叶变换的库 FFTW 和 KissFFT 的封装;
  • ofxNodejs - 桥接 Node.js 的插件;
  • ofxLua - 桥接 Lua 的插件;
  • ofxBox2d - 对流行的 2D 物理模拟库 box2d 的封装;
  • ofxBullet - 对另一个物理模拟库 Bullet Physics 的封装;
  • ofxLearn - 通用的机器学习插件,支持分类、回归、聚类等任务;
  • ofxJSON - 对 Json 库 JsonCpp 的封装;
  • ofxHttpServer - 一个基于 libmicrohttpd 的 http 服务器插件;
  • ofxAddonTemplate - 一个空的目录框架,可以借鉴它自己编写插件(这都有……--bb)。

插件使用方法:

访问这个插件的 Github 项目主页;

把它克隆到你的 addons 目录:

进入你的 openFrameworks 目录下的 addons 目录,git clone 该项目;

如果这个项目自带 example ,可以直接 make && make run 编译和执行它看看结果。

说明: 本文大量参考A Brief Introduction to openFrameworks-介绍一个开源的 C++ 开发框架 openFrameworks文中的内容, 特此感谢.

参考

A Brief Introduction to openFrameworks-介绍一个开源的 C++ 开发框架 openFrameworks

介绍一个非常好用的跨平台C++开源框架:openFrameworks的更多相关文章

  1. 介绍一个python的新的web framework——karloop框架

    karloop是一款轻型的web framework,和tornado.webpy类似.mvc分层设计,眼下已经公布早期版本号了,使用方便, 下载地址例如以下:https://github.com/k ...

  2. 文件系统:介绍一个高大上的东西 - 零基础入门学习Python030

    文件系统:介绍一个高大上的东西 让编程改变世界 Change the world by program 接下来我们会介绍跟Python的文件相关的一些十分有用的模块.模块是什么?不知大家对以下代码还有 ...

  3. 如何创建一个基于 MSBuild Task 的跨平台的 NuGet 工具包

    MSBuild 的 Task 为我们扩展项目的编译过程提供了强大的扩展性,它使得我们可以用 C# 语言编写扩展:利用这种扩展性,我们可以为我们的项目定制一部分的编译细节.NuGet 为我们提供了一种自 ...

  4. 介绍一个axios调试好用的工具:axios-mock-adapter

    上一篇文章中写到用promise时应注意的问题,这一篇文章继续介绍一个可以和axios库配合的好工具: axios-mock-adapter.axios-mock-adapter可以用来拦截http请 ...

  5. 介绍一个基于jQuery的Cookie操作插件

    在网页客户端,我们经常会遇到读取或者设置cookie的情况,如果用纯生的js我们可能会遇到一些兼容性带来的麻烦,这里给大家介绍一个比较实用jquery操作cookie的插件,插件的源代码如下: jQu ...

  6. 介绍一个python视频处理库:moviepy

    由于博客园的插件和我自己博客的插件不一致,代码以及视频插入转换很麻烦,所以还是我原来博客的地址查看吧. 介绍一个python视频处理库:moviepy

  7. 转:介绍一个好用的抓取dump的工具-ProcDump

    介绍一个好用的抓取dump的工具-ProcDump Procdump是一个轻量级的Sysinternal团队开发的命令行工具, 它的主要目的是监控应用程序的CPU异常动向, 并在此异常时生成crash ...

  8. ISE(Iris Server Engine)是一个基于现代C++的跨平台(Linux和Windows)框架

    ISE(Iris Server Engine)是一个基于现代C++的跨平台(Linux和Windows)的高性能多线程并发网络服务器程序框架.它封装了琐碎的socket以及各种操作系统APIs,以面向 ...

  9. Microsoft SilverLightt是一个跨浏览器的、跨平台的插件,为网络带来下一代基于.NETFramework的媒体体验和丰富的交互式应用程序。

    Microsoft Silverlight是一个跨浏览器的.跨平台的插件,为网络带来下一代基于.NETFramework的媒体体验和丰富的交互式应用程序.Silverlight提供灵活的编程模型,并可 ...

随机推荐

  1. 嵌入式Linux驱动学习之路(十六)输入子系统

    以前写的一些输入设备的驱动都是采用字符设备处理的.问题由此而来,Linux开源社区的大神们看到了这大量输入设备如此分散不堪,有木有可以实现一种机制,可以对分散的.不同类别的输入设备进行统一的驱动,所以 ...

  2. SQL/LINQ/Lamda 写法[转发]

    SQL LINQ Lambda SELECT * FROM HumanResources.Employee from e in Employees select e Employees   .Sele ...

  3. concat() 方法用于连接两个或多个数组。

    我们创建了三个数组,然后使用 concat() 把它们连接起来: <script type="text/javascript"> var arr = new Array ...

  4. Swift中的willSet与didSet

    Swift中的willSet与didSet 周银辉 在Swift语言中用了willSet和didSet这两个特性来监视属性的除初始化之外的属性值变化 无需说太多,看看下面的代码你就能很快明白的 imp ...

  5. 直接启动tomcat时为tomcat指定JDK

    第一种: 在windows环境下以批处理文件方式启动tomcat,只要运行<CATALINA_HOME>/bin/startup.bat这个文件,就可以启动Tomcat.在启动时,star ...

  6. linux进阶1

    1.linux命令 1.1.find功能:在linux文件系统中,用来查找一个文件放在哪里了.举例:find /etc -name "interfaces"总结:(1)什么时候用f ...

  7. javaweb局部刷新-ajax异步请求springMVC显示返回的jsp内容,代替iframe

    在jsp上要引入jquery <script src="<%=request.getContextPath()%>/js/jquery_ui/jquery.js" ...

  8. 标准C++之运算符重载和虚表指针

    1 -> *运算符重载 //autoptr.cpp     #include<iostream> #include<string> using namespace std ...

  9. miniui无法传递input值

    miniui获取到的值死活传不到php去处理,input框里有值php接收到却一直为空,又是查资料.测试.搜索.提问,最后才在文档中发现尼玛miniui不用name的,其实是<input tex ...

  10. 【整理】Word OpenXML常用标签

    一.背景 最近在做关于Word内容自动标引,需要了解Word的底层结构,顺便梳理一下OpenXML的标签含义,方便后续开发,提高对OpenXML标签的查找效率,也是一个熟悉的过程. 二.内容 < ...