전체 글 35

[게임 프레임워크 개발 일지] #8 편식 안 하고 뭐든 잘 먹는 Event

지난 포스팅에 이어서, return type / parameter type이 무엇이든 상관 없이 함수를 할당할 수 있는 Event를 설계할 겁니다. 정확히는, 지난 포스팅에서 std::vector를 parameter로 받는 void 함수만을 받도록 해서 구현했고 이번에는 정말 그 type이 뭐가 되든 상관 없는 Event를 구현해볼 겁니다. 미리 결론부터 봅시다. 그래서 구현 가능한가요? 일부는 예, 일부는 아니오 입니다. 다시 말하면 나름 구색은 갖출 정도로 구현은 가능하지만, 제약이 있습니다. 그럼 천천히 살펴봅시다. 제 기준이지만, 내용이 꽤 어렵습니다. 구현하고 싶은 결과물을 코드로 나타내면 이렇습니다. Event e([](int a, int b) { cout 그렇기 때문에, lambda 식은 이..

C++/Game 2022.07.24

[게임 프레임워크 개발 일지] #7 Variadic Template과 Lambda

게임 프레임워크에 한정되는 이야기는 아니지만, 개발하면서 헤매던 내용이라 정리할 겸 포스팅으로 올립니다. template은 어떤 타입이 함수나 클래스에 오더라도 대응할 수 있게 해줍니다. 그만큼 강력하고, 또 그만큼 어렵습니다. 제 게임 프레임워크에서 template을 주로 사용하는 클래스는 Entity와 Event 였습니다. Entity는 Component로 구성되어 있습니다. 벽과 상자는 모두 충돌 판정이 필요하고 (Collidable), 그릴 그래픽이 있지만 (Drawable) 벽은 이동하지 않고 상자는 플레이어가 민다든지 하는 작용으로 이동할 수도 있습니다 (Movable). 상호작용이 필요할 수도 있겠네요. (Interactable) 물론 게임마다 다르겠지만 말입니다. 괄호 속에 병기한 클래스들..

C++/Game 2022.07.20

[JUCE] Juce Framework로 사운드 프로그래밍 #7 Pitch Shift

음의 높낮이는 주파수에 따라 정해집니다. 주파수가 높으면 높은 음, 낮으면 낮은 음이 됩니다. 그래서 신디사이저에서 음의 높낮이를 조절하려면, wavetable을 훑는 delta 값을 조절해줘야 합니다. //prepare auto frequency = 440.0 * pow (2.0, (midiNote - 69.0) / 12.0); auto cyclesPerSample = frequency / sampleRate; delta = cyclesPerSample * juce::MathConstants::twoPi; //render currentSample = std::sin (currentAngle); currentAngle += delta; if (currentAngle >= juce::MathConstant..

C++/Sound 2022.07.11

[JUCE] Juce Framework로 사운드 프로그래밍 #6 ADSR

신디사이저에서는 사운드를 만드는 Oscillator 파트 외에도 그 사운드에 간단한 효과를 입히는 FX 파트가 있습니다. LFO, Filter부터 시작해서 Distortion이나 Reverb 등을 신디사이저 내에 구현하기도 합니다. 당장 이미지로 올린 Serum 부터가 그러하고요. 여기서는 그 중 가장 기본적인 ADSR에 대해 다룰 겁니다. 신디사이저를 다룰 때 잠깐 언급만 했습니다. ADSR은 Attack, Decay, Sustain, Release를 말합니다. 신디사이저에서 사운드를 재생하기 시작한 시점에서 끝나는 시점까지의 4단계입니다. Panning이나 Pitch 등에도 ADSR을 적용할 수 있지만 주로 Volume에서 많이 볼 수 있습니다. 여기서는 Volume을 예시로 설명하겠습니다. Atta..

C++/Sound 2022.07.10

[JUCE] Juce Framework로 사운드 프로그래밍 #5 GUI

GUI는 개발자가 프로그램을 개발하는데 있어서 가장 귀찮은 부분일겁니다. 이벤트 처리도 그렇고, 그래픽을 그럴듯하게 구현하는 것이 직관적이지 못하기 때문입니다. 다행히도 Juce에서는 기본적인 GUI를 지원합니다. GUI의 종류를 각각 설명하고, 공통적인 사용법을 다루겠습니다. 1. Text 일반적인 Text는 juce::Label을 이용하면 됩니다. juce::Label label; label.setText("Text", juce::dontSendNotification); label.setJustificationType(juce::Justification::centred); label.attachToComponent(&component, false); setText에서 두번째 parameter는 이벤트..

C++/Sound 2022.07.02

[JUCE] Juce Framework로 사운드 프로그래밍 #4 Processor와 Value Tree

가상악기는 Standalone으로 쓰기보다는 DAW 프로그램에서 불러와서 쓰기 마련입니다. 그래서 DAW 프로그램과 연동시킬 수 있도록 프로그래밍하는 것이 중요합니다. 바로 그 부분을 담당하는 곳이 Processor와 ProcessorEditor입니다. 이전 포스팅에서 이야기했듯이, Processor가 사운드 프로세싱을 한다면, ProcessorEditor는 GUI를 그립니다. Processor는 그 외에도 프로그램에 관련된 데이터를 저장하고 불러오는 기능도 하는데, 함수 getStateInformation과 setStateInformation을 사용합니다. 우리는 이 함수에다 무슨 데이터를 저장하고 불러올지만 작성해주면 됩니다. 데이터는 XML로 저장되고, JUCE에서도 juce::XmlElement ..

C++/Sound 2022.06.24

[JUCE] Juce Framework로 사운드 프로그래밍 #3 신디사이저 만들기

소리를 재생해봅시다. 지난 포스팅에서 이야기했듯이, JUCE에서 사운드를 만들어내려면 juce::Synthesiser를 이용해야 합니다. 다만 정확히는 만들어낸 사운드를 Synthesiser를 통해서 내보낸다는 느낌에 가깝고, 사운드를 만들어내는 것 자체는 Voice에서 이루어집니다. Synthesiser에 보내줄 사운드는 Voice에서 만들고, Voice에서는 Sound 소스를 받아서 렌더링합니다. 만들 사운드의 특징은 Sound에 저장하고, Voice에서는 그런 Sound를 받아 렌더링을 한 뒤에, 연결된 Synthesiser로 보내주는 겁니다. 사운드가 만들어지는 과정부터 천천히 알아봅시다. 이미지가 각 좌표에 해당하는 픽셀 값으로 이루어져 있듯이, 사운드는 각 시간대에 재생할 진폭의 값으로 이루어..

C++/Sound 2022.06.12

[JUCE] Juce Framework로 사운드 프로그래밍 #2 구조 대충 알아보기

먼저, JUCE를 이용해 Audio Application을 만들 때 고려할 사항을 정리해봅시다. Plugin과의 가장 큰 차이점이라고 한다면, 아마도 Processor가 없다는 점일 겁니다. 간단히 말해서, MIDI 데이터를 받아오고, 사운드를 내보낼 Component가 필요합니다. 물론 JUCE에서 제공하는 템플릿으로 생성했다면 MainComponent라고 이미 생성이 되어 있을 겁니다. class MainComponent : public juce::AudioAppComponent { public: MainComponent(); ~MainComponent() override; void prepareToPlay(int samplesPerBlockExpected, double sampleRate) over..

C++/Sound 2022.06.08

[JUCE] Juce Framework로 사운드 프로그래밍 #1 프로젝트 만들기

프로그래밍할 때 가장 동기를 잘 부여해주는 것은 시청각적인 결과물이라고 생각합니다. 검은 콘솔 창에서 Hello World! 나 띄우고 있는 건 얼마나 고리타분합니까. 제가 그림을 보여주고 소리를 재생하는 걸 좋아하는 이유입니다. 심심해서 이전에도 가상 악기 플러그인을 만들어 본 적이 있고, 최근에도 하나 시작했었는데 거기서 막혔던 부분이 좀 많아서 정리하는 김에 포스팅합니다. 위에서 링크한 리포지토리는 VST GUI라는 걸 사용합니다. 오래됐고, 사용법도 찾아보기가 어렵습니다. 만들다 버린 프로젝트에 가깝습니다. 요즘 VST 같은 사운드 프로그래밍을 하는 데에는 Juce 만한게 없는 것 같습니다. GUI를 대부분 쉽게 지원해준다는 점이 좋네요. 전 다른 것보다도 UI가 정말 귀찮습니다. 홈페이지에서 J..

C++/Sound 2022.06.05

[게임 프레임워크 개발 일지] #6 SFML의 버튼 GUI와 죽이고픈 마우스 이벤트

SFML에서는 공식적으로 제공하는 GUI가 없습니다. SFML은 멀티미디어 라이브러리지, GUI 라이브러리가 아닙니다. 물론 구글링을 조금만 해도 구현하는 예시들을 많이 찾아볼 수 있지만, 정해진 길이 없다는 것이 난처합니다. 게임을 만들다보면 으레 필수가 되는 GUI들은 여기서도 미리 구현을 해두려고 합니다. Button이나 TextInput 같은 게 있겠네요. 지난 포스트에서 긁어와서 쓴 RichText 또한 이런 부류에 해당됩니다. 이번에는 Button을 만들겠습니다. 제목에서 죽이고픈 마우스 이벤트라고 했듯이, 구현할 게 많아서 시간을 좀 오래 썼고 포스팅을 오래 안 한 이유이기도 합니다. 구현이 어려운 건 아니지만, 너무 귀찮거든요. * 글을 다 쓰고 느꼈습니다. 구현도 어렵네요. * Butto..

C++/Game 2022.05.15