전체 글 35

[게임 프레임워크 개발 일지] #18 Clipping Mask

TextInput을 구현할 때 glScissor를 사용해서 Clipping을 구현했었고, 그 외에는 SFML의 RenderTexture에서 BlendMode 같은 걸 사용했었습니다. 그런데 TextInput에 transform을 적용해서 회전하거나 비율이 달라져도 glScissor에는 적용되지 않는다는 문제를 발견했습니다. 특히 회전하는 경우에는 직사각형 형태로 클리핑할 수가 없기 때문에, 새로운 방법이 필요했습니다. 사실 SFML에는 2.0 초창기부터 Clipping Mask에 대한 기능 요구가 있었습니다만, 다른 기능들과의 호환성 문제 때문인지 Clipping Mask가 구현된 fork까지 있음에도 불구하고 적용되지 않았습니다. 근데 이걸 이제야 3.0에서 구현하고 있더군요. 그래서 깃허브에서 cli..

C++/Game 2024.02.19

[게임 프레임워크 개발 일지] #17 Window 이것저것 수정하기

지금까지 작업한 걸로 뭔가 만들어보려다 바로 에러가 나서 다시 수정할 필요성을 느꼈습니다. 1. Event mutex 처리 디버그 중에 가끔씩 프로그램을 종료할 때 mutex destroyed while busy 에러가 발생해서 알아보다가 문제를 발견했습니다. 이 에러 자체는 mutex가 lock인 상태에서 프로그램이 종료되는 등의 문제로 강제로 mutex가 삭제될 때 발생합니다. 실험을 해보니 디버그 중에만 에러 메시지가 나오고, 릴리즈 모드일 때 에러가 발생하지는 않습니다. Window를 닫는 도중에 렌더나 이벤트 호출이 발생하면 안 된다는 생각에 두 mutex를 잠그고 끄게 했는데, 메인 쓰레드에서 이벤트를 호출하는 도중에 시스템 쓰레드에서 윈도우를 종료하면 데드락이 걸려서 발생하는 문제였습니다. ..

C++/Game 2024.02.18

[게임 프레임워크 개발 일지] #16 일단 마무리

최근에 개발을 마무리지었습니다. 쓰다 보면 또 부족한 게 무더기로 나올 느낌이지만, 일단은 말입니다. 사실 포스팅으로 쓸 건 없는데 마무리는 해야 되겠다 싶어서 글을 씁니다. 1. 윈도우가 여러 개일 때 루프 처리 일반적으로는 윈도우는 하나만 띄워둡니다만, 윈도우를 Entity로 추가한 이상 여러 개가 동시에 있는 것도 구현을 해야겠죠. 실제 인게임은 Scene의 loop로 돌아가니, 메인에서 렌더링만 처리해줬습니다. //previous version while (window->isRenderable()) { sf::Time delta = clock.restart(); loop(delta.asSeconds()); window->render(); } -> while (true) { auto windows ..

C++/Game 2023.08.09

[게임 프레임워크 개발 일지] #15 지옥의 Multithread와 메모리 관리

이전에 시스템 이벤트 처리와 렌더링 루프를 멀티쓰레드로 분리했습니다. 무려 #2에서 말입니다. 그 이후로 이벤트 트리거나 ECS를 구축하면서 발견한 문제가 있습니다. 이벤트 처리에서 race condition이 발생합니다. 이걸 인지한 지는 오래됐는데, 작업 목록에 UNDONE 박아 놓고는 신경을 안 쓰고 있었습니다. 내가 선택한 업보가 이제 돌아왔군요 #2에서 렌더링 관련 race condition을 어느 정도 해결하려 했고, 해결하긴 했습니다만 사실 엉성하게 코드를 짜놓아서 재검토할 필요가 있었습니다. 상황을 간단히 정리하면 이렇습니다. 1. 시스템과 인게임의 쓰레드를 분리해놓았다. 2. 시스템 쓰레드와 렌더(인게임) 간에 문제가 발생한다. (race condition) 3. 시스템 쓰레드와 인게임 ..

C++/Game 2023.07.02

[게임 프레임워크 개발 일지] #14 Sound Panning에 관한 삽질

일단 Sound Manager를 만들던 과정부터 설명해야겠네요. SFML에서는 sf::Sound와 sf::Music을 지원합니다. sf::Sound는 메모리에 데이터를 통째로 올려놓고 재생시키는 방식이고, sf::Music은 재생할 때 파일에서 짧은 분량 (1초 정도)을 스트리밍하듯이 매번 불러와서 재생하는 방식입니다. 효과음처럼 짧은 소리는 sf::Sound를, 길이가 긴 배경음악은 sf::Music을 사용하라는 뜻이죠. 대부분의 게임을 대상으로 한 사운드 라이브러리가 이런 방식을 지원합니다. 공식 튜토리얼에서도 사람들이 자주하는 실수라고 언급하는 내용이지만, sf::Sound에는 사운드 데이터가 저장되어 있지 않고, sf::SoundBuffer에 저장해놓습니다. sf::Sprite와 sf::Textu..

C++/Game 2023.06.11

[게임 프레임워크 개발 일지] #13 Collider System

2D Collider를 만들고, Broadphase까지 적용한 건 좋았는데 그래서 캐릭터와 벽이 충돌하는 건 언제 볼 수 있느냐가 문제입니다. Entity 간의 상호작용이므로, 충돌 상호작용을 전담할 System을 설계해야 합니다. 여기서 만들 Collider System은 (처리할 Scene 내의) Entity 목록을 받아와서 1. 각 Entity의 collider boundary를 계산해서 AABB를 만들고 2. 그 AABB에 대해 broadphase를 거친 뒤에 3. 실제 collider 끼리 비교해서 충돌한 두 Entity pair에게 Collided Event를 호출해야 합니다. 여기서 Entity가 collider를 갖고 있어야 하니, Collidable이라는 Component를 가진 Enti..

C++/Game 2023.05.26

[게임 프레임워크 개발 일지] #12 코드와의 재회는 최악이었다

오랜만입니다. 어떻게 이게 2023년 첫 글이 될 수 있으며, 지난 글과 7~8개월 정도 차이가 날 수 있을까요. 그동안 어디서 굴러먹다 왔느냐 하면, 음악을 하고 있었습니다. 곡 투고하느라 몇 개월을 고생했고, 그 와중에 2~3주마다 외주를 했습니다. 그러고 오랜만에 코드를 살펴보는데, 영 이상한 게 있어서 갈아엎었습니다. 다 갈아엎은 건 아니고, Event 메커니즘만 바꿨습니다. 이번 글은 뭘 새로 만들었다 라는 내용보다는, 기존에 있던 걸 새로 만들었다는 내용입니다. 그냥 생존 신고 같은 거죠 뭐 이전에는 EventManager과 Event만 있어서, Manager에 Event를 추가하고 Manager에 특정 EventType을 트리거시키면 등록된 Event를 호출하는 방식으로 구현했었습니다. 근데..

C++/Game 2023.05.26

[게임 프레임워크 개발 일지] #11 충돌 시스템 개선하기 - Broad Phase

2D 충돌 알고리즘에 대해서는 이전 포스팅에서 다뤄본 적이 있습니다. 실제로 사용하려면, 각 Entity마다 Collider를 할당하고, pair에 대해서 충돌하는지 검사해주면 됩니다. 그런데 막상 사용하려고 코드를 짜보니 이중 for 문에 O(N^2)이 나오더군요. 무식하게 pair를 만들고 다 비교하려고 해서 그렇습니다. Brute Force는 대충 다음처럼 돌아갑니다. for (int i = 0; i < colliders.size(); i++) { for (int j = i + 1; j < colliders.size(); j++) { if (Collide(colliders[i], colliders[j])) { //collide } } } Collider를 만들 때 QuadTree를 사용해서 최적화를..

C++/Game 2022.10.05

[게임 프레임워크 개발 일지] #10 Text Input은... 서비스 종료다

그간 개발을 좀 쉬었습니다. 갑자기 음악에 삘이 꽂혀서 그거 하느라인 것도 있고, 몸이 안 좋아서 쉰 것도 있고 Text Input을 건드릴 엄두가 안 나던 탓도 있습니다. 아무튼 시작해봅시다. 1. SFML에서 한글 입력받는 방법 SFML에서는 sf::Event::TextEntered를 통해 입력받은 글자의 unicode를 가져올 수 있습니다. 문제는 한글(또는 한자)은 조합형 문자라는 특성상, 문자가 완성된 후에야 입력된다는 점입니다. Windows에서 영문자만을 제대로 지원하는 프로그램에서 한글을 입력하면 대개 우하단에 이런 창이 뜨는 걸 볼 수 있습니다. 한중일권(CJK)의 문자는 Input Method Editor(이하 IME)를 통해 글자를 조합한 후에 입력할 수 있습니다. IME에서 완성된 ..

C++/Game 2022.09.18

[게임 프레임워크 개발 일지] #9 SFML의 Alpha Mask와 Invert

TextInput을 구현하려면 여러 가지 기능을 구현해야 합니다. 텍스트 입력을 처리하다 보니 커서도 만들어줘야 되고, 한글 입력을 해보니 조합이 완성되어야 글자가 나타나고, 텍스트 선택을 구현하다보니 렌더링 효과를 만들어줘야 하더군요. 오늘 다룰 것은 바로 이 렌더링 효과입니다. 이건 TextInput과 상관 없어도 다룰 필요가 있었거든요. 이것 관련해서 할 얘기가 좀 있긴 한데, 이건 다음에 얘기합시다. 골치 아프니까요. 선택한 텍스트 영역은 주로 파란 배경에 흰색 텍스트로 표시됩니다. Visual Studio 등에서는 텍스트 색이 그대로기도 합니다만, 텍스트 색이 배경색과 같은 경우의 참사를 막기 위해서 여기서는 파란 배경에 흰색 텍스트 표시를 목표로 하겠습니다. 파란 배경이 될 사각형 영역은 글자..

C++/Game 2022.08.15