블로그

[openFrameworks] 텍스트 파일 화면에 그리기 본문

openFrameworks

[openFrameworks] 텍스트 파일 화면에 그리기

confielder 2021. 12. 23. 20:17

openFrameworks에서 파일을 읽고 쓰기 위해서는 ofBuffer라는 클래스를 사용하면 된다. 

 

이는 C++의 파일 입출력을 간단한 함수만으로 표현할 수 있으며, C++ 특유의 신경 써야 할 것이 많은 문자열 받아오기 등을 편하게 함수로 구현할 수 있다는 것이 장점이다.

setup()

//ofApp.cpp
void ofApp::setup() {
    nextLetterTime = ofGetElapsedTimeMillis();
    lineCount      = 0;
    letterCount    = 0;
    
    ofBuffer buffer = ofBufferFromFile("ohplaces.txt");
 
    if(buffer.size()) {

		for (ofBuffer::Line it = buffer.getLines().begin(), end = buffer.getLines().end(); it != end; ++it) {

			string line = *it;

            if(line.empty() == false) {
                seussLines.push_back(line);
            }
        }
    }
}

우선 nextLetterTime , lineCount , letterCount는 각각 해당 문자열의 다음 문자를 그리는 시간 , 몇 번째 줄인지 , 몇 번째 문자인지 를 타나 내는 것으로 update() 구문에서 자세히 다룬다.

 

 

다음으로 ofBuffer 클래스를 사용하는데 ofBufferFromFile이라는 함수를 사용하여 불러오며, 매개변수에서 지정한 파일을 버퍼로 읽는다(버퍼는 일시적으로 데이터를 보관하는 메모리로 데이터를 이동시킬 때 사용된다.)

 

 

다음 줄에 if(buffer.size()) 즉 파일에 문자가 있다면 스트링 변수에 한 줄 단위의 문장을 넣고, 넣은 문장을 벡터에 푸쉬 해주는 코드이다.

 

for (ofBuffer::Line it = buffer.getLines().begin(), end = buffer.getLines().end(); it != end; ++it) {
	string line = *it;
}

 

여기서 iterator를 사용하여 for문을 돌리는데 우선 iterator는 쉽게 말하면 배열을 가리키는 포인터로, 배열의 내용 하나하나를 순회할 때 사용된다.

 

getLines()를 통하여 한 줄(단어 한 개씩 아님)씩 저장하여 string line에 넣는데 여기서 *it는 it 가 포인터인 이유로 값을 넣기 위해 *it를 사용하였으며

 

if(line.empty() == false) {
	seussLines.push_back(line);
}

만약 라인이 비어있지 않다면 문장을 seussLines에 푸쉬하고 다음 문장이 있으면(++it가 다음 문장을 가리킴) 또 다음 문장이 string line에 들어오고 그걸 다시 seussLines에 저장하는 과정이다.

draw()

//#ofApp.cpp
void ofApp::draw() {

    string typedLine = seussLines[lineCount].substr(0, letterCount);
    ofDrawBitmapString(typedLine, 100, 100);
    
    float time = ofGetElapsedTimeMillis() - nextLetterTime;
    
    if(time > 11) {
        
        if(letterCount < (int)seussLines[lineCount].size()) {
           
            letterCount ++;
            nextLetterTime = ofGetElapsedTimeMillis();
        }
        else {
            
            if(time > 300) {
                
                nextLetterTime = ofGetElapsedTimeMillis();
                letterCount = 0;
                lineCount ++;
                lineCount %= seussLines.size();
				
            }
        }
    }
}

Draw()에서는 본격적으로 짧은 딜레이를 주면서 한문자 한문자씩 화면에 그린다. 

 

여기서 주의 깊게 생각할 것은 (1). 어떻게 문장 단위를 문자 하나하나로 표현하지? , (2). 시간을 활용하는 법 ,

(3). 다음 문자로 넘어가는 알고리즘 등등을 배울 수 있다.(하지만 가장 중요한 건 ofBuffer 클래스의 활용..)

 

    string typedLine = seussLines[lineCount].substr(0, letterCount);
    ofDrawBitmapString(typedLine, x+4, y+11);

typedLine은 substr()를 사용하였으며, 이는 문자열의 문자 일부분을 리턴하는 것으로 첫 번째 매개변수와 두 번째 매개변수 사이의 문자를 반환한다. 따라서 주의 깊게 생각할 것 1번은 이 코드에서 해결되며 letterCount를 어떻게 설정하는지는 다음 코드 블록에서 본다.

 

DrawBitmapString은 간단하니깐 생략.

 

    float time = ofGetElapsedTimeMillis() - nextLetterTime;
    
    if(time > 11) {
        
        if(letterCount < (int)seussLines[lineCount].size()) {
           
            letterCount ++;
            nextLetterTime = ofGetElapsedTimeMillis();
	}

여기서부터 알고리즘 느낌이 나는데 우선 time이라는 float 변수가 있고 이 타임은 한 문장문자 하나를 입력한 뒤 초기화되고 다시 11ms의 딜레이 후 문장의 2번째 문자가 나오고 초기화되고의 반복이다. 

 

한마디로 문자 하나하나를 그리는데 걸리는 딜레이라고 할 수 있다. 

 

else { 
          if(time > 300) { 
              nextLetterTime = ofGetElapsedTimeMillis();
              letterCount = 0;
              lineCount ++;
              lineCount %= seussLines.size();	
            }
        }

문장의 끝에 도달해서 더 이상의 문자가 없다면 else문으로 넘어간다.

 

300ms의 딜레이 후에, letterCount 가 0 , lineCount 가 1이 되며 즉 다음 문장의 첫 번째 문자로 넘어가는 것이다.

재밌는 점으로는 lineCount %= seussLines.size()를 통해 문자열 끝에 도달하면 다시 lineCount가 0이 되어 처음부터 반복하는 코드도 작성했다. 

마치며

of 공식 예제를 지금까지 3개 정도 분석하면서 다른 사람이 만든 코드를 빠르고 효율적으로 이해하는 방법이 어느 정도 늘었다.

 

우선 이 예제를 통해 배울 수 있는 점을 생각하고, 전체적인 코드가 어떤 식으로 돌아가는지 생각한 뒤에 자잘 자잘한 함수나 알고리즘 등을 분석하는 것이 효율적이었으며, 앞서 말한 것들 중 순서가 하나라도 바뀐다면 너무 많은 시간을 허비하게 되는 것 같더라.

 

2번째 뮤직비디오 제작에 꼭 필요한 기능들을 오늘 배웠으니 다음에는 내가 직접 만든 작품을 분석하는 글을 올려야겠다.

 

 

 

'openFrameworks' 카테고리의 다른 글

뮤직비디오 작업기 1일차 - 파티클 각자의 포지션 만들기  (0) 2021.11.23
짧은 코드2  (0) 2021.11.19
짧은 코드  (0) 2021.11.18
openFrameworks 이미지에 대해  (0) 2021.11.17
openFrameworks 에서의 진동(회전)  (0) 2021.11.12