Сайты:
OF: http://www.openframeworks.cc
P: http://processing.org
Лицензия:
OF: MIT (используемые библиотеки, имеют собственные лицензии)
P: GPL and LGPL
Версия:
OF: 0.061
P: 1.2.1
Wiki:
OF: http://en.wikipedia.org/wiki/OpenFrameworks
P: http://en.wikipedia.org/wiki/Processing_(programming_language)
http://ru.wikipedia.org/wiki/Processing
Документация:
OF: http://www.openframeworks.cc/documentation
P: http://processing.org/reference/
Попробуем портировать скетч Processing-а в программу для OpenFrameworks.
Возьмём скетч Chain.pde (Topics — Simulate)
Цепь. Один массивный объект (окружность) прикрепляется к позиции указателя мышки, а второй объект прикрепляется к первому. На оба объекта действует сила гравитации, которая тянет их вниз.
Т.о. скетч рисует две окружности, соединённых белой линией и одна линия соединяется с текущим положеним указателя мышки.
Вот как это выглядит:

А вот код Processing-а:
/**
 * Chain. 
 * 
 * One mass is attached to the mouse position and the other 
 * is attached the position of the other mass. The gravity
 * in the environment pulls down on both. 
 */
Spring2D s1, s2;
float gravity = 6.0;
float mass = 2.0;
void setup() 
{
  size(200, 200);
  smooth();
  fill(0);
  // Inputs: x, y, mass, gravity
  s1 = new Spring2D(0.0, width/2, mass, gravity);
  s2 = new Spring2D(0.0, width/2, mass, gravity);
}
void draw() 
{
  background(204);
  s1.update(mouseX, mouseY);
  s1.display(mouseX, mouseY);
  s2.update(s1.x, s1.y);
  s2.display(s1.x, s1.y);
}
class Spring2D {
  float vx, vy; // The x- and y-axis velocities
  float x, y; // The x- and y-coordinates
  float gravity;
  float mass;
  float radius = 20;
  float stiffness = 0.2;
  float damping = 0.7;
  
  Spring2D(float xpos, float ypos, float m, float g) {
    x = xpos;
    y = ypos;
    mass = m;
    gravity = g;
  }
  
  void update(float targetX, float targetY) {
    float forceX = (targetX - x) * stiffness;
    float ax = forceX / mass;
    vx = damping * (vx + ax);
    x += vx;
    float forceY = (targetY - y) * stiffness;
    forceY += gravity;
    float ay = forceY / mass;
    vy = damping * (vy + ay);
    y += vy;
  }
  
  void display(float nx, float ny) {
    noStroke();
    ellipse(x, y, radius*2, radius*2);
    stroke(255);
    line(x, y, nx, ny);
  }
} 
Попробуем портировать его на OpenFrameworks.
В директории examples создаём новую папку, которую назовём myofChain.
Копируем туда содержимое директории emptyExample, переименовываем файлы проекта и вносим в них требуемые изменения (этот шаг подробно описан во вводной статье про OpenFrameworks)
Первым делом нужно создать файлы Spring.h и Spring.cpp
— в них будет храниться класс Spring2D:
Spring.h:
#ifndef _SPRING_H_
#define _SPRING_H_
//
// openFrameworks vs Processing
// 
// Chain.pde
//
#include "ofMain.h"
class Spring2D 
{
public:
	float vx, vy; // The x- and y-axis velocities
	float x, y; // The x- and y-coordinates
	float gravity;
	float mass;
	float radius;
	float stiffness;
	float damping;
	Spring2D();
	~Spring2D();
	Spring2D(float xpos, float ypos, float m, float g);
	void update(float targetX, float targetY);
	void display(float nx, float ny);
};
#endif //#ifndef _SPRING_H_  
Spring.cpp:
#include "Spring.h"
Spring2D::Spring2D():
radius(20),
stiffness(0.2),
damping(0.7)
{
}
Spring2D::~Spring2D()
{
}
Spring2D::Spring2D(float xpos, float ypos, float m, float g):
radius(20),
stiffness(0.2),
damping(0.7) 
{
	x = xpos;
	y = ypos;
	mass = m;
	gravity = g;
}
void Spring2D::update(float targetX, float targetY) 
{
	float forceX = (targetX - x) * stiffness;
	float ax = forceX / mass;
	vx = damping * (vx + ax);
	x += vx;
	float forceY = (targetY - y) * stiffness;
	forceY += gravity;
	float ay = forceY / mass;
	vy = damping * (vy + ay);
	y += vy;
}
void Spring2D::display(float nx, float ny) 
{
	//noStroke();
	//ellipse(x, y, radius*2, radius*2);
	//stroke(255);
	//line(x, y, nx, ny);
	ofSetColor(0x000000);
	ofEllipse(x, y, radius*2, radius*2);
	ofSetColor(0xFFFFFF);
	ofLine(x, y, nx, ny);
}
Тут всё просто. Делаем все данные и методы публичными, добавляем конструктор и деструктор.
Присваивание значений переменным выносим в инициализацию конструктора.
Более важные изменения вносятся в метод display(). Функции рисования Processing необходимо заменить на соответствующие функции OpenFrameworks-а.
Переходим к функции начальной установки setup():
float gravity = 6.0;
float mass = 2.0;
void setup() 
{
  size(200, 200);
  smooth();
  fill(0);
  // Inputs: x, y, mass, gravity
  s1 = new Spring2D(0.0, width/2, mass, gravity);
  s2 = new Spring2D(0.0, width/2, mass, gravity);
}
и просто переносим данный код в аналогичный метод:
void testApp::setup(){
	width = 200;
	height = 200;
	//--------------------------
	gravity = 6.0;
	mass = 2.0;
	//size(200, 200);
	ofSetWindowShape(200, 200); // размер окна
	//smooth();
	ofEnableSmoothing();
	//fill(0);
	ofBackground(0, 0, 0); // чёрный фон
	
	// Inputs: x, y, mass, gravity
	s1 = new Spring2D(0.0, width/2, mass, gravity);
	s2 = new Spring2D(0.0, width/2, mass, gravity);
	//------------------------
	//lets make our circles look a little nicer!
	ofSetCircleResolution(50);
	
	ofSetVerticalSync(true);
	ofSetFrameRate(50);
	mouseX=0;
	mouseY=0;
	mouseClickX=0;
	mouseClickY=0;
}
В класс testApp необходимо добавить переменные width и height для хранения размеров окна. А так же переменные mouseX и mouseY, которые понадобятся в методе draw() и которые содержат текущие координаты указателя мышки:
void testApp::mouseMoved(int x, int y ){
	printf("[i][mouseMoved] x: %d y: %d\n", x, y);
	mouseX=x;
	mouseY=y;
}
Осталось переписать функцию
void draw() 
{
  background(204);
  s1.update(mouseX, mouseY);
  s1.display(mouseX, mouseY);
  s2.update(s1.x, s1.y);
  s2.display(s1.x, s1.y);
}
в одноимённом методе
void testApp::draw(){
	//background(204);
	ofBackground(204, 204, 204); // серый фон
	//s1.update(mouseX, mouseY);
	//s1.display(mouseX, mouseY);
	//s2.update(s1.x, s1.y);
	//s2.display(s1.x, s1.y);
	if(s1){
		s1->update(mouseX, mouseY);
		s1->display(mouseX, mouseY);
	}
	if(s2){
		s2->update(s1->x, s1->y);
		s2->display(s1->x, s1->y);
	}
}
Вот и всё! Вот что получилось:

Скачать программу + исходники. (1.9 Mb)
Для запуска программы, в каталоге bin должны находиться все требуемые dll-библиотеки.
Вывод:
openFrameworks ещё доволно молод и по сравнению с Processing-ом многих простых функций ему ещё очень не хватает. Но его простота и прозрачность — это замечательный плюс, который позволяет программировать на С++ захватывающие графические и интерактивные приложения.
Ссылки
http://thomas-gerhardt.com/itp/2008/04/03/open-frameworks-vs-processing/



0 комментариев на «“openFrameworks vs Processing”»
— хорошая статейка (и предыдущая о openFrameworks), очень меня заинтересовала эта библиотека, буду изучать! =)
усехов 🙂 можно начать с перевода скетчей Processing-а 😉