39
Разработка интерактивных систем на OpenFrameworks Двумерная графика УрГУ / ИММ весна 2011 лекции и объявления: www.uralvision.blogspot.com вопросы по проектам и программированию: [email protected]

OpenFrameworks: 2d-графика

Embed Size (px)

DESCRIPTION

Двумерная графика в OpenFrameworks, рисование фигур, изображения, прозрачность, экранный буфер. Creative Coding, Generative Art.

Citation preview

Page 1: OpenFrameworks: 2d-графика

Разработка интерактивных систем на OpenFrameworks

Двумерная графика

УрГУ / ИММ весна 2011

лекции и объявления: www.uralvision.blogspot.com

вопросы по проектам и программированию: [email protected]

Page 2: OpenFrameworks: 2d-графика

Настройка экрана

в main.cpp:

ofSetupOpenGL(&window, 1024,768, OF_WINDOW);

1024, 768 - размеры экрана, OF_WINDOW - вывод в окно.

Чтобы вывести на полный экран в 1280x1024:

ofSetupOpenGL(&window, 1280,768, OF_FULLSCREEN);

Page 3: OpenFrameworks: 2d-графика

Настройка экрана

Переключение между полноэкранным режимом в ходе работы программы (в update()) :ofSetFullscreen(bool fullscreen) Пример: по нажатию '1'/'2' - вкл/выкл полноэкранный режим: void testApp::keyPressed(int key){ if ( key == '1' ) { ofSetFullscreen( true ); } if ( key == '2' ) { ofSetFullscreen( false ); }}

Page 4: OpenFrameworks: 2d-графика

Настройка фона

ofBackground(int r, int g, int b) устанавливает цвет фона (по умолчанию 128, 128, 128).Примечание: надо ставить в setup(), если включен ofSetBackgroundAuto. ofSetBackgroundAuto(bool bAuto) - включает/выключает режим очистки картинки в каждом кадре, перед вызовом draw() (по умолчанию true).

Page 5: OpenFrameworks: 2d-графика

Рисование фигурЛиния ofLine(float x1, float y1, float x2, float y2)

Прямоугольник ofRect(float x1, float y1, float w, float h)

Круг ofCircle(float x, float y, float radius)

Треугольник ofTriangle(float x1, float y1, float x2, float y2, float x3, float y3)

Эллипс ofEllipse

Многоугольник ofBeginShape(), ofVertex(), ofEndShape()

Гладкая кривая ofCurve

Page 6: OpenFrameworks: 2d-графика

Рисование фигурНастройки: Цвет рисования ofSetColor(int red, int greeb, int blue), где числа от 0 до 255. ofSetColor(int red, int green, int blue, int alpha ) /*alpha - прозрачность, см. далее*/ ofSetColor(int hexColor) - 16-чная задание цвета, Толщина линий ofSetLineWidth(float lineWidth) толщина линий в пикселах

Заливать/не заливать фигуры ofFill() - заливать ofNoFill() - не заливать

Page 7: OpenFrameworks: 2d-графика

Вывод текста- Простой вывод текста, без настроек шрифта и размера: ofDrawBitmapString("Some text", 50, 50 ); //параметры: текст и координаты - Для вывода нормальным шрифтом и размером - использовать ofTrueTypeFont:

1) скопировать в bin/data шрифт, например, verdana.ttf (есть в папке openframeworks) 2) объявить: ofTrueTypeFont myFont; 3) в setup(): myFont.loadFont("verdana.ttf", 32 /*размер*/); 4) в draw(): myFont.drawString("Good", 50, 50); - Вывод в текстовое окно консоли:cout << "Text" << endl;

Page 8: OpenFrameworks: 2d-графика

Пример

Это то, что называется "генерируемое искусство" (generative art) и "творческое программирование" (creative coding)

Page 9: OpenFrameworks: 2d-графика

Пример

Объявление переменных float px; //начало линии float py; float qx; //отступ float qy; float col; //цвет

setup() ofBackground( 255, 255, 255 ); ofSetBackgroundAuto( false ); px = 320; py = 240; qx = 0; qy = 0; col = 0;

Page 10: OpenFrameworks: 2d-графика

Примерupdate() px += ofRandom( -1, 1 ); //ofRandom(a,b) - случайная велечина в [a,b] py += ofRandom( -1, 1 ); qx += ofRandom( -0.3, 0.3 ); qy += ofRandom( -0.3, 0.3 );

if ( px < 0 ) px += 640; if ( px >= 640 ) px -= 640; if ( py < 0 ) py += 480; if ( py >= 480 ) py -= 480;

if ( qx < -30 ) qx += 15; if ( qx > 30 ) qx -= 15; if ( qy < -30 ) qy += 15; if ( qy > 30 ) qy -= 15;

col += 0.02; if ( col >= 256 ) col = col - 256;

Page 11: OpenFrameworks: 2d-графика

Примерdraw() int r = col; int g = int(col * 2) % 256; int b = 255 - col; ofSetColor( r, g, b ); ofLine( px, py, px + qx, py + qy );

Page 12: OpenFrameworks: 2d-графика

Рисование изображений

Page 13: OpenFrameworks: 2d-графика

КоллажКоллаж (от фр. collage — наклеивание) — технический приём в изобразительном искусстве, заключающийся в наклеивании на подложку предметов и материалов, отличающихся от основы по цвету и фактуре. Коллажем также называется произведение, целиком выполненное в этой технике. (Википедия) А здесь мы будем под коллажом понимать размещение различных картинок на экране.

Для коллажа нужно: - загрузить набор картинок,осуществить их - вращение, - перенос, - изменение размера,- прозрачность. http://www.chinesecontemporary.com/hong_hao_5.htm

Page 14: OpenFrameworks: 2d-графика

Загрузка и рисование изображенияобъявление картинкиofImage image;

в setup()image.loadImage( "texture.jpg" ); //загрузка с диска //файл должен лежать в bin/data

в draw()ofSetColor( 255, 255, 255 ); //зачем это нужно - см. ниже //"Прозрачность всего изображения"image.draw ( 100.0, 50.0 ); //вывод на экран //левый верхний угол будет в (100, 50) Это изображение можно скачать с http://uralvision.blogspot.com/2010/03/4.htmlИсходное изображение было взято с http://ayesha5.files.wordpress.com/2008/06/sun-flower2.jpg

Page 15: OpenFrameworks: 2d-графика

Поворот изображенияв draw() ofPushMatrix(); //запомнить матрицу преобразования ofRotate( 10.0 ); //поворот в градусах левого верх. угла image.draw( 0.0, 0.0 ); //рисуемofPopMatrix(); //восстановить матрицу

Page 16: OpenFrameworks: 2d-графика

Вращение около своего центрав draw() //Рисуем повернутым, и чтоб центр был в ( 200.0, 100.0 ) ofPushMatrix(); ofTranslate( 200.0, 100.0 ); //центр картинки ofRotate( 20.0 ); //поворот //рисование со сдвигом: image.draw( -image.width / 2, -image.height / 2 ); ofPopMatrix();

Page 17: OpenFrameworks: 2d-графика

Прозрачность

Page 18: OpenFrameworks: 2d-графика

Прозрачность для пикселовЧтобы сделать хороший коллаж из нескольких картинок, нужно убрать черный фон. Это делается путем использования прозрачности для пикселов изображения.

Page 19: OpenFrameworks: 2d-графика

Применение прозрачности для пикселов изображенияЕсли к каналам Red, Green, Blue добавить канал Alpha, то можно задавать прозрачность пикселов. Alpha = 0 - пиксел прозрачен и невидим,Alpha = 255 - пиксел полностью непрозрачен.То есть можно просто вырезать фон.

Page 20: OpenFrameworks: 2d-графика

Схема смешивания цветов при прозрачностиОбычно данные о прозрачности хранятся в виде параметра "alpha". Это "непрозрачность". Если значение alpha фрагмента в [0, 1] (то есть alpha = Alpha / 255.0)то старый цвет C0 смешивается с цветом фрагмента C1 по формуле R = (1-alpha) * R0 + alpha * R1G = (1-alpha) * G0 + alpha * G1B = (1-alpha) * B0 + alpha * B1

Если alpha = 0 - новый цвет равен просто старому C0.Если alpha = 1 - новый цвет равен цвету фрагмента C1.При промежуточных значениях - происходит смешивание цветов.

Если несколько объектов накладываются - процедура выполняется последовательно, от дальнего к ближнему.

Page 21: OpenFrameworks: 2d-графика

Схема смешивания цветов при прозрачностиКрасный квадрат накладываем на черный, белый и синий цвет.Накладываем три раза, с alpha: 0.3, 0.6, 1.0.

Page 22: OpenFrameworks: 2d-графика

Способы получения изображений с вырезанным фоном 1. из векторного редактора 2. "умным" выделением краев в Photoshop или Gimp 3. вручную - плохое качество (алиасинг-рваные края)!

Page 23: OpenFrameworks: 2d-графика

Форматы картинок, хранящие прозрачность1. Форматы, позволяющие хранить прозрачностьpng-24 - наилучший по качеству / размеру / скорости распаковкиbmp-32, tiff, tga.2. Форматы, которые хранят прозрачность 1-битовую (рваные края):gif, png-8.

3. Не хранит прозрачность в принципе: jpg.

Page 24: OpenFrameworks: 2d-графика

Пример: вращающиеся подсолнухи

//Объявление переменных ofImage image; //картинкаfloat angle = 0.0; //угол вращения //Инициализация void testApp::setup(){ image.loadImage( "texture.png" ); //png - с прозрачностью angle = 0.0;}

//Обновление состоянияvoid testApp::update(){ angle += 0.1; //поворот}

Page 25: OpenFrameworks: 2d-графика

Пример: вращающиеся подсолнухи//Рисованиеvoid testApp::draw(){ //включить режим прозрачности ofEnableAlphaBlending(); //2-й вариант, с точным указанием функции для прозрачности: //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

for (int i=0; i<5; i++) { ofPushMatrix(); ofTranslate( 300.0 + i * 100.0, 300.0 ); //перенос ofRotate( angle ); //вращение ofScale( 1.0 + 0.2 * i, 1.0 + 0.2 * i ); //увеличение размера image.draw( -image.width / 2, -image.height / 2 ); ofPopMatrix(); } ofDisableAlphaBlending(); //выключение режима прозрачности //glDisable(GL_BLEND);}

Page 26: OpenFrameworks: 2d-графика

Прозрачность всего изображенияТакже для коллажей часто используют прозрачность для всего изображения (слоя). На картинке показан коллаж, где некоторые подсолнухи наложены с прозрачностью. А у двух подсолнухов к тому же сделана полная прозрачность (т.е. невидимы) соответственно Red, Blue и Green, Blue каналы.

Page 27: OpenFrameworks: 2d-графика

Прозрачность всего изображения- это реализуется путем установки цвета ofSetColor( r, g, b, a), перед рисованием изображения.Дело в том, что изображения рисуются с попиксельным умножением на компоненты текущего цвета, что условно можно записать так: R = r / 255.0 *R0G = g / 255.0 *G0B = b / 255.0 * B0A = a / 255.0 * A0 Поэтому-то, чтобы вывести изображение без изменений, используется ofSetColor(255, 255, 255) перед рисованием изображения.

Внимание: если стоял черный цвет, то изображение будет невидимым. Это довольно часто встречающаяся "проблема"!

Page 28: OpenFrameworks: 2d-графика

Прозрачность всего изображения//Рисованиеvoid testApp::draw(){ float w = image.width; float h = image.height; ofBackground(0, 0, 0); //задаем цвет фона ofEnableAlphaBlending(); //включение прозрачности

//текущий цвет влияет на выводимую текстуру //а именно, текстура поканально умножается на R,G,B компоненты //цвета и еще учитывается его прозрачность ofSetColor( 255, 255, 255 ); //непрозрачно image.draw( w, h );

ofSetColor( 255, 255, 255, 128 ); //полупрозрачно image.draw( w/2, h/2 );

ofSetColor( 0, 255, 0, 128 ); //полупрозрачно, только зеленый канал image.draw( w/2, h + h/2 ); ofDisableAlphaBlending(); //выключение прозрачности}

Page 29: OpenFrameworks: 2d-графика

Результат

Page 30: OpenFrameworks: 2d-графика

Рисование в буфер

Page 31: OpenFrameworks: 2d-графика

Как нарисовать путь движения маятникаЗадача: в проект с качающимся маятником добавить, чтобы рисовалось, где побывал центр маятника. То есть как будто в маятнике в центре стоит карандаш, который чертит на бумаге.

Как это сделать? Если запоминать траекторию в виде ломаной и каждый раз ее выводить на экран - постепенно программа будет работать все медленней.Лучший способ решения - рисовать траекторию маятника в некоторый буфер вне экрана, а потом выдавать содержимое буфера на экран.

Этот буфер - как бы экран, который мы не видим. В отличие от экрана, буфер не будет чиститься при каждом рисовании экрана.

FBO - Frame Buffer Object

В такой буфер можно рисовать как на экране, а затем использовать результат как текстуру - т.е. выводить ее а экран или рисовать ей в других буферах.Можно делать сложные многослойные изображения, позволяющие делать эффекты типа "следа" от движущихся объектов. Для этого нужно рисовать один буфер в другом с разной прозрачностью.

Page 32: OpenFrameworks: 2d-графика

Как нарисовать путь движения маятникаТогда алгоритм рисования в draw() будет такой: 1. в буфере рисуется прямая, соединяющая текущее положение маятника с предыдущим, 2. буфер выводится на экран3. на экране рисуется сам маятник

Page 33: OpenFrameworks: 2d-графика

Работа с буфером рисования

Для работы с буфером рисования в OpenFrameworks лучше всего использовать аддон ofxFBOTexture.

Он состоит из двух файлов - ofxFBOTexture.h и ofxFBOTexture.cpp.http://addons.openframeworks.cc/projects/list_files/ofxfbotexture

Эти файлы нужно добавить в проект, например, так:1. Скопировать их в src проекта2. в VisualStudio ткнуть правой кнопкой по проекту, в меню - Add Existing Items и добавить их оба.

Правильней копировать все аддоны в папку openframeworks/addons, но это может быть неудобно, если проект должен быть мобильным, то есть собираться на разных компьютерах.

Page 34: OpenFrameworks: 2d-графика

Работа с буфером рисования

... #include "ofxFBOTexture.h" ...ofxFBOTexture buffer; //буфер для рисования вне экрана

в setup() //создание буфера buffer.allocate( ofGetWidth(), ofGetHeight(), false //без автоочистки при каждом рисовании - т.к. будем там накапливать картинки );

buffer.clear( 0, 0, 0, 255 ); //очистка черным цветом

//нужно заметить, что если ставить не черный цвет, то буфер может окраситься в первый используемый вами цвет. Как устранить проблему?

Page 35: OpenFrameworks: 2d-графика

Работа с буфером рисования

в draw() buffer.begin(); //начало рисования в буфер

// процедуры рисования в буфер - оформляется так же, как на экран ... ofSetColor, ofLine, ...

buffer.end(); //конец рисования в буфер buffer.draw( 0, 0 ); //вывод буфера на экран

// остальное рисование ...

В этом случае процедуры рисования в буфер будут оставаться от кадра к кадру (путь: который прошел маятник), а процедуры остального рисования - показываться только в одном кадре (сам маятник с резинкой).

Page 36: OpenFrameworks: 2d-графика

Домашнее задание (*)

Нарисовать многоугольник, заполненный (текстурированный) некоторым изображением.

Подсказка. Схема вызова функций: ofTexture tex = image.getTextureReference();tex.bind();glBegin( GL_QUADS ); glTexCoord2f(...) glVertex2f(...) ...glEnd();tex.unbind();

Page 37: OpenFrameworks: 2d-графика

Приложение:Запись видео работающей программы и публикация

Page 38: OpenFrameworks: 2d-графика

Захват видео с экранаПрограмма CamStudio - бесплатная программа для захвата изображений с экрана и записи в видеофайл. http://camstudio.org При больших размерах захватываемой области скорость захвата может весьма низкой. Не забывайте при съемке вашего проекта установить режим Release, а не Debug.

Лучше использовать кодек CamStudio Lossless codec, он достаточно быстрый и не портит изображение. Но файлы получаются большого размера. Поэтому, перед публикацией, лучше конвертировать файл с помощью программы VirtualDub в другой кодек, например, XVID.

Page 39: OpenFrameworks: 2d-графика

Публикация видеороликаГде публиковать: Youtube, Vimeo. Youtube - наиболее распространен, интегрирован во многие блоги; просматривается на устройствах iOS. Vimeo - качество видео превосходит Youtube, поэтому профессиональные работы публикуют часто одновременно и тут, и на Youtube.