For openFrameworks Users

openFrameworks
사용자 위한
TrussC 입문

oF를 좋아하셨다면, TrussC도 좋아할 것입니다.

TrussC는, openFrameworks가 개척한 <크리에이티브 코딩의 즐거움>을 깊이 존중합니다.

하지만 oF가 설계된2000년대와 지금은, 하드웨어도 C++도 크게 변했습니다.
TrussC는 oF의 정신을 계승하면서도 오늘날의 환경에 최적화된, 앞으로의 10년을 위한 발판입니다.

변하지 않는 것

oF사용자라면 익숙하게 시작할 수 있습니다.

setup, update, draw

크리에이티브 코딩의 기본 리듬, 이 구조는 그대로 유지합니다.

ofApp tcApp

익숙한 메소드명

학습곡선을 최소화 하기 위해, 메소드명을 유지했습니다.

ofDrawCircle(x, y, r) drawCircle(x, y, r)

XCode / VS / VSCode 지원

여러분의 최고의 IDE를 고르세요. 물론, Cursor도 지원합니다.

CMake + clangd

oF에서의 불편한 지점을 해결했습니다.

오랫동안 괴롭혔던 문제들에 대한 TrussC의 해결책.

문제들

OpenGL은 macOS에서 더이상 지원되지 않습니다.

Apple은 OpenGL을 버리고 Metal로 전환했습니다.
앞으로의 호환성과 성능 최적화는 불투명해졌습니다.
가장 중요한 질문은 이겁니다 - 언제 지원이 완전히 끊길것인가?

TrussC의 해결책

Sokol를 통한 네이티브 백엔드

Metal / DirectX 12 / Vulkan / WebGPU을 사용합니다.
각 OS의 네이티브 API 위에서 구동되므로 고성능과 고효율이 보장됩니다.
WebAssembly + WebGPU를 지원하기 때문에 브라우저로의 이식률도 높습니다.

문제점

상업용도일 경우 라이선스에 대한 고민

oF 자체는 MIT라이선스이지만, 의존 라이브러리 중에는 GPL이 포함되어있습니다.
FFmpeg, FreeType 등의 라이선스를 일일히 확인하는것은 번거롭습니다.
클라이언트 작업에 사용할 때 라이선스 리스크가 불분명합니다.

TrussC의 해결책

MIT / zlib / Public Domain만 사용

철저한 GPL 프리.
모든 종속 라이브러리는 상업적 사용에 친화적입니다.
안심하고 클라이언트 작업에 사용할 수 있습니다.

문제점

수동 부모-자식 관리

ofNode는 있지만, 부모-자식 관계를 수동으로 관리해야 합니다.
자식 노드를 추가/제거할 때 메모리 관리가 복잡해집니다.
부모가 삭제되었지만, 자식이 남아버리는 문제가 생기기도 합니다.

TrussC의 해결책

shared_ptr 기반으로 자동 관리

// shared_ptr 기반으로 자동 관리
auto parent = Node::create();
auto child = Node::create();
parent->addChild(child);

// 부모를 삭제하면, 자식이 자동으로 해제됩니다.
// 순환 참조도 weak_ptr를 사용해 안전하게 회피합니다.
문제점

"3초 뒤 실행" 을 안전하게 할 방법이 없습니다

ofThread는 데이터 경쟁(data race)을 일으키기 쉽습니다.
"N초 뒤 실행" 을 안전하게 수행하는 표준화된 방법이 없으며,
update() 내에서 시간을 측정해 if문을 쓰면 코드가 지저분해 집니다.

TrussC의 해결책

메인 스레드에서의 안전한 동기화 타이머

// 메인 스레드에서 안전하게 딜레이를 실행
node->callAfter(3.0f, []() {
    // 메인 스레드 위에서 3초 후 수행됨
    // Mutex가 필요하지 않고, 데이터 경쟁에 대한 걱정도 없습니다.
});

// 반복 실행도 역시 쉽습니다.
node->callEvery(1.0f, []() {
    // 매 1초마다 실행됨
});
문제점

그릴 수 없는 굵은 선

ofSetLineWidth()는 OpenGL의 한계로 1px 이상의 두꼐는 보장되지 않습니다.
macOS / Metal에서는 완전히 무시됩니다. 굵은 선을 그리려면 메시를 직접 생성해야 했습니다.

TrussC의 해결책

내장된 굵은 선 그리기

간단히 beginStroke() / endStroke()을 사용하면 됩니다.
line cap과 join도 자동으로 깔끔하게 처리됩니다.

// beginStroke/endStroke 을 사용해 아름다운 굵은선을 그린다.
setStrokeWeight(5.0f);  // 5px의 굵은 선
beginStroke();
vertex(0, 0);
vertex(100, 50);
vertex(200, 0);
endStroke();  // cap과 join은 자동

시작하기

oF사용자라면, 익숙합니다.

폴더 구조

TrussC의 디렉토리 구조는 oF와 아주 비슷합니다.
예제, 애드온 등등 익숙한 구성을 갖추고 있습니다.

openFrameworks

of_v0.12.0/
├── addons/
├── apps/
│   └── myApps/
│       └── myProject/
├── examples/
├── libs/
├── projectGenerator/
└── scripts/

TrussC

TrussC/
├── addons/
├── apps/
│   └── myApps/
│       └── myProject/
├── examples/
├── trussc/
├── projectGenerator/
└── scripts/

projectGenerator

oF와 마찬가지로, projectGenerator를 사용해 프로젝트를 생성할 수 있습니다.
클래식한 oF처럼 보일 수 있지만, 기능은 완전히 최신입니다.

TrussC projectGenerator

작성만 하면 됩니다.

프로젝트를 생성하고 나면, 이전처럼 setup / update / draw 를 작성하면 됩니다.
ofApptcApp로, ofDrawCircledrawCircle로 이름만 바꼈을 뿐,
코딩 작성은 거의 동일합니다.

void tcApp::setup() {
    // 평소처럼 setup
}

void tcApp::update() {
    // 평소처럼 update
}

void tcApp::draw() {
    clear(0.1, 0.1, 0.1);
    setColor(1, 0.5, 0);
    drawCircle(getWindowWidth()/2, getWindowHeight()/2, 100);
}

별 차이 없죠?
oF에서의 코딩방식은 TrussC에서도 다르지 않습니다.

API 레퍼런스

oF의 함수, TrussC에서는 이렇게 씁니다.

API 레퍼런스를 불러오는 중...

준비됐나요?

oF에서의 경험은 그대로 유지됩니다.