{"id":26820323,"url":"https://github.com/jinhyeonseo01/project-rhythmengineer","last_synced_at":"2025-04-24T03:28:12.655Z","repository":{"id":165625138,"uuid":"640755594","full_name":"jinhyeonseo01/Project-RhythmEngineer","owner":"jinhyeonseo01","description":"C++ WinAPI\u0026Direct2D 2D Rendering Pipeline Game Project,  (University Project)","archived":false,"fork":false,"pushed_at":"2024-12-28T23:36:59.000Z","size":314008,"stargazers_count":4,"open_issues_count":3,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-30T06:31:39.559Z","etag":null,"topics":["2d-game","cpp","direct2d","game","project","rendering-2d-graphics","rythm-game","university","winapi"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jinhyeonseo01.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-15T04:03:34.000Z","updated_at":"2025-03-27T12:39:45.000Z","dependencies_parsed_at":"2023-07-20T00:45:59.452Z","dependency_job_id":"83d877e1-2024-4d1c-bad8-d707d5a3b1bd","html_url":"https://github.com/jinhyeonseo01/Project-RhythmEngineer","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinhyeonseo01%2FProject-RhythmEngineer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinhyeonseo01%2FProject-RhythmEngineer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinhyeonseo01%2FProject-RhythmEngineer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinhyeonseo01%2FProject-RhythmEngineer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jinhyeonseo01","download_url":"https://codeload.github.com/jinhyeonseo01/Project-RhythmEngineer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250554564,"owners_count":21449639,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["2d-game","cpp","direct2d","game","project","rendering-2d-graphics","rythm-game","university","winapi"],"created_at":"2025-03-30T06:30:50.024Z","updated_at":"2025-04-24T03:28:12.643Z","avatar_url":"https://github.com/jinhyeonseo01.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Project : Rhythm Engineer\n\n**C++에서 WinAPI와 Direct2D를 이용해 Rendering Pipeline을 설계한 2D 리듬게임 프로젝트**  \n2023 University(한국공학대학교) Win32 Project (2_1 Grade) 2D Pipeline Process Develop Project  \n\n## 3rd Party Stack\n - **MFC/ATL** // Visual Studio Package\n - **WinAPI** // Windows Graphic API\n - **Direct2D** // GPU Graphic API\n - **FMOD** // Sound\n - **Eigen3** // Math:Matrix\n\n![img](./docs/f_1.gif)  \n[https://youtu.be/temw8YyZNhk](https://youtu.be/temw8YyZNhk)  \n[Node 작업 Google Sheet](https://docs.google.com/spreadsheets/d/1XC7WaIaXhewO1Sn5aK0LbLGpy6XT9koK-jMesOznveg/edit?usp=sharing)  \n\u003c/br\u003e\n\n* * *\n## Workers\n - Jin Hyeon Seo (Clrain) : Main Develop \u0026 Main Art \u0026 Main Design\n - Jung Jin Bong : Music Node Data Maker\n\n* * *\n\n## 조작키\n\n\u003cdetails\u003e\n\u003csummary\u003e접기/펼치기\u003c/summary\u003e\n\n![img](./docs/control.png)\nCtrl + Q : 종료\nCtrl + 1 : 타겟 프레임 30 설정  \nCtrl + 2 : 타겟 프레임 60 설정  \nCtrl + 3 : 타겟 프레임 144 설정  \nCtrl + 4 : 타겟 프레임 244 설정  \nCtrl + 0 : 프레임 제한 설정/해제  \nY : 게임 일시정지  \nU : 게임 일시정지 해제  \nI : 게임 정지  \nL : 오토 공격 켜기/끄기  \n로고 화면 + S : 로고 스킵.  \n\n\u003c/details\u003e\n\n  \n* * *\n## Install \u0026 Execution 방법\n\u003cdetails\u003e\n\u003csummary\u003e접기/펼치기\u003c/summary\u003e\n\n``` c++\n#include \u003catlImage.h\u003e\n```\n을 찾을 수 없을 경우 (Not Found).\nVisual Studio Installer에서\n개별 구성요소 -\u003e MFC/ATL 모듈 구성 요소를 설치할 것.\n\n\u003c/details\u003e\n\n* * *\n# Develop Log\n## Day 1(23.5.15) Log\n### Logic Pipeline \u0026 Render Pipeline \u0026 Debug System Develop\n\u003cdetails\u003e\n\u003csummary\u003eLogic Pipeline \u0026 Render Pipeline \u0026 Debug System Develop\u003c/summary\u003e\n\n![Alt text](https://user-images.githubusercontent.com/45618159/238410773-956ea9fa-16f8-4216-9e79-1993f3dae090.png)\n\n\u003e1. Debug 창과 MicroSecond 단위로 측정되는 deltaTime log.\n\u003e2. Update PipeLine이 개발된 상태.\n\u003e3. Camera와 공간상 좌표계를 표현하고 활용하기 위해\n\u003e   벡터와 행렬의 연산을 도와줄 Eigen 라이브러리를 기용.\n\u003c/details\u003e\n\n* * *\n## Day 2\n### Sprite Rendering pipeline 계산 절차 설계\n\u003cdetails\u003e\n\u003csummary\u003eSprite Rendering pipeline 계산 절차 설계\u003c/summary\u003e\n\n![Alt text](https://user-images.githubusercontent.com/45618159/238851939-b670c12c-aa06-4527-8d6b-01236a237708.png)\n\n3단계 프로세스에 걸쳐서 Rendering 과정을 수립.\n논리적 사고 흐름을 정리.\n\u003e1. 원시데이터를 스케일링, 컷팅, 플립을 계산하여 StretchBlt 수행\n\u003e\u003e![Alt text](https://user-images.githubusercontent.com/45618159/238854895-c18e07d8-379c-48be-84c6-fd322dd96e02.gif)\n\u003e2. 행렬 매트릭스로 3개의 벡터를 곱.\n\u003e    [ cos(angle), -sin(angle)]\n\u003e    [ sin(angle),  cos(angle)]\n\u003e v1 : (-stretch * pivot) 뒤로 당겨주는 벡터.\n\u003e v2 : (stretchW, 0)\n\u003e v3 : (0, stretchH)\n\u003e\u003e - R*V로 구해진 회전벡터에 |stretch| stretch의 대각 길이를 더해준다.\n\u003e\u003e - |stretch| stretch의 대각 길이 * 2의 BitMap을 준비하는 것으로 pivot 0~1사이에서 자유롭게 회전했을때 모두 비트맵에 담을 수 있도록 크기정해준다.\nPigBit 수행\n\u003e\u003e![Alt text](https://user-images.githubusercontent.com/45618159/238852550-706ff44a-358f-4929-a894-c2cd0935447a.gif)\n\u003e\u003e![Alt text](https://user-images.githubusercontent.com/45618159/238852335-7ec4da00-d8a4-4827-9925-fe5e1b888b34.gif)\n\u003e3. 마지막으로 Alpha값이 적용될 수 있도록 Position - |stretch|위치에 렌더링한다.\n\u003e AlphaBlend 수행\n\u003e![Alt text](https://user-images.githubusercontent.com/45618159/238857866-2cf6a137-52e5-4201-894c-751719640683.gif)\n\u003cdetails\u003e\n\u003csummary\u003e렌더링 소스코드 (접기/펼치기)\u003c/summary\u003e\n\n```cpp\nHDC m_hDC = img.GetDC();\n\nfloat stretchW = sizex;\nfloat stretchH = sizey;\n// -- 1단계 --\nHDC m_hDC2 = CreateCompatibleDC(m_hDC);\nHBITMAP bmp = CreateCompatibleBitmap(m_hDC, stretchW, stretchH);\nSelectObject(m_hDC2, bmp);\nfloat filterX = imageW * imageOffsetx;\nfloat filterY = imageH * imageOffsety;\nfloat filterW = imageW * imageScalex;\nfloat filterH = imageH * imageScaley;\nStretchBlt(m_hDC2, 0, 0, stretchW, stretchH, m_hDC,\n\tfilterX + (flipx == 1 ? 0 : filterW - 1),\n\tfilterY + (flipy == 1 ? 0 : filterH - 1),\n\t(flipx == 1 ? 1 : -1)* filterW, (flipy == 1 ? 1 : -1)* filterH, SRCCOPY);\n\n// -- 2단계 --\nfloat bmp3Size = sqrt(stretchW * stretchW + stretchH * stretchH);\nHDC m_hDC3 = CreateCompatibleDC(m_hDC);\nHBITMAP bmp3 = CreateCompatibleBitmap(m_hDC, bmp3Size * 2, bmp3Size * 2);\nSelectObject(m_hDC3, bmp3);\n\nEigen::Matrix3d rotateM;\nrotateM \u003c\u003c\ncos(angle * D2R), -sin(angle * D2R), 0,\nsin(angle* D2R), cos(angle* D2R), 0,\n0, 0, 1;\nEigen::Vector3d v1, v2, v3;\nv1 \u003c\u003c stretchW, 0, 1;\nv2 \u003c\u003c 0, stretchH, 1;\nv3 \u003c\u003c -stretchW * pivotx, -stretchH * pivoty, 1;\nv1 = rotateM * v1;\nv2 = rotateM * v2;\nv3 = rotateM * v3;\n\nPOINT a[3] = {\n\t{bmp3Size + v3.x(), bmp3Size + v3.y()},\n\t{bmp3Size + v3.x() + v1.x(), bmp3Size + v3.y() + v1.y()},\n\t{bmp3Size + v3.x() + v2.x(), bmp3Size + v3.y() + v2.y()},\n};\n::PlgBlt(m_hDC3, a, m_hDC2,\n\t0, 0,\n\tstretchW, stretchH,\n\tNULL, NULL, NULL);\n\n// -- 3단계 --\nBLENDFUNCTION bf;\nbf.BlendOp = AC_SRC_OVER;\nbf.BlendFlags = 0;\nbf.SourceConstantAlpha = 0xff;\nbf.AlphaFormat = AC_SRC_ALPHA;\nbResult = ::AlphaBlend(hDC,\n\tx - bmp3Size, y - bmp3Size,\n\tbmp3Size * 2, bmp3Size * 2,\n\tm_hDC3, 0, 0,\n\tbmp3Size * 2, bmp3Size * 2, bf);\n\nDeleteObject(m_hDC2);\nDeleteObject(bmp);\n\nDeleteObject(m_hDC3);\nDeleteObject(bmp3);\n\nimg.ReleaseDC();\n```\n\u003c/details\u003e\n\u003c/details\u003e\n\n* * *\n\n## Day 3 (23.5.20)\n### Camera 기반 렌더링 시스템 \u0026 Hierarchy 구조 도입\n\u003cdetails\u003e\n\u003csummary\u003eCamera 기반 렌더링 시스템 \u0026 Hierarchy 구조 도입\u003c/summary\u003e\n\n#### Day 3\nTargetFrame System을 도입.\nFrame Lock을 걸면 해당 프레임 이상 솓구치지 않는 것을 확인했다.\n\n![Alt text](https://user-images.githubusercontent.com/45618159/239778291-71a9fa16-1575-4566-bd63-359e744d762c.gif)\n\n카메라 렌더링 시스템을 개발했다.\n근데 PlgBit의 레스터라이즈 과정이 CPU에서 진행된다는 매우 치명적인 단점이 있었다.\n그래서 angle이 0도일땐 괜찮지만... angle이 조금이라도 들어가면 매우매우 렉걸리는 상황에 봉착했고, 이 프레임 문제를 해결해야하는 과제가 생겼다.\n\n\u003c/details\u003e\n\n* * *\n\n## Day 4 (23.5.21)\n### 렌더링 API를 GDI에서 Direct2D로 전면 교체\n\u003cdetails\u003e\n\u003csummary\u003e렌더링 API를 GDI에서 Direct2D로 전면 교체\u003c/summary\u003e\n\n#### Day 4\n#### 문제해결 절차\n\t이슈 발생 -\u003e 원인 분석 -\u003e 해결방안 모색 -\u003e 적정 기술 학습 -\u003e 기술 도입 -\u003e 기술 호환성 -\u003e 사후 리뷰  \n\n* * *\n\n#### 이슈 발생\n - PlgBit의 성능이 매우 좋지 않아 1920x1080 해상도에서 1\\~4프레임정도 나온다는 것을 확인했다.  \n#### 원인 분석\n - PlgBit는 오래된 API인 GDI 1세대를 기반으로한 함수이다.\n - 픽셀 레스터라이즈 과정을 CPU로 수행하기 때문에 속도가 느릴 수 밖에 없다.\n#### 해결방안 모색\n- 고심끝에 Direct2D로 렌더링 시스템을 전면 교체하기로 했다.  \n- Direct2D는 GDI 3세대 기술로 GPU렌더링을 지원한다.  \n- GDI보다 절차가 복잡하고, 기반지식이 하나도 없어서 밑바닥부터 전부 다시 배워야하는 학습장벽이 존재했다.  \n- 하지만, 좋은 퀄리티의 게임을 개발하기 위해서 빠르게 습득하기로 결정했다.\n#### 기술 호환성\n![Alt Text](https://user-images.githubusercontent.com/45618159/239778075-47bbb7d8-448a-4784-8eef-19411b505d5e.gif)\n- 24시간 정도의 학습기간을 갈아넣은 결과 프레임이 굉장히 잘나온다. 달리진게 없어 보이지만, 내부 코드는 완전히 싹다 갈아 엎었다.  \n- 렌더링 부분만 뜯어내면서 기존로직과 100% 호환되게 작업했기 때문에 겉보기엔 똑같이 보인다.  \n#### 비교 분석 리뷰\n\u003e**Before** ![Before](https://user-images.githubusercontent.com/45618159/239789772-d1c19672-1ce0-4b1e-8194-5b8f8ce4409a.png)\n\u003e**After** ![Alt Text](https://user-images.githubusercontent.com/45618159/239778700-2b4c82dc-c2da-46d5-9c46-e7ee62821a13.png)  \n\n- 기존 GDI라면 1\\~4프레임 나오겠지만, Direct2D에선 160\\~200프레임 이상 나오는 것을 확인했다.  \n  \n#### 성능 향상\n\n| API | FPS | 배수 |  \n| --- | ---: | ---: |  \n| GDI | 1 \\~ 4 | 1.0 |  \n| Direct2D | 165 \\~ 200 | 90.0 \\~ 100.0 |  \n\n\u003c/details\u003e\n\n* * *\n\n## Day ~ Final (23.6.9)\n### 구체적인 기록을 못해서, 그 뒤 작업 내역\n\u003cdetails\u003e\n\u003csummary\u003e구체적인 기록을 못해서, 그 뒤 작업 내역\u003c/summary\u003e\n\n#### Animation System 적용\n*허가받지 않은 이미지 이용, 이 자리를 빌어 죄송하단 말씀 올립니다...*\n![img1](./docs/10.gif)\n\n#### Google Sheet를 통한 Json Serialize 연동 작업\n![img](./docs/sheet1.png)\n[Node 작업 Google Sheet](https://docs.google.com/spreadsheets/d/1XC7WaIaXhewO1Sn5aK0LbLGpy6XT9koK-jMesOznveg/edit?usp=sharing)\n![img2](./docs/11.gif)\n\n#### VFX 1차 작업\n![img3](./docs/12.gif)\n\n#### FMOD를 활용한 FFT 기반 사운드 스펙트럼 기능 추가 \u0026 VFX 2차 작업\n![img3](./docs/13.gif)\n\n#### UI 기능 및 Rotating 레코드 스크롤 메뉴\n![img4](./docs/14.gif)\n\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjinhyeonseo01%2Fproject-rhythmengineer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjinhyeonseo01%2Fproject-rhythmengineer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjinhyeonseo01%2Fproject-rhythmengineer/lists"}