====== Atelier OpenFrameworks ====== Atelier donné au Fablab LFO pour les [[http://reso-nance.org/lfo/article8/week-end-fablab|week-ends fablabs]], les 14 et 15 mars 2015. **Tous les fichiers (25 Mo) : {{:logiciels:openframeworks:atelier:ofatelier.zip|}}** ===== Fichiers ===== Pour commencer, il faut trois fichiers : main.cpp, ofApp.h et ofApp.cpp. Ces fichiers sont générés par le //ProjectGenerator//. ++++ main.cpp | #include "ofMain.h" #include "ofApp.h" int main( ){ ofSetupOpenGL(700,700,OF_WINDOW); ofRunApp(new ofApp()); } ++++ ++++ 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); voi mouseReleased(int x, int y, int button); void windowResized(int w, int h); void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); }; ++++ ===== Cours 1 - premiers dessins ===== {{:logiciels:openframeworks:atelier:cours01.png?200|}} ++++ ofApp.cpp | #include "ofApp.h" int myCircleX = 250; int myCircleY = 100; int myCircleRadius = 50; int red = 255; bool bg = true; void ofApp::setup(){ ofSetRectMode(OF_RECTMODE_CENTER); } void ofApp::update(){ } void ofApp::draw(){ if (bg) ofBackground(0); ofSetColor(255); ofNoFill(); ofRect(100, 100, 100, 100); ofFill(); ofSetColor(red, 255, 255); ofCircle(myCircleX, myCircleY, myCircleRadius); ofSetColor(255); ofNoFill(); ofEllipse(400, 100, 80, 100); ofTriangle(500, 150, 550, 50, 600, 150); ofLine(700, 50, 700, 150); if (ofGetMousePressed(OF_MOUSE_BUTTON_LEFT)) { ofFill(); float randomColor = ofRandom(50, 255); ofSetColor(randomColor); ofRect(ofGetMouseX(), ofGetMouseY(), 50, 50); } if (ofGetMousePressed(OF_MOUSE_BUTTON_RIGHT)) { bg = !bg; ofSetBackgroundAuto(bg); } } void ofApp::keyPressed(int key){ if (key == 's') { glReadBuffer(GL_FRONT); // HACK: only needed on windows ofSetAutoBackground(false) ofSaveScreen("savedScreenshot_"+ofGetTimestampString()+".png"); } } void ofApp::mouseMoved(int x, int y ){ float distance = ofDist(myCircleX, myCircleY, x, y); if(distance < myCircleRadius){ red=0; } else { red=255; } } void ofApp::mousePressed(int x, int y, int button){ float distance = ofDist(myCircleX, myCircleY, x, y); if(distance < myCircleRadius){ myCircleRadius=myCircleRadius*1.1; } } ++++ ===== Cours 2 : pinceau ===== {{:logiciels:openframeworks:atelier:01.png?200|}} ++++ ofApp.cpp | // From Fleeing Triangle Brush : ofBook (https://github.com/openframeworks/ofBook). // Copyright (c) 2014 Michael Hadley, mikewesthad.com #include "ofApp.h" void ofApp::setup(){ ofSetFrameRate(60); ofSetBackgroundAuto(false); ofBackground(0); } void ofApp::update(){ } void ofApp::draw(){ if (ofGetMousePressed(OF_MOUSE_BUTTON_LEFT)) { int numTriangles = 10; int minOffset = 5; int maxOffset = 70; int alpha = 150; for (int t=0; t ++++ ===== Cours 3 : tableau, matrice ===== {{:logiciels:openframeworks:atelier:02d.png?200|}} ++++ ofApp.cpp | #include "ofApp.h" int ROWS; int COLS; int posX; int posY; float percent; float GRIDX; float GRIDY; float dx, dy; float angle; ofVec2f p1; ofVec2f p2; void ofApp::setup(){ ofBackground(0); ofSetFrameRate(30); ROWS = 80; COLS = ROWS; GRIDX = float(ofGetScreenWidth() / COLS); GRIDY = float(ofGetScreenHeight() / ROWS); ofSetLineWidth(2); percent=1; p1.set(0, -GRIDY*percent); p2.set(0, GRIDY*percent); } void ofApp::update(){ } void ofApp::draw(){ for (int rows=0; rows ++++ {{:logiciels:openframeworks:atelier:cours02.png?200|}} ++++ ofApp.cpp | #include "ofApp.h" #define NUM_CIRCLES 500 float circleX[NUM_CIRCLES]; float circleY[NUM_CIRCLES]; float circleRad[NUM_CIRCLES]; int circleR[NUM_CIRCLES]; int circleG[NUM_CIRCLES]; int circleB[NUM_CIRCLES]; void ofApp::setup(){ ofSetFrameRate(24); for(int i=0; i ++++ ===== Cours 4 : objets ===== {{:logiciels:openframeworks:atelier:cours04.png?200|}} ++++ ofApp.h | #pragma once #include "ofMain.h" #include "ofBall.h" class ofApp : public ofBaseApp{ public: void setup(); void update(); void draw(); void keyPressed(int key); void mousePressed(int x, int y, int button); vector balls; }; ++++ ++++ ofApp.cpp | #include "ofApp.h" void ofApp::setup(){ for( int i = 0; i < 10; i=i+1){ balls.push_back(ofBall()); } ofBackground(255); } void ofApp::update(){ for( int i = 0; i < balls.size(); i=i+1){ balls[i].update(); } } void ofApp::draw(){ for( int i = 0; i < balls.size(); i=i+1){ balls[i].draw(); } } void ofApp::keyPressed(int key){ if (key == 's') { glReadBuffer(GL_FRONT); // HACK for windows ofSaveScreen("savedScreenshot_"+ofGetTimestampString()+".png"); } } void ofApp::mousePressed(int x, int y, int button){ balls.push_back(ofBall()); } ++++ ++++ ofBall.h | // ofBall.h // Created by rux on 3/31/14. #ifndef _OF_BALL #define _OF_BALL #include "ofMain.h" class ofBall { // place public functions or variables declarations here public: ofBall(); // constructor // methods, equivalent to specific functions of your class objects void update(); // update method, used to refresh your objects properties void draw(); // draw method, this where you'll do the object's drawing // variables float x; // position float y; float speedY; // speed and direction float speedX; int dim; // size ofColor color; private: // place private functions or variables declarations here }; // don't forget the semicolon!! #endif ++++ ++++ ofBall.cpp | #include "ofBall.h" ofBall::ofBall(){ x = ofRandom(0, ofGetWidth()); // give some random positioning y = ofRandom(0, ofGetHeight()); speedX = ofRandom(-10, 10); // and random speed and direction speedY = ofRandom(-10, 10); dim = ofRandom(5, 30);; color.set(ofRandom(255), ofRandom(255), ofRandom(255)); } void ofBall::update(){ if(x < 0 ){ x = 0; speedX *= -1; } else if(x > ofGetWidth()){ x = ofGetWidth(); speedX *= -1; } if(y < 0 ){ y = 0; speedY *= -1; } else if(y > ofGetHeight()){ y = ofGetHeight(); speedY *= -1; } x+=speedX; y+=speedY; } void ofBall::draw(){ ofSetColor(color); ofCircle(x, y, dim); } ++++ ===== Cours 5 : fichier ===== * Fichiers police et textes : {{:logiciels:openframeworks:atelier:data.zip|}} {{:logiciels:openframeworks:atelier:cours05.png?200|}} ++++ ofApp.h | #pragma once #include "ofMain.h" class ofApp : public ofBaseApp{ public: void setup(); void update(); void draw(); ofTrueTypeFont font; ofTTFCharacter ttfChar; float angle; vector words; vector positions; ofEasyCam camera; }; ++++ ++++ ofApp.cpp | #include "ofApp.h" void ofApp::setup(){ ofBackground(255,255,255); glEnable(GL_DEPTH_TEST); //glEnable(GL_BLEND); //glBlendFunc(GL_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glAlphaFunc(GL_GREATER, 0.5) ; glEnable(GL_ALPHA_TEST) ; font.loadFont("Batang.ttf", 24, true, true, true); ttfChar = font.getCharacterAsPoints('C'); ofSetFullscreen(false); angle = 0.0; // Fichier de mots ifstream infile; infile.open("./data/miserables.txt"); if (!infile) cout << "can't open file" << endl; string w; while (infile >> w) { words.push_back(w); positions.push_back(ofPoint(ofRandom(0,700)-350, ofRandom(0,700)-350, ofRandom(0,700)-350)); } } void ofApp::update(){ // Brownian motion for (int i = 0; i < words.size(); i++) { positions[i].x += ofRandom(-1,1); positions[i].y += ofRandom(-1,1); } } bool wordIsTooHip(string w) { if (w == "a") return true; // caractère en rouge else return false; } void ofApp::draw(){ ofFill(); camera.begin(); ofPushMatrix(); for (int i = 0; i< words.size(); i=i+1) { ofPushMatrix(); ofTranslate(positions[i]); if ( wordIsTooHip(words[i]) ) ofSetColor(255,0,0); else ofSetColor(0,0,0); font.drawString(words[i], 0.0, 0.0); ofPopMatrix(); } ofPopMatrix(); camera.end(); } ++++ ===== Cours 6 : Mesh ===== * Fichier image : {{:logiciels:openframeworks:atelier:stars.png?linkonly|}} {{:logiciels:openframeworks:atelier:05b.png?200|}} ++++ ofApp.h | // from http://www.openframeworks.cc/tutorials/graphics/generativemesh.html #pragma once #include "ofMain.h" class ofApp : public ofBaseApp{ public: void setup(); void update(); void draw(); ofMesh mesh; ofImage image; ofEasyCam easyCam; vector offsets; }; ++++ ++++ ofApp.cpp | #include "ofApp.h" void ofApp::setup(){ ofSetFrameRate(60); image.loadImage("stars.png"); image.resize(200, 200); // car trop de sommets ~ 64000 mesh.setMode(OF_PRIMITIVE_LINES); //OF_PRIMITIVE_POINTS ou OF_PRIMITIVE_LINES float intensityThreshold = 150.0; int w = image.getWidth(); int h = image.getHeight(); for (int x=0; x= intensityThreshold) { float saturation = c.getSaturation(); float z = ofMap(saturation, 0, 255, -100, 100); // We shrunk our image by a factor of 4, so we need to multiply our pixel // locations by 4 in order to have our mesh cover the openFrameworks window ofVec3f pos(4*x, 4*y, z); //ofVec3f pos(x, y, 0.0); mesh.addVertex(pos); mesh.addColor(c); // It will create a ofVec3f with 3 random values // These will allow us to move the x, y and z coordinates of each vertex independently offsets.push_back(ofVec3f(ofRandom(0,100), ofRandom(0,100), ofRandom(0,100))); } } } //cout << mesh.getNumVertices() << endl; // Let's add some lines! float connectionDistance = 30; int numVerts = mesh.getNumVertices(); for (int a=0; a ++++ ===== Cours 7 : vidéo ASCII ===== * Fichier police à mettre dans "data" : {{:logiciels:openframeworks:atelier:courriernewbold.zip|}} {{:logiciels:openframeworks:atelier:06a.png?200|}} ++++ ofApp.h | #pragma once #include "ofMain.h" class ofApp : public ofBaseApp{ public: void setup(); void update(); void draw(); void keyPressed(int key); ofVideoGrabber vidGrabber; int camWidth; int camHeight; string asciiCharacters; ofTrueTypeFont font; }; ++++ ++++ ofApp.cpp | #include "ofApp.h" void ofApp::setup(){ ofBackground(0,0,0); ofSetFrameRate(60); ofEnableAlphaBlending(); camWidth = 640; // try to grab at this size. camHeight = 480; vidGrabber.setVerbose(true); vidGrabber.initGrabber(camWidth,camHeight); font.loadFont("Courier New Bold.ttf", 9); //this set of characters comes from processing: //http://processing.org/learning/library/asciivideo.html //changed order slightly to work better for mapping asciiCharacters = string(" ..,,,'''``--_:;^^**""=+<>iv%&xclrs)/){}I?!][1taeo7zjLunT#@JCwfy325Fp6mqSghVd4EgXPGZbYkOA8U$KHDBWNMR0Q"); } void ofApp::update(){ vidGrabber.update(); } void ofApp::draw(){ // change background video alpha value based on the mouse position // float videoAlphaValue = ofMap(mouseX, 0,ofGetWidth(),0,255); // ofSetColor(255,255,255,videoAlphaValue); // vidGrabber.draw(0,0); ofPixelsRef pixelsRef = vidGrabber.getPixelsRef(); ofSetHexColor(0xffffff); for (int i = 0; i < camWidth; i+= 7){ for (int j = 0; j < camHeight; j+= 9){ // get the pixel and its lightness (lightness is the average of its RGB values) float lightness = pixelsRef.getColor(i,j).getLightness(); // calculate the index of the character from our asciiCharacters array int character = powf( ofMap(lightness, 0, 255, 0, 1), 2.5) * asciiCharacters.size(); // draw the character at the correct location font.drawString(ofToString(asciiCharacters[character]), i, j); } } } void ofApp::keyPressed (int key){ // in fullscreen mode, on a pc at least, the // first time video settings the come up // they come up *under* the fullscreen window // use alt-tab to navigate to the settings // window. we are working on a fix for this... if (key == 's' || key == 'S'){ vidGrabber.videoSettings(); } } ++++