article search result of 'C++(oF)' : 55

  1. 2017.02.24 비연결형 소켓 OF (C++) 편
  2. 2017.02.24 Generic Singleton Base Class
  3. 2016.09.01 중국어 , 한국어 완벽지원 addon , ofxFontStash
  4. 2016.08.27 Visual Studio 2015 에서 Icon 바꾸기
  5. 2016.07.31 libVLC 를 이용한 캡처장치 수신
  6. 2016.07.29 보다 높은 퍼포먼스를 위한 LIBVLC 사용
  7. 2016.07.10 Poco 를 이용한 날짜 계산
  8. 2016.07.09 [of] LIB VLC 사용하기
  9. 2016.06.18 Blur쉐이더 , Desktop 용
  10. 2016.06.18 Desktop 과 IOS(openGLES2.0) 의 쉐이더 텍스처 기본 시작 코드
  11. 2016.04.16 [IOS] 아이폰의 카메라 기능을 모두 사용 하기
  12. 2016.04.14 CLM Framework with (TBB) on openFrameworks
  13. 2016.04.11 간단한 다각형의 HitTest
  14. 2016.04.06 [초간단] OF윈도우 리사이즈 막기
  15. 2016.04.02 OF로 만든 VR 비디오 뷰어.
  16. 2016.03.20 ARToolkit5 새로운 패턴 적용 하기
  17. 2016.03.18 OF를 유틸리티 프로그램으로 사용하기
  18. 2016.03.18 [OF] Visual Studio 2015 Community 에서 Icon 바꾸기
  19. 2016.02.25 ofDrawBitamp(...) 의 텍스트 렌더링 사이즈 알아내기
  20. 2016.02.16 openFrameWorks 에서 FFMPEG 사용하기 :: 준비단계
  21. 2016.02.11 ofXml 간단 사용법
  22. 2016.01.25 InClass GLSL Shader , 클래스 코드 안에 쉐이더 코드를...
  23. 2016.01.24 In Class Static 와 Singleton
  24. 2016.01.14 람다 콜백 , std::function<void()> 이용한 DelayCall
  25. 2016.01.13 ofEvents() 이벤트 우선순위
  26. 2016.01.08 ofxTrueTypeFontUC 를 이용한 한글 출력 (0.9.0)
  27. 2015.08.03 [작성중] FTGL 과 한글Automata 를 이용한 한글입력
  28. 2015.07.20 oF 에서 FTGL 을 통한 한글 출력
  29. 2015.06.14 Xcode 에서 Homebrew 를 통해 OpenCv 설치 하기
  30. 2015.06.03 [OpenCv] Static 으로 빌드하여 배포 환경에 맞추기. (별도의 DLL 필요없음)

비연결형 소켓 OF (C++) 편


총 3개의 Layer로 구성됨

16 byte    : 머신, 혹은 App 을 구별할 GUID(UUID)
1  byte     : 0 ~ 255 까지의 message type 분류
data bytes : 실제 데이터  



* c# 용 비연결형 udp 소켓은 ( http://yamecoder.tistory.com/367 )


Communicaotr.h 싱글톤 Singleton<T> 는 ( http://yamecoder.tistory.com/368 )

#pragma once

/**
* [ Udp Communicator ]
*
* @author  yamecoder
* @version 17/02/24
*/


#include "Singleton.h"
#include "ofxNetwork.h"
#include "ofMain.h"

class Communicator : public Singleton<Communicator> , ofThread
{
public:
    const static char data_type_json = 0;
    const static char data_type_vec2 = 1;
    const static char data_type_text = 2;

private:
    bool is_setup = false;
    char* byte_id;
    ofxUDPManager udp_listener;
    ofxUDPManager udp_sender;
    
    char* buf_received_data;
    int buf_received_data_len = 10000;
    int byte_position = 0;

public:
    Communicator();
    ~Communicator();

    void Setup();

    void Send(char message_type, string str);

private:
    char* GenGuid();
    void threadedFunction();
    char* readData(int size);
};




ㅁㅁㅁ

Communicaotr.cpp

/**
* [ Udp Communicator ]
* 
* @author  yamecoder 
* @version 17/02/24
*/


#include "Communicator.h"
#include <objbase.h>

Communicator::Communicator()
{
    
}

Communicator::~Communicator()
{
}

void Communicator::Setup()
{
    if (is_setup == true)
        return;
    is_setup = true;

    byte_id = GenGuid();
    buf_received_data = new char[buf_received_data_len];

    //setup udp
    udp_listener.Create();
    udp_listener.BindMcast("224.0.0.0", 9999);
    
    udp_sender.Create();
    udp_sender.ConnectMcast("224.0.0.0", 9999);


    startThread();
}

void Communicator::Send(char message_type , string str)
{
    vector<char> data;
    for (size_t i = 0; i < 16; i++)
    {
        data.push_back(byte_id[i]);                 // insert byte_id(guid) of this machine
    }

    data.push_back(message_type);                   // insert message type (0 ~ 255 , 1byte)

    for (size_t i = 0; i < str.length(); i++)
    {
        data.push_back(str.c_str()[i]);             // insert message bytes
    }
    
    udp_sender.Send(&data[0], data.size());
}

char* Communicator::GenGuid()
{
    char* n_id = new char[16];

    GUID newId;
    HRESULT hr = CoCreateGuid(&newId);
    char* re_id = reinterpret_cast<char*>(&newId.Data4[0]);

    if (SUCCEEDED(hr))
    {
        char raw_id[16]
        {
            (newId.Data1 >> 24) & 0xFF,
            (newId.Data1 >> 16) & 0xFF,
            (newId.Data1 >> 8) & 0xFF,
            (newId.Data1) & 0xff,

            (newId.Data2 >> 8) & 0xFF,
            (newId.Data2) & 0xff,

            (newId.Data3 >> 8) & 0xFF,
            (newId.Data3) & 0xFF,

            (char)newId.Data4[0],
            (char)newId.Data4[1],
            (char)newId.Data4[2],
            (char)newId.Data4[3],
            (char)newId.Data4[4],
            (char)newId.Data4[5],
            (char)newId.Data4[6],
            (char)newId.Data4[7]
        };
        memcpy(n_id, raw_id, 16);

    }
    else
    {
        n_id = new char[16];
        for (size_t i = 0; i < 16; i++)
        {
            n_id[i] = char(i);
        }
    }
    

    return n_id;
}


void Communicator::threadedFunction()
{
    cout << "started !" << endl;
    while (isThreadRunning())
    {
        //wait
        udp_listener.Receive(buf_received_data, buf_received_data_len);
        
        //start read
        byte_position = 0;

        //read 16 bytes for sender guid.
        char* sender_id = readData(16);

        // check reflection
        bool check_myself = memcmp(sender_id, byte_id, 16);

        //release mem
        delete[] sender_id;
        
        if (check_myself != false)
        {
            char* type = readData(1);
            char* str = readData(buf_received_data_len - byte_position);




            // your code.
            if (type[0] == data_type_text)
            {

            }
            else if (type[0] == data_type_json)
            {

            }
            else if (type[0] == data_type_vec2)
            {

            }
            cout << str << endl;
            // end your code





            //release mem
            delete[] type;
            delete[] str;

            //clear buffer mem
            fill_n(buf_received_data, buf_received_data_len, 0);
        }
        else {
            // cout << "relfected form this machine" << endl;
        }
        


    }
}

char* Communicator::readData(int size)
{
    char* data = new char[size];
    memcpy(data, buf_received_data + byte_position, size);
    byte_position += size;
    return data;
}




Yamecoder 야매코더_
C++(oF) 2017.02.24 11:13

Generic Singleton Base Class


출처 : http://vallista.tistory.com/entry/1-Singleton-Pattern-in-C



#pragma once

//http://vallista.tistory.com/entry/1-Singleton-Pattern-in-C

template < typename T >
class Singleton
{
protected:
    Singleton()
    {

    }
    virtual ~Singleton()
    {

    }

public:
    static T * GetInstance()
    {
        if (m_pInstance == nullptr)
        {
            m_pInstance = new T;
        }
        return m_pInstance;
    }

    static void DestoryInstance()
    {
        if (m_pInstance)
        {
            delete m_pInstance;
            m_pInstance = nullptr;
        }
    }

private:
    static T * m_pInstance;
};

template < typename T > T * Singleton<T>::m_pInstance;



간단 활용법

#include "Singleton.h" class Communicator : public Singleton<Communicator> { public: Communicator(); ~Communicator(); }



Yamecoder 야매코더_
C++(oF) 2017.02.24 11:04

중국어 , 한국어 완벽지원 addon , ofxFontStash

ofxFontStash

https://github.com/armadillu/ofxFontStash



예제를 보면 직접 코드에 중국어 등을 입력 하여 출력 하였지만, 

Visual C++ 2015 에서의 cpp 안에 직접 작성한 문자열이 UTF8을 정확히 읽지 못하는것으로 예상, 그래서 외부의 Txt을 불러와 랜더링을 하였다.


#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup() {

    //ofEnableAlphaBlending();
    ofSetVerticalSync(true);
    ofSetFrameRate(60);
    ofBackground(22, 22, 22, 255);

    unicodeFont.setup("Arial Unicode.ttf", //font file, ttf only
        1.0,                    //lineheight percent
        1024,                   //texture atlas dimension
        true,                   //create mipmaps of the font, useful to scale down the font at smaller sizes
        8,                  //texture atlas element padding, shouldbe >0 if using mipmaps otherwise
        4.0f                    //dpi scaleup, render textures @2x the reso
    );                  //lower res mipmaps wil bleed into each other

    unicodeFont.setLodBias(-1);

    ofFile f("text.txt" , ofFile::Mode::ReadOnly);
    ofBuffer buf = f.readToBuffer().getText();
    f.close();
    str = buf.getText();
}

void ofApp::update() {
}

//--------------------------------------------------------------
void ofApp::draw() {
    ofSetColor(255);
    unicodeFont.drawMultiLine(str, 30, 0, 30);
}




Hello.

한글테스트.

首先要拥有一个优酷帐号,

并申请加入视频云,点击这里注册优酷帐号

一个开发者帐号可以申请多个应用

(client_id),点击这里申请

应用自动生效,可作为开发和测试使用。

应用分为四个等级,普通、中级、

高级和合作级。升级后不同等级应用可

调用不同API。




영어, 한글, 중국어 모두 정상적으로 출력된다.


Yamecoder 야매코더_
C++(oF) 2016.09.01 22:13

Visual Studio 2015 에서 Icon 바꾸기



이미지 따라 하면 됨




1. http://icoconvert.com/image_to_icon_converter/




2.



3.



4.



5.



6.



7.



8.



9.



10.



11.



12.



13.



14.


Yamecoder 야매코더_
C++(oF) 2016.08.27 19:41

libVLC 를 이용한 캡처장치 수신

이전글 참고 : 

http://scripter.co.kr/354



 

aaa

위에 것은 캡처 카드를 수신 한 것이고, 

아래 것은 웹캠을 수신 한 것이다. 


libVlc 를 이용 하여 캡처장치를 열때, 약간의 딜레이가 발생 할 수 있는데, 원인은 바로 사운드 이다. 

사운드 장치를 none 으로 바꾸도록 설정 한 다음 이용 하면 레퍼런스 프로그램 수준으로 딜레이가 없어진다. 


코드 : https://github.com/jjongun/ofxAddons/tree/master/work_addons/ofxVlcDShowGrabber


[문제점]

1) 간혹 play 할때 에러가 난다.

2) ( 어플리케이션을 종료 하거나 할때 ) 장치가 간혹 잘 종료 되지 않아 다음 회차에 사용을 못할 경우가 있다.

Yamecoder 야매코더_
C++(oF) 2016.07.31 20:29

보다 높은 퍼포먼스를 위한 LIBVLC 사용




이전글 참고 : 

http://scripter.co.kr/354


기존에 작성되었던  https://github.com/jnakanojp/ofxVLCVideoPlayer 약간의 문제를 포함 하고 있었다. 


1. 불필요 하게 class가 2개 였다.

2. 컬러포멧은 RGBA, 즉 4바이트를 할당하게 하여 퍼포먼스에 문제가 있었다.

3. 다소 불필요한 thread lock, unlock 으로 인한 퍼포먼스 저하가 있었다( 어떤 낮은 시스템에서는 필요 할 수 있다. )


이점들을 해결 하여 새롭게 작성 하였다. 


https://github.com/jjongun/ofxAddons/tree/master/work_addons/ofxVlcMediaPlayer/src


아울러 발견된 사실은, 


1. libvlc.dll 에 따라 vlc 초기화 옵션중 작동을 하지 못하는 경우가 있다.

2. 위와 같이 성능을 최적화 시키고 thread를 충분히 할당 하면 4K 30fps 는 무난히 돌아 가나, 60fps 에는 다소 무리가 있다. 

테스트 대상 [ https://kodi.tv/media-samples/ ]



Yamecoder 야매코더_
C++(oF) 2016.07.29 08:33

Poco 를 이용한 날짜 계산

#include "ofApp.h"
#include "Poco\Timespan.h"
#include "Poco\DateTime.h"
using namespace Poco;
//--------------------------------------------------------------
void ofApp::setup(){

    Timespan _fewDays(3, 0, 0, 0, 0); // 3일 
    DateTime _today(2016,1,1);
    DateTime _before = _today - _fewDays;
    DateTime _ago = _today + _fewDays;

    cout << "today is  : " << _today.year() << "/" << _today.month() << "/" << _today.day() << endl;
    cout << "- 3 days  : " << _before.year() << "/" << _before.month() << "/" << _before.day() << endl;
    cout << "+ 3 days  : " << _ago.year() << "/" << _ago.month() << "/" << _ago.day() << endl;

    
    // 오늘로 날짜 리셋
    _today = DateTime(ofGetYear(), ofGetMonth(), ofGetDay()); 
    DateTime _olyrimpicDay(2018, 2, 9);
    Timespan dday = _olyrimpicDay - _today + 1; // 오늘 부터 1일
    cout << dday.days()  << endl; // 평창 올림픽 까지 남은 날.
}



C# 만큼 편리한 계산이 가능함.

Yamecoder 야매코더_
C++(oF) 2016.07.10 21:24

[of] LIB VLC 사용하기

0. 왜 VLC 인가? 

우선 윈도우용 0.9.X(3)  까지 의 내장된 ofVideoPlayer는 극히 성능이 저질이다. 720P 정도도 온전한 재생이 힘들다.

물론 대안으로 HAP 이 있다. 퍼포먼스는 보장 하지만 HAP 영상파일 자체는 매우 파일이 거대? 하며 용량이 무압축에 가깝다. 퍼포먼스를 위해 감내해야 하는 비용이 상당하다. 또한 윈도우용 WMF 코덱을 이용하는 방법이 있다. 하지만 보다 범용적이고, 그래픽 성능을 모두 발휘 할 수 있는 VLC는 잘 다루면 스트리밍 서버/ 클라이언트 까지 구현이 가능 하며, 호환성이 좋기 때문에 응용하기에 따라 맥, 리눅스 에서도 무사히 사용이 가능 하다. 심지어 관련 정보도 많이 있다. 





1. vlc 를 다운 받는다. 대상 버전은, 현재 안정 버전인 2.0.5 이다.

1) http://www.videolan.org/vlc/#download




2. vlc 에드온 https://github.com/jnakanojp/ofxVLCVideoPlayer 을 다운받는다.

1) 설명에 적혀 있듯, 몇몇 파일들이 필요 하다. 필자의 경우 원본 훼손 우려를 피하기 위해 별도의 폴더에 필요한 파일을 옮기고 필요하다면 코드를 수정한다.

- 필요항목

* plugins 폴더

* sdk 폴더

* dll 들 : axvlc.dll , libvlc.dll , libvlccore.dll , npvlc.dll (사실 libvlc 와 libvlccore 만 있어도 됨)




3. ofxVLCVideoPlayer를 포함한 openframeworks 프로젝트를 생성 한다. 

1) 빌드를 한다음 bin 폴더에 이전에 따로 보관했던 [plugins 폴더]와 [  libvlc.dll , libvlccore.dll ] 을 복사한다.




4. 생성된 프로젝트에 Properties를 열어 VLC 라이브러리를 붙여 본다. 

(필자의 경우 [C:\CppLibs\vlc] 에 sdk 를 복사해서 사용 하였다. )


1) [C/C++] -> [Additional Include Directories] : 

* C:\CppLibs\vlc\sdk\include 추가

* C:\CppLibs\vlc\sdk\include\vlc\plugins 추가


2) [Linker] -> [Additional Library Directories] 

* C:\CppLibs\vlc\sdk\lib


3) [Linker] -> [Additional Library Directories] -> [input] -> [Additional Dependencies]

* libvlc.dll 기입

* libvlccore.dll 기입




5. 빌드를 해보자. 

ofApp.h 에 [ #include "ofxVLCVideoPlayer.h" ] 를 기록 하고 빌드를 해보자. 아마 수 많은 에러로 인하여 빌드가 되지 않을 것이다.




6. 이 문제를 해결하여 보자. 

아마 다른 플랫폼 혹은, 예전 컴파일러와 개발환경에 맞추어 져 있는 몇몇 코드들 때문에 원활히 빌드가 안되는것으로 예상한다. sdk 중 몇몇 코드를 수정 해야 한다.  (OF .0.9.3 기준, VisualStudio 2015 기준)


1) plugins/vlc_meta.h , plugins/vlc_epg.h , vlc_input_item.h , 

* #include <vlc_common.h> 추가


2) plugins/vlc_arrays.h

* strdup 을 -> _strdup 으로 수정한다. 

- Line 515 , 532 



7. ofxVLCVideoPlayer 의 일부 코드도 변경이 필요 하다. 

1) 94 ~ 97 줄 주석(//) 처리

2) 115 ~ 126 줄 주석(//) 처리



8. 마지막으로 SAFESSH 를 비활성화 한다.

1) [Linker] -> [Advanced] -> [Image Has Safe Exception Handlers] -> No 




9. 예제 코드 


ofApp.h

#include "ofMain.h"
#include "ofxVLCVideoPlayer.h"

class ofApp: public ofBaseApp{
    
    public:
        
        void setup();
        void update();
        void draw();
        
        void keyPressed(int key);   
        
        float   counter;
        bool    bSmooth;

        ofVideoPlayer player2;
        ofxVLCVideoPlayer player;

        ofImage testImage;
};



ofApp.cpp


#include "testApp.h"


//--------------------------------------------------------------
void ofApp::setup(){
player.loadMovie("test.mp4"); } //-------------------------------------------------------------- void ofApp::update(){
player.update(); } //-------------------------------------------------------------- void ofApp::draw(){
player.draw(0,0); } //-------------------------------------------------------------- void ofApp::keyPressed (int key){
if (key == ' ') { player.play(); } }






10. 성능과 마무리 

ofxVLCVideoPlayer 는 아직 정리가 덜된듯 하다. 그러나 1920x1080 영상은 매우 매끄럽게 돌아간다. 하지만 QHD , 4K 는 vlc 의 온전한 성능을 못내는것 같다.

아마 vlc 에서 콜백으로 픽셀을 받고 치환 하는 과정에서 무언가 비효율이 발생 하는듯 한데 조만간 ofxVLCVideoPlayer 를 참고하여 온전한 vlc 성능을 내는 에드온을 만들어야 하겠음.



참고로 원래 vlc 플레이어는 4K 영상이 온전히 돌아간다. 



(7/25) 만들었음 : http://scripter.co.kr/356



Yamecoder 야매코더_
C++(oF) 2016.07.09 22:53

Blur쉐이더 , Desktop 용






원본은 https://www.shadertoy.com/view/4lXXWn 이다.

하지만 OF용으로 몇몇것들이 맞지 않아 수정을 해야 했다.



결과물 상세 이미지





쉐이더 1번에 최대한 효과적인 블러를 만들어야 겠다는 목표로.. 






#define STRINGIFY(A) #A

ofImage image1;
ofImage boy;
ofShader shader1;

//--------------------------------------------------------------
void ofApp::setup(){

//원본 : https://www.shadertoy.com/view/4lXXWn
string shaderProgram = STRINGIFY(

uniform sampler2DRect iChannel0;
uniform vec3 iResolution;

uniform float repeats;
uniform float amount; // 범위 0.0 ~ 0.1

vec4 texture(vec2 uv) {
return texture2DRect(iChannel0,vec2(uv.x * iResolution.x ,uv.y * iResolution.y));//.rgb;
}


//랜덤 이용
float rand(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

void mainImage( out vec4 fragColor, vec2 fragCoord )
{

vec2 uv = (fragCoord.xy / iResolution.xy);

vec4 blurred_image = vec4(0.);
for (float i = 0.0; i < repeats; i++) {
vec2 q = vec2(cos(degrees((i/repeats)*360.)),sin(degrees((i/repeats)*360.))) * (rand(vec2(i*uv.x ,i*uv.y ))+amount);
vec2 uv2 = uv+(q*amount);
blurred_image += texture(uv2)/2.;
q = vec2(cos(degrees((i/repeats)*360.)),sin(degrees((i/repeats)*360.))) * (rand(vec2(i*uv.x ,i*uv.y ))+amount);
uv2 = uv+(q*amount);
blurred_image += texture(uv2)/2.;
}
blurred_image /= repeats;
fragColor = blurred_image;
}


void main(void)
{
vec2 pos = gl_TexCoord[0].st;
vec4 color = vec4(0.0 , 0.0 , 0.0 , 0.0);
mainImage(color , pos);
gl_FragColor = color;
}

);

shader1.setupShaderFromSource(GL_FRAGMENT_SHADER , shaderProgram);
shader1.linkProgram();

boy.load("images/boy.png");
image1.load("images/scenery.png");
}

//--------------------------------------------------------------

float elapsed_time = 0.0;
void ofApp::draw(){

elapsed_time += ofGetLastFrameTime();

int repeats = ofMap(ofGetMouseX() ,0 , ofGetWidth() , 1 , 240);
float amount = ofMap(ofGetMouseY() , 0 , ofGetHeight() , 0.0 , 0.1);

boy.draw(0 , 0 , ofGetWidth() , ofGetHeight());

shader1.begin();
shader1.setUniform3f("iResolution" , image1.getWidth() , image1.getHeight() , 0.0f);
shader1.setUniform1f("repeats" , repeats);
shader1.setUniform1f("amount" , ofMap(ofGetMouseY() , 0 , ofGetHeight() , 0.0 , 0.1));
image1.draw(0,0);
shader1.end();

ofDrawBitmapStringHighlight(ofToString(ofGetFrameRate()) , 30,30);
ofDrawBitmapStringHighlight("repeats : " + ofToString(repeats) , 30 , 60);
ofDrawBitmapStringHighlight("amount : " + ofToString(amount) , 30 , 75);

boy.draw(30 , 90 , 50 , 50);

}

//--------------------------------------------------------------
void ofApp::update(){

}



//--------------------------------------------------------------
void ofApp::keyPressed(int key){

if(key == '1')
{
image1 = ofImage("images/scenery.png");

}
else if(key == '2')
{
image1 = ofImage("images/CircleAndRect1.png");
}

} 

저장저장


Yamecoder 야매코더_
C++(oF) 2016.06.18 21:28

Desktop 과 IOS(openGLES2.0) 의 쉐이더 텍스처 기본 시작 코드

Desktop 코드


#define STRINGIFY(A) #A

ofImage image1;
ofShader shader1;
//--------------------------------------------------------------
void ofApp::setup(){


string shaderProgram = STRINGIFY(

uniform sampler2DRect tex0;
void main(void)
{
vec2 pos = gl_TexCoord[0].st;
gl_FragColor = texture2DRect(tex0 , pos);
}

);

shader1.setupShaderFromSource(GL_FRAGMENT_SHADER , shaderProgram);
shader1.linkProgram();

image1.load("images/image1.jpg");

}

//--------------------------------------------------------------
void ofApp::draw(){
shader1.begin();
image1.draw(0,0);
shader1.end();

} 









IOS 코드 (아래 중요(important!)부분이 반드시 들어가야 setupShaderFromSource(...) 를 이용 할 수 있다)

#define STRINGIFY(A) #A

ofImage image1;
ofShader shader1;
//--------------------------------------------------------------
void ofApp::setup(){


ofxiPhoneSetOrientation(OF_ORIENTATION_90_LEFT);

string shaderProgram_vert = STRINGIFY(
uniform mat4 modelViewProjectionMatrix;
attribute vec4 position;
attribute vec2 texcoord;
varying vec2 texCoordVarying;

void main(void)
{
texCoordVarying = texcoord;
gl_Position = modelViewProjectionMatrix * position;
}
);

string shaderProgram_frag = STRINGIFY(

precision highp float;
uniform sampler2D tex0;
varying vec2 texCoordVarying;
void main(void)
{
gl_FragColor = texture2D(tex0 , texCoordVarying);
}

);

shader1.setupShaderFromSource(GL_VERTEX_SHADER , shaderProgram_vert );
shader1.setupShaderFromSource(GL_FRAGMENT_SHADER , shaderProgram_frag);

// important!
if( ofIsGLProgrammableRenderer())
{
shader1.bindDefaults();
}
shader1.linkProgram();

image1.load("images/image1.jpg");

}

void ofApp::draw(){

shader1.begin();
image1.draw(0,0);
shader1.end();

}


Yamecoder 야매코더_
C++(oF) 2016.06.18 02:41

[IOS] 아이폰의 카메라 기능을 모두 사용 하기



아이폰에서 OF 를 통하여 카메라를 사용 할때 ofVideoGrabber 를 사용하면 fps 가 현저히 떨어진다 (0.9.3 의 경우)


따라서 이건 사용 하지 못하고 [ AVFoundationVideoGrabber ] 를 사용 하여야 한다. 


아쉽게도 직접 그리는 방법은 제공 되지 않고 ofImage로 픽셀을 복사 하여 draw 하면 된다. 



그런데 아쉽게도 of에서 제공하는 [ AVFoundationVideoGrabber ]  는 아이폰 카메라의 focus , torch , white balance 의 기능을 제어하지 못하게 되어 있다. 


하지만 objective-c 를 호출 하여 해결 할 수 있다.



또한 아이폰 카메라 뷰의 "사진" 모드와 다소 비율이 다른데 이것은 


AVFoundationVideoGrabber.mm 에서 해상도 설정을 강제로 4:3 으로 맞추면 된다. (1024 x 768)

그렇게 하면 아래위로 보다 넓은 해상도를 얻을수 있다.

이때 preset 을 16:9 가 명시되어 있는 것으로 지정 하면 종횡비가 맞지 않는다. (AVCaptureSessionPreset1280x720 와 같은것은 안된다.)



(원문 출처 : : :https://github.com/armadillu/openFrameworks/blob/7c6d4e28802a9bbfd47ed27651e7df10c1b78a1f/addons/ofxiPhone/src/AVFoundationVideoGrabber.h)

 : 

AVFoundationVideoGrabber.h 중 일부 


... (생략) ...

-(void)lockExposureAndFocus;
-(vector <string>)listDevices;
-(void)setDevice:(int)_device;
-(void)eraseGrabberPtr;

-(CGImageRef)getCurrentFrame;


//add jjongun

// focus
-(bool)setContinuousAutoFocus;
-(bool)focusOnce;
-(bool)lockFocus; //at curent focus
-(bool)touchFocusAt:(CGPoint)focusPoint; // (0,0) bottom left, (1,1) top right, calls focusOnce



// Exposure
-(bool)setContinuousAutoExposure;
-(bool)lockExposure;
-(bool)autoExposureOnce;
-(bool)touchExposeAt:(CGPoint)autoExposeHere; // (0,0) bottom left, (1,1) top right, calls autoExposreOnce



// Torch
-(float)currentTorchLevel; // [0..1]
-(bool)startTorch;
-(bool)setAutoTorch; //adjust torch intensity depending on scene darkness
-(bool)stopTorch;



//white balance
-(bool)setContinuousAutoWhiteBalance;
-(bool)lockWhiteBalance;
-(bool)autoWhiteBalanceOnce;



@end

class AVFoundationVideoGrabber{

    public:     
        AVFoundationVideoGrabber();
        ~AVFoundationVideoGrabber();

 ... (생략) ...

//jjongun c++ 로 링킹 iOSVideoGrabber* getiOSVideoGrabber() const; //focus bool setContinuousAutoFocus(); bool focusOnce(); bool lockFocus(); bool touchFocusAt(ofVec2f point); //Exposure bool setContinuousAutoExposure(); bool lockExposure(); bool autoExposureOnce(); bool touchExposeAt(ofVec2f point); // Torch float currentTorchLevel(); // [0..1] bool startTorch(); bool setAutoTorch(); //adjust torch intensity depending on scene darkness bool stopTorch(); //white balance bool setContinuousAutoWhiteBalance(); bool lockWhiteBalance(); bool autoWhiteBalanceOnce();


 ... (생략) ...



이하 mm 파일은 아래에 


AVFoundationVideoGrabber.h


AVFoundationVideoGrabber.mm



..



 

Yamecoder 야매코더_
C++(oF) 2016.04.16 16:22

CLM Framework with (TBB) on openFrameworks

..(아직 포스팅 안됨)..

Yamecoder 야매코더_
C++(oF) 2016.04.14 00:42

간단한 다각형의 HitTest

...

Yamecoder 야매코더_
C++(oF) 2016.04.11 23:37

[초간단] OF윈도우 리사이즈 막기

#include "ofMain.h"
#include "ofApp.h"

//========================================================================
int main( ){
    ofGLFWWindowSettings settings;
    settings.width = 1024;
    settings.height = 1024;
    settings.windowMode = OF_WINDOW;
    settings.resizable = false; // 리사이즈 셋팅
    ofCreateWindow(settings);
    //ofSetupOpenGL(&window , 600,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());

}



ofSetupOpenGL 대신 푸른색 부분으로 치환 

Yamecoder 야매코더_
C++(oF) 2016.04.06 18:45

OF로 만든 VR 비디오 뷰어.

와... 배경음악 저작권 찾아내는게 기술이다.. 



Yamecoder 야매코더_
C++(oF) 2016.04.02 19:32

ARToolkit5 새로운 패턴 적용 하기


[Windows]


1. 사용 버전과 동일한 패키지 다운로드 하기 : http://artoolkit.org/download-artoolkit-sdk


2.. 다운로드 후 설치 


3. bin 위치로 이동 [기본) C:\Program Files (x86)\ARToolKit5\bin ]


4. mk_patt.exe 실행 


5. 카메라세팅은 디폴트로 (보통 웹캠의 경우... ) 한다면 그냥 엔터. 


6. 간단한 카메라 프리셋 


7. 카메라를 통해 마커 노출 




영역이 잡힌다면, 영역을 마우스 좌클릭,


8. 콘솔창으로 이동 하여 세이브 경로 지정 

- 만약 에러(error) 가 난다면, 절대 경로 부터 입력

 예) c:/temp/ex.pat


9. 세이브 파일을 황용.

Yamecoder 야매코더_
C++(oF) 2016.03.20 02:55

OF를 유틸리티 프로그램으로 사용하기

OpenFrameworks 는 훌륭한 그래픽 프레임워크인 동시에 POCO 와 BOOST 또는 네트워크 , 이미지 처리등 비주얼에 관한 기능을 구지 제외 하더라도 꾀 생산성 있는 프레임 워크임에 분명하다.


특히 ofFile관련 클래스들을 이용하면 c# 응용 프로그램으로 처리하는 간단한 파일 처리, 등을 동일한 생산성으로 더 높은 퍼포먼스로 응용 프로그램을 만들수 있다.

ofxAddos 에도 XML , JSON 등의 라이브러리를 이용 할 수 도 있다. 


그러기 위해선 main.cpp 에 약간의 준비 과정이 필요 하다.

#include "ofMain.h"
#include "ofApp.h"
#include "ofUtils.h" // 추가

//========================================================================
int main( ){
    
    /* 화면이 필요 없는 유틸리티 프로그램으로, OpenGL을 셋팅 하는 부분과 ofApp 을 실행 하는 부분을 제거 한다.
    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());
    */


    of::priv::initutils(); // ofUtil을 초기화 한다.

    cout << "Start Program" << endl;
    cout << endl;
    cout << ofFilePath::getCurrentExeDir() << endl; // ofUtil을 초기화 하지 않으면, ofFile 관련 기능에서 에러가 난다.

    // 
    this_thread::sleep_for(1000ms);
    //


    cout << "End of Program" << endl;
    getchar();
}


위와 같이 of::priv::initutils()로 초기화를 해주고, 불필요한 부분은 제거 한다.


이렇게 하는 이유중 하나는 OF윈도우와 OpenGL이 셋업되면 그에 수반한 여타 DLL 들이 동시에 필요 하여 유틸리티 프로그램으로서 휴대성을 상실 하기 마련이다.

하지만 이렇게 설정 하면 빌드된 단일 .exe 파일 하나만으로 완벽히 실행이 된다.



Yamecoder 야매코더_
C++(oF) 2016.03.18 22:14

[OF] Visual Studio 2015 Community 에서 Icon 바꾸기

Community 버전 이라 그런지 딱히 리소스 이미지 파일을 수정 할 수 없다.




1. 아이콘으로 사용할 이미지 확보 

1) https://thenounproject.com/

2) https://design.google.com/icons/

3) http://simpleicon.com/

등등 여러가지




2. 온라인 아이콘 컨버터 이용 ( http://icoconvert.com/ )

1) 파일을 선택 한후 [Upload] 버튼을 누른다.

2) 아래의 설정 처럼 모든 사이즈를 선택 한다.

3) [Convert] 클릭 및 다운로드




3. 아이콘 파일을 프로젝트 폴더로 복사 및 파일명 교체

1) 파일을 복사 하여 icon_debug.ico 와 icon.ico 로 용도를 나누어 2개의 파일을 만들자.

2) 프로젝트 폴더 (.sln 파일과 같은 위치)에 넣는다.



4. 빌드

1) 디버그로 빌드를 하면 탐색기 상에 아이콘이 변경이 되지 않아 보일 수 있다. 그러나, 다른 폴더로 복사 하여 확인 해 보면 확일 할 수 있다.


Yamecoder 야매코더_
C++(oF) 2016.03.18 20:06

ofDrawBitamp(...) 의 텍스트 렌더링 사이즈 알아내기






각 Char 당 가로 8pt , 세로 11pt 로 계산 하면 딱 맞다. 

물론 대문자의 경우 높이가 7pt 이지만 소문자의 j p q y 등과 같은 아래로 내려 오는 문자를 포함 하면 11pt 로 계산 하는것이 맞다.

또한 공백 역시 7pt 폭을 유지 했다.




- 추가 내용 

관련 내용을 OF 포럼에 문의 하고 답변을 달았더니, roymacdonald님 이 깔끔하게 정리 해줌.



https://forum.openframeworks.cc/t/how-to-get-size-of-ofdrawbitmapstring/22578/6



ofRectangle getBitmapStringBoundingBox(string text){
vector<string> lines = ofSplitString(text, "\n");
    int maxLineLength = 0;
    for(int i = 0; i < (int)lines.size(); i++) {
        // tabs are not rendered
        const string & line(lines[i]);
        int currentLineLength = 0;
        for(int j = 0; j < (int)line.size(); j++) {
            if (line[j] == '\t') {
                currentLineLength += 8 - (currentLineLength % 8);
            } else {
                currentLineLength++;
            }
        }
        maxLineLength = MAX(maxLineLength, currentLineLength);
    }
    
    int padding = 4;
    int fontSize = 8;
    float leading = 1.7;
    int height = lines.size() * fontSize * leading - 1;
    int width = maxLineLength * fontSize;
return ofRectangle(0,0,width, height);
}


//using


string comment = "thanks roymacdonald!\nIt is exactly what I need.\nyo!\n-openframeworks- ";
    ofRectangle rect = getBitmapStringBoundingBox(comment);
    rect.x = 100;
    rect.y = 100;
    ofSetColor(ofColor::yellow);
    ofRect(rect.x, rect.y, rect.width, rect.height);
    ofSetColor(ofColor::red);
    ofDrawBitmapString(comment, rect.x, rect.y + 11); // '11' is a static character size of height.


Yamecoder 야매코더_
C++(oF) 2016.02.25 20:33

openFrameWorks 에서 FFMPEG 사용하기 :: 준비단계


참고 사이트 : http://aslike.egloos.com/category/%E2%94%94%20FFMPEG



FFMPEG 를 openFrameWorks 0.9 와 Windows Visual Studio 2015 환경에 맞추어 보는 과정을 기록 함.



1. FFMPEG 다운 

1) 이동 : http://ffmpeg.zeranoe.com/builds/

2) [ Download FFmpeg git-588e2e3 32-bit Shared ] 와 [ Download FFmpeg git-588e2e3 32-bit Dev ] 를 다운 받음

-> Shared 와 Dev 둘다 필요 하다.

3) 압축 파일을 (권장 사항) C:/FFmpeg/ 에 풀어 정리 한다. 아래는 간편한 사용을 위해 본인이 만든 폴더 구조를 그대로 분할 압축 해 놓은것임.

FFmpeg.z01

FFmpeg.zip


2. openFrameWorks 프로젝트 생성 

3. 프로젝트 설정 (프로젝트 우클릭->Properties)

1) [ C/C++ ] -> [ Additional Include Directories ] -> [ C:\FFmpeg\include ] 추가

2) [ Linker ] -> [ General ] -> [ Additional Library Directories ] -> [ C:\FFmpeg\lib ] 추가

3) 중요! [ Linker ] -> [ Command Line ] -> [ Additional Options ] -> [ /safeseh:no ] 추가

4) 한번 빌드 후 [/bin] 폴더에 [ C:\FFmpeg\bin ] 의 모든 DLL 복사



4. 테스트용 비디오 다운로드

1) 예제가 전체 데이터를 한꺼번에 읽는 것 이어서 영상 파일 크기가 크면 테스트 시간이 오래 걸려, 아래와 같은 비디오를 준비 하였음

출처 : http://download.wavetlan.com/SVV/Media/HTTP/http-mp4.htm

H264_test1_Talkinghead_mp4_480x360.mp4


5. 테스트 코드 작성


#include "ofApp.h"
extern "C"
{
#include <libavformat\avformat.h>
}
#pragma comment(lib , "avformat.lib")
#pragma comment(lib , "avutil.lib")
#pragma comment(lib , "avcodec.lib")


static void write_ascii_frame(const char *szFileName, const AVFrame *frame)
{
    int x, y;
    uint8_t *p0, *p;
    const char arrAsciis[] = " .-+#";

    FILE* fp = fopen(szFileName, "w");
    if (fp) {
        /* Trivial ASCII grayscale display. */
        p0 = frame->data[0];
        for (y = 0; y < frame->height; y++) {
            p = p0;
            for (x = 0; x < frame->width; x++)
                putc(arrAsciis[*(p++) / 52], fp);
            putc('\n', fp);
            p0 += frame->linesize[0];
        }
        fflush(fp);
        fclose(fp);
    }
}

//--------------------------------------------------------------

void ofApp::setup() {

    cout << "start app : " << std::this_thread::get_id() << endl;
    string movie = "D:/temp/2015_12_12/H264_test1_Talkinghead_mp4_480x360.mp4";
    
    
    //
    //initialize
    //
    av_register_all();
    avformat_network_init();


    //
    //open
    //
    int ret = 0;
    int nVSI = -1;
    int nASI = -1;
    AVFormatContext* pFmtCtx = NULL;
    ret = avformat_open_input(&pFmtCtx, movie.c_str(), NULL, NULL);

    cout << ret << endl; //ret 이 0 이 아니면 오류

    ret = avformat_find_stream_info(pFmtCtx, NULL);
    cout << ret << endl; //ret 이 0 이 아니면 오류


    //
    // find streams
    //
    for (size_t i = 0; i < pFmtCtx->nb_streams; i++)
    {
        cout << "Stream " << i << " is ";

        switch (pFmtCtx->streams[i]->codec->codec_type)
        {
        case AVMEDIA_TYPE_VIDEO:
            cout << "video" << endl;
            break;
        case AVMEDIA_TYPE_AUDIO:
            cout << "audio" << endl;
            break;
        case AVMEDIA_TYPE_SUBTITLE:
            cout << "subtitle" << endl;
            break;
        // AVMEDIA_TYPE_ 에 타입 종류는 다양히 명시 되어 있음
        default:
            break;
        }
    }

    nVSI = av_find_best_stream(pFmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
    nASI = av_find_best_stream(pFmtCtx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
    cout << "find best stream is " << nVSI << " , " << nASI << endl;


    //
    // create decoder 
    //
    AVCodec* pVideoCodec = avcodec_find_decoder(pFmtCtx->streams[nVSI]->codec->codec_id);
    AVCodec* pAudioCodec = avcodec_find_decoder(pFmtCtx->streams[nASI]->codec->codec_id);

    if (pVideoCodec == NULL)
        cout << "fail : video codec finding";

    if (pAudioCodec == NULL)
        cout << "fail : audio codec finding";

    ret = avcodec_open2(pFmtCtx->streams[nVSI]->codec, pVideoCodec, NULL);
    if (ret < 0)
        cout << "fail : video codec opening";

    ret = avcodec_open2(pFmtCtx->streams[nASI]->codec, pAudioCodec, NULL);
    if (ret < 0)
        cout << "fail : video codec opening";



    //
    //reading data
    //
    AVCodecContext* pVCtx = pFmtCtx->streams[nVSI]->codec;
    AVCodecContext* pACtx = pFmtCtx->streams[nASI]->codec;
    AVFrame* pVFrame = av_frame_alloc();
    AVFrame* pAFrame = av_frame_alloc();
    AVPacket packet;

    int bGotPicture = 0;
    int bGotSound = 0;
    int reading_count = 0;

    bool isPrintTest = false;
    while (av_read_frame(pFmtCtx, &packet) >= 0)
    {

        cout << "reading : " << reading_count << "  ";
        
        if (packet.stream_index == nVSI)
        {
            avcodec_decode_video2(pVCtx, pVFrame, &bGotPicture, &packet);
            if (bGotPicture)
            {
                cout << "video data able : " << bGotPicture;


                //test capture pixels
                if (isPrintTest == false && reading_count > 1346)
                {
                    isPrintTest = true;
                    write_ascii_frame("output.txt", pVFrame);
                }
            }
        }
        else if (packet.stream_index == nASI)
        {
            avcodec_decode_audio4(pACtx, pAFrame, &bGotSound, &packet);
            if (bGotSound)
            {
                //ready to render
                cout << "Audio data able: " << bGotSound;
            }
        }

        cout << endl;
        reading_count++;


        av_free_packet(&packet); // free packet data
    }


    //
    // free data and close 
    //
    av_free(pVFrame);
    av_free(pAFrame);

    avformat_close_input(&pFmtCtx);
    avformat_network_deinit();
}



참고 : https://sourceforge.net/u/leixiaohua1020/wiki/simplest_ffmpeg_tutorial/

Yamecoder 야매코더_
C++(oF) 2016.02.16 17:25

ofXml 간단 사용법

#include "ofApp.h" #pragma region names vector<string> names({ "Merissa Canney", "Ha Gandee", "Mercedes Shimmin", "Helaine Axley", "Daniell Ory", "Melodie Hossain", "Tanya Blaisdell", "Deloris Liles", "Ellsworth Mays", "Latesha Twilley", "Kizzie Mcneely", "Neva Verduzco", "Queenie Gammill", "Hai Boothby", "Arlette Duley", "Milford Shultis", "Emerita Bonk", "Johanne Mcclinton", "Suzann Drye", "Eloisa Camarena" }); #pragma endregion ofXml xml; int name_count = 0; ofXml CreateClass(string className) { ofXml classXml; classXml.addChild("class"); classXml.setAttribute("name" , className); for (size_t i = 0; i < 4; i++) { ofXml student; student.addChild("student"); //student.setTo("//student"); 참고 1-1 student.setAttribute("age", ofToString(8 + rand() % 10)); student.setAttribute("name", names[name_count]); student.addValue("score", rand() % 101); name_count++; classXml.addXml(student); } return classXml; } //-------------------------------------------------------------- void ofApp::setup(){ // // XML 만들기 // xml.addChild("root"); xml.addXml(CreateClass("1-1")); xml.addXml(CreateClass("1-2")); xml.addXml(CreateClass("1-3")); xml.save("ClassData.xml"); // // XML 읽기 // stringstream ss; for (size_t i = 0; i < xml.getNumChildren(); i++) { xml.setToChild(i); // 진입 1 ss << endl; ss << endl; ss << "class name : " << xml.getAttribute("name") << endl; ss << "student length : " << xml.getNumChildren() << endl; ss << "======================" << endl; for (size_t j = 0; j < xml.getNumChildren(); j++) { xml.setToChild(j); // 진입 2 string student_name = xml.getAttribute("name"); int student_age = ofToInt( xml.getAttribute("age") ); xml.setTo("score"); // 진입 3 상대적으로 위치를 지정 //xml.setToChild(0); // 진입 3 int score = ofToInt(xml.getValue()); xml.setToParent(); // 탈출 3 xml.setToParent(); // 탈출 2 ss << endl; ss << " name : " << student_name << endl; ss << " age : " << student_age << endl; ss << " scrore : " << score << endl; } xml.setToParent(); // 탈출 1 } ofstream outFile("data/save.txt"); outFile << ss.str(); cout << ss << endl; xml.setTo("//class[1]//student//score"); // 한번에 위치를 지정 할 수 있다. cout << xml.getValue() << endl; }



ofXml 은 xml을 기록 혹은 읽어드릴 위치를 명시한 다음 활용 해야 한다. 









Yamecoder 야매코더_
C++(oF) 2016.02.11 00:11

InClass GLSL Shader , 클래스 코드 안에 쉐이더 코드를...

#define STRINGIFY(A) #A //메크로 선언 ofShader shader; //-------------------------------------------------------------- void ofApp::setup() { string shaderstr = STRINGIFY( #version 150\n //버전 텍스트 라인을 \n으로 리터럴 uniform float value0; //프로퍼티 선언 out vec4 outputColor; void main() { float windowWidth = 1024; float windowHeight = 768; float r = gl_FragCoord.x / windowWidth; float g = gl_FragCoord.y / windowHeight; float b = value0;//1.0; float a = 1.0; outputColor = vec4(r, g, b, a); } ); shader.setupShaderFromSource(GL_FRAGMENT_SHADER, shaderstr); //쉐이더 코드 삽입 shader.linkProgram(); //컴파일 } //-------------------------------------------------------------- void ofApp::draw() { shader.begin(); float v = ofMap(mouseX, 0, ofGetWidth(), 0, 1); shader.setUniform1f("value0", v); //프로퍼티 사용 ofRect(0, 0, 1024, 768); shader.end(); }




추가 16.05.07


ios 에서 오작동. , 

ios 에서는 버전을 명시 하면 안됨. 제거를 하면 컴파일은 무사히 되나, 오작동 함. (텍스트 인코딩 쪽에 문제로 추정됨)


Yamecoder 야매코더_
C++(oF) 2016.01.25 20:59

In Class Static 와 Singleton


C++ 에서 클래스 안의 Static 필드를 사용하기 위해서 한가지 주의해야 할 항목이 있다.





StaticExample.h

#pragma once
#include<map>
#include <iostream>

using namespace std;
class StaticExample
{
private:
    static map<int, int> sampleMap;
public:
    static void CheckContainKey(int key);
}


StaticExample.cpp

#include "StaticExample.h"

map<int, int> StaticExample::sampleMap; // 이 부분이 없으면 LNK2001 , LNK1120 에러가 난다. void StaticExample::CheckContainKey(int key) { int already_count = sampleMap.count(key); cout << "count is : " << already_count << endl; }




추가로 

간단한 싱글턴 만들기



TestSingleton.h

#pragma once

#include <iostream>

using namespace std;
class TestSingleton
{

public:
    static TestSingleton* GetInstance();
    void Something();
private:
    static TestSingleton* instance;
    TestSingleton();
    
};


TestSingleton.cpp

#include "TestSingleton.h" TestSingleton* TestSingleton::instance = nullptr; // 이 부분이 없으면 LNK2001 , LNK1120 에러가 난다. TestSingleton* TestSingleton::GetInstance() { if (instance == nullptr) instance = new TestSingleton(); return instance; } void TestSingleton::Something() { cout << " single access method " << endl; } TestSingleton::TestSingleton() { cout << "single create " << endl; }


Yamecoder 야매코더_
C++(oF) 2016.01.24 18:26

람다 콜백 , std::function<void()> 이용한 DelayCall

람다 , 콜백 관련글


http://scripter.co.kr/325

http://scripter.co.kr/326



std::function<void()> 를 이용하여

콜백 함수를 전역의 변수화 하여 다른 메서드에서 호출 하는 타이밍을 조절 한다.



#pragma once

ofxDelayCall.h


#include "ofEvents.h"
#include "ofUtils.h"
class ofxDelayCall
{

private:

    float interval = 0;
    float startTime = 0;
    std::function<void()> callback;

    

    void StartTimer();
    void StopTimer();
    void update(ofEventArgs &e);

public:
    ~ofxDelayCall();
    void DelayCall(float interval, std::function<void()> callback);
};





ofxDelayCall.cpp

#include "ofxDelayCall.h"


ofxDelayCall::~ofxDelayCall()
{
    cout << "delete call " << endl;
}

void ofxDelayCall::StartTimer()
{
    //타이머 시작
    ofAddListener(ofEvents().update,this, &ofxDelayCall::update);
}

void ofxDelayCall::StopTimer()
{
    //타이머 삭제
    ofRemoveListener(ofEvents().update, this, &ofxDelayCall::update);
}

void ofxDelayCall::update(ofEventArgs & e)
{
    float elapsed = ofGetElapsedTimef() - startTime;
    if (elapsed < 0.0001f) elapsed = 0;

    if (elapsed > interval)
    {
        cout << "callback!" << endl;
        callback();
        StopTimer();
    }
}

void ofxDelayCall::DelayCall(float interval, std::function<void()> callback)
{
    this->callback = callback;
    this->interval = interval;
    startTime = ofGetElapsedTimef();
    StartTimer();
}



활용 : 

cout << "delay start : " << std::this_thread::get_id() << endl; ofxDelayCall::DelayCall(1.5, [=]() { cout << "complete " << std::this_thread::get_id() << endl; });


Yamecoder 야매코더_
C++(oF) 2016.01.14 14:54

ofEvents() 이벤트 우선순위


별도의 클래스에 ofApp.cpp 와 같은 이벤트를 만들어 수신 할 수 있는데, 이때, 이벤트 수신의 순위를 지정 할 수 있다.









 

ofApp.cpp

#include "ofApp.h"
#include "SomeObject.h"

//--------------------------------------------------------------
void ofApp::setup(){

    /*
    본문의 Draw 이벤트는 우선순위가(Event priority value) 100 이고, 
    이것을 기준으로 이벤트 우선순위를 정하는데, 값이 높을 수록 최상단에 위치함.
    값이 동격일 경우 생성 순서에 의하여 결정됨.
    */
    DrawObject* so1 = new DrawObject(ofVec2f(150, 100), ofColor::skyBlue, 101); // 본문 보다 앞에 있음
    DrawObject* so2 = new DrawObject(ofVec2f(125, 50), ofColor::brown , 99); // 본문 보다 뒤에 있음.
}

//--------------------------------------------------------------
void ofApp::draw() {

    ofSetColor(ofColor::red);
    ofDrawCircle(100, 100, 50);
    ofSetColor(ofColor::white);
}




DrawObject.h

#pragma once

#include "ofMain.h"
#include "ofEvents.h"

class DrawObject 
{
private:
    ofVec2f pos;
    ofColor color;
    int prio;
public :

    DrawObject(ofVec2f pos , ofColor color , int prio)
    {
        this->pos = pos;
        this->color = color;
        this->prio = prio;
        
        //ofEvents 에서는 우선순위를 쉽게 지정 할 수 있도록 아래의 값을 만들어 놨다.
        //OF_EVENT_ORDER_BEFORE_APP = 0;
        //OF_EVENT_ORDER_AFTER_APP = 200;
        //OF_EVENT_ORDER_APP = 100;


        //객체에 이벤트를 별도로 수신 하도록 하여 독립적인 draw 이벤트를 만들었다.
        ofAddListener(ofEvents().draw, this, &DrawObject::draw, prio);
    }

    void draw(ofEventArgs &e)
    {
        ofSetColor(color);
        ofDrawCircle(pos.x, pos.y, 50);
    }
    
};




Yamecoder 야매코더_
C++(oF) 2016.01.13 21:36

ofxTrueTypeFontUC 를 이용한 한글 출력 (0.9.0)


1. addon download


ofxTrueTypeFontUC https://github.com/hironishihara/ofxTrueTypeFontUC



2. 0.9.0 에서 적용하기

1) ofxTrueTypeFontUC.cpp 의 include 수정 (13줄) " /freetype/ " 삭제


#include "freetype2/freetype/freetype.h"

#include "freetype2/freetype/ftglyph.h"

#include "freetype2/freetype/ftoutln.h"

#include "freetype2/freetype/fttrigon.h"


을 


#include "freetype2/freetype.h"

#include "freetype2/ftglyph.h"

#include "freetype2/ftoutln.h"

#include "freetype2/fttrigon.h"


로 바꿈.




3. 적용 및 확인 


ofApp.h

#pragma once

#include "ofMain.h"
#include "ofxTrueTypeFontUC.h"
#include "ofxGui.h"

class ofApp : public ofBaseApp{

public:
    ofxTrueTypeFontUC myFont;
    ofxPanel gui;
    ofxFloatSlider fontSpaceSlider;
    

    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);
        */
        
};



ofApp.cpp

#include "ofApp.h"


//--------------------------------------------------------------
void ofApp::setup(){
    
    myFont.loadFont("HMFMPYUN.TTF", 64, true, true);

    gui.setup();
    gui.add(fontSpaceSlider.setup("font latter spaceing", myFont.getLetterSpacing() , 0.0f , 2.0f ));
    fontSpaceSlider.setSize(300, 30);
}

//--------------------------------------------------------------
void ofApp::update(){
    //자간 조절
    myFont.setLetterSpacing(fontSpaceSlider);
}

//--------------------------------------------------------------
void ofApp::draw(){
    ofSetColor(ofColor::red);

    myFont.drawString("안녕 !", 100, 150);

    ofSetColor(ofColor::green);
    myFont.drawStringAsShapes("하세요?", 100, 250);

    ofSetColor(ofColor::blue);
    myFont.drawString("supersc", 100, 350);

    gui.draw();
}







Yamecoder 야매코더_
C++(oF) 2016.01.08 17:42

[작성중] FTGL 과 한글Automata 를 이용한 한글입력


http://scripter.co.kr/328 에 에드온을 이용한 한글 출력 방법이 있습니다.






본 포스트는 아직 작성중 입니다. This Post is not completed.

(밥벌이와 상관이 없어서, 짬 날때 마다 합니다. 언제 업데이트 될지는 모릅니다.)



* 필요한 리소스

한글 렌더링 라이브러리 : ofxFTGLFont ( http://yamecoder.tistory.com/?page=2 )

한글 오토마타 : ( http://srctalk.imfree.co.kr/view.ife?seq=615 )




* 필요한 사전 지식

문자열 인코딩 변환 : http://icartsh.tistory.com/13#recentTrackback

Array to string : http://stackoverflow.com/questions/8960087/how-to-convert-a-char-array-to-a-string

string to Array :http://stackoverflow.com/questions/13294067/how-to-convert-string-to-char-array-in-c






*어려움 

 - 오토마타에서 건내주는 string 이 FTGL 에서 사용하는 문자열 인코딩이 아니다(UTF8). 따라서 바로 drawString 통해 출력시 글자가 깨진다.

 - 특수문자 ("?" , "!" 등등) 을 입력 할 경우 오류상황. 현재 키보드 스테이트를 확인 해야 한다.

 - 문자열 길이에 맞게 변환에 쓰일 배열 크기 조절 (이건 뭐.. 어렵지는 않음)



*작성중인 테스트 코드 (스피트 테스트 용 , 작성중)

기저 아이디어 : 오토마타 -> 멀티바이트 변환 -> UTF8 변환 -> FTGL 출력



#include "ofApp.h"
#include "KorAutomata.h"
#include "utf8.h"
#include "ofxFTGLFont.h"

using namespace RBAUTOMATA;
CKoreanAutomata Automata;
ofxFTGLFont font;
wstring wstr = L"";

string resultStr;
//--------------------------------------------------------------
void ofApp::setup(){
    
    font.loadFont("batang.ttc" , 10);
}

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){
    ofSetColor(ofColor::blue);
    font.drawString(resultStr , 0 , 100);
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}


//--------------------------------------------------------------
void ofApp::keyReleased(int key){
    
    string outStr ="";  
    Automata.KeyPush(key);
    unsigned short RealCode = Automata.GetConvertedUnionCode();

    if(Automata.State())
    {
        char buff[3] = {RealCode & 0x00ff , RealCode >> 8 , 0};
        string whileInputKor(buff);
        outStr += Automata.GetStringBuffer() + whileInputKor;
    }else{
        outStr += Automata.GetStringBuffer();
    }
    

    wchar_t strUnicode[1024] = {0,};
    char    strMultibyte[1024] = {0,};
    strcpy_s(strMultibyte,1024,outStr.c_str());

    int nLen = MultiByteToWideChar(CP_ACP, 0, strMultibyte, strlen(strMultibyte), NULL, NULL);
    MultiByteToWideChar(CP_ACP, 0, strMultibyte, strlen(strMultibyte), strUnicode, nLen);

    char strUtf8[1024] ={0,};
    nLen = WideCharToMultiByte(CP_UTF8, 0, strUnicode, lstrlenW(strUnicode), NULL, 0, NULL, NULL);
    WideCharToMultiByte (CP_UTF8, 0, strUnicode, lstrlenW(strUnicode), strUtf8, nLen, NULL, NULL);

    string out(strUtf8);
    resultStr = out;
}

//--------------------------------------------------------------
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::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){ 

}


Yamecoder 야매코더_
C++(oF) 2015.08.03 16:31

oF 에서 FTGL 을 통한 한글 출력

해당하는 에드온은 

https://github.com/Flightphase/ofxFTGL

이다.


FTGL 은 유니코드를 사용함으로 폰트만 있다면, 운영체제에서 지원하는 모든 문자를 표현 할 수 있다.




#include "ofApp.h"
#include "ofxFTGLFont.h"


ofxFTGLFont font;
//--------------------------------------------------------------
void ofApp::setup(){
    font.loadFont("batang.ttc" , 32 );
}

//--------------------------------------------------------------
void ofApp::draw(){
    font.drawString(L"한글ABC" , 0 , 100);
 }


batang.ttc 는 빌드된 폴더안의 data 폴더에 넣으면 된다.

기본적인 사용법은 ofTrueTypeFont 와 유사하다.

Yamecoder 야매코더_
C++(oF) 2015.07.20 23:58

Xcode 에서 Homebrew 를 통해 OpenCv 설치 하기

http://www.theworldneedsmoredreamers.net/using-opencv-2-with-os-x-hello-world/

Yamecoder 야매코더_
C++(oF) 2015.06.14 17:24

[OpenCv] Static 으로 빌드하여 배포 환경에 맞추기. (별도의 DLL 필요없음)

OpenCv 를 빌드 하고 배포 하려면 배포컴퓨터에 OpenCv를 설치하고 환경 변수를 맞춰 주거나, DLL 들을 함께 배포 하여야 한다.

솔루션 크기도 커지고 여간 불편한것이 아니다.


그래서 다크프로그래머[http://darkpgmr.tistory.com/50] 님의 글을 보고 Static 빌드를 시도해 봤다.

Static 빌드를 하면, 배포 컴퓨터에 별도의 추가 작업 없이 실행이 가능하다.



1. 프로젝트 속성 /MT , /MTd 로 바꾸기 (/MTd 는 디버그 용 이다.)



2. 프로젝트 Path 설정

1) C/C++  ->  General  ->  Additional Include Directories  => [C:\opencv\build\include] 추가

2) Linker  ->  General  ->  Additional Library Directories => [C:\opencv\build\x86\vc11\staticlib] 추가 (x64로 해도 된다.)

3) 3) Linker  ->  Input  ->  Additional Dependencies  => 

[

IlmImfd.lib

libjasperd.lib

libjpegd.lib

libpngd.lib

libtiffd.lib

opencv_calib3d2411d.lib

opencv_contrib2411d.lib

opencv_core2411d.lib

opencv_features2d2411d.lib

opencv_flann2411d.lib

opencv_gpu2411d.lib

opencv_highgui2411d.lib

opencv_imgproc2411d.lib

opencv_legacy2411d.lib

opencv_ml2411d.lib

opencv_nonfree2411d.lib

opencv_objdetect2411d.lib

opencv_ocl2411d.lib

opencv_photo2411d.lib

opencv_stitching2411d.lib

opencv_superres2411d.lib

opencv_ts2411d.lib

opencv_video2411d.lib

opencv_videostab2411d.lib

zlibd.lib

]


staticlib 에 있는 모든 lib 파일을 링크 한다. 역시나 말미에 [d] 는 디버그 용이니 릴리즈 용 구성시 d 를 뺀 리스트를 추가 한다.




추가 

1. Static 구성중 [cvCaptureFromCAM] 접근시 LNK2019 ,,, cap_vfw.obj 관련된 highgui 쪽 에러가 난다면,


#pragma comment(lib, "vfw32.lib")
#pragma comment( lib, "comctl32.lib" )

를 헤더에 추가해 준다.

(원문 : http://stackoverflow.com/questions/13472294/opencv-243-using-static-libs-error-lnk2019)



2. [ error C4996: 'fopen' .... ] 관련 에러가 뜰 경우

 C/C++  ->  Preprocessor  ->  Preprocessor Definitions => (추가) _CRT_SECURE_NO_WARNINGS

를 해준다.




/부록 (릴리즈용 lib 리스트)

IlmImf.lib

libjasper.lib

libjpeg.lib

libpng.lib

libtiff.lib

opencv_calib3d2411.lib

opencv_contrib2411.lib

opencv_core2411.lib

opencv_features2d2411.lib

opencv_flann2411.lib

opencv_gpu2411.lib

opencv_highgui2411.lib

opencv_imgproc2411.lib

opencv_legacy2411.lib

opencv_ml2411.lib

opencv_nonfree2411.lib

opencv_objdetect2411.lib

opencv_ocl2411.lib

opencv_photo2411.lib

opencv_stitching2411.lib

opencv_superres2411.lib

opencv_ts2411.lib

opencv_video2411.lib

opencv_videostab2411.lib

zlib.lib



Yamecoder 야매코더_
C++(oF) 2015.06.03 14:34
Powerd by Tistory, designed by criuce
rss