반응형

전체 글 214

Unity 개발시 편집 중인 텍스트나 csv파일 데이터를 게임에서 읽기

유니티에서 게임 개발시 텍스트나 csv 데이터 파일의 로딩이 실패하지 않으려면 편집 중인 데이터 파일을 닫고 로딩해야 합니다. 하지만 게임을 개발하다보면 게임 개발과 텍스트나 csv 파일의 데이터 편집을 동시에 하고 싶을 때가 있습니다. 이럴 때는 아래의 방법을 사용하면 텍스트나 csv 데이터 파일을 편집하면서 게임 로딩이 정상적으로 일어나게 할 수 있습니다. 우선 아래의 간단한 소스를 보겠습니다. using UnityEngine; using System.IO; public class Test { public static void Load(string file) { string filepath = Application.dataPath + "/Resources/Data/" + file; using (var..

Unity 2D 카메라 화면 크기 및 좌표 범위 얻기

Unity로 2D 게임을 만들다보면 카메라가 표시하는 화면 좌표에 대한 정보를 얻어야 할 때가 있습니다. 그럴 때 카메라가 표시하는 화면의 왼쪽(Left), 오른쪽(Right), 위(Top), 아래(Bottom), 전체 길이(Width), 전체 높이(Height) 등의 정보가 필요합니다. 아래 소스는 camera_ 변수에 화면을 표시하는 카메라를 설정하면 화면의 왼쪽(Left) x좌표, 오른쪽(Right) x좌표, 위(Top) y좌표, 아래(Bottom) y좌표 및 전체 길이(Width), 전체 높이(Height) 등을 얻는 간단한 소스 예제입니다. 예제 소스에서는 마우스 오른쪽 버튼을 누르면 해당 정보가 디버그로 표시하게 해놓았습니다. 참고로 해당 소스는 간단히 만든 관계로 camera_에 대한 nul..

Unity 씬 이동 간에 빈 이동 씬을 이용하여 최대 사용 메모리 줄이기

이건 전 AXE팀의 NDC 발표 내용 중 일부인데 유니티에서 씬간의 이동시 중간에 빈 씬을 삽입하여 순간적 최대 사용 메모리 양을 줄이는 기법입니다. 이론적으로 말하자면 A씬에서 B씬으로 이동한다고 하였을 때 B씬이 로딩되었을 때 A씬이 언로드되기 전까지 최대 메모리 사용량은 A씬의 메모리 사용량 + B씬의 메모리 사용량이 됩니다. 이때 중간에 메모리 사용량이 거의 없는 빈 이동 씬을 삽입하여 A씬에서 빈 이동 씬으로 이동한 후에 빈 이동 씬에서 B씬으로 이동하게 만듭니다. 이런 빈 이동 씬을 이용하면 순간적 최대 사용 메모리양은 A씬 + 빈 이동 씬과 빈 이동 씬 + B씬 중 최대 메모리 사용량이 됩니다. NDC 내용을 보면 순간 최대 사용 메모리양으로 인하여 튕긴 현상이 있어서 이것을 구현하였다고 합..

std::chrono::steady_clock 관련 종합 예제

std::chrono::steady_clock을 사용할 일이 있어서 이리 저리 조사를 하며 만들어본 예제입니다. 예제에는 지나간 시간 체크, 시간 차 duration에 시간 더하기, 현재 구한 시간에 시간 더하기, duration과 long long간의 형변환, 시간차를 나타내는 duration 시간 이쁘게 보여주기 등등이 포함되어 있습니다. 예제 소스는 아래와 같습니다. #include #include #include #include using namespace std; int main(int argc, char* argv[]) { // 예제 #1: 지나간 시간을 체크합니다. auto now1 = std::chrono::steady_clock::now(); this_thread::sleep_for(st..

C++ 프로그래밍 2021.11.22

C++ boost json 구조체와 json 문자열간 변환 예제

boost json라이브러리를 사용하면 구조체와 json문자열 간의 상호 변환이 간단합니다. 여기서는 간단한 변환 예를 살펴보며 사용법을 알아보겠습니다. 우선 아래와 같은 간단한 예로 살펴보겠습니다. #include #include #include using namespace std; struct user { int id; string name; bool login; }; void tag_invoke(boost::json::value_from_tag, boost::json::value& jv, user const& u) { jv = { {"id", u.id}, {"name", u.name}, {"login", u.login} }; } user tag_invoke(boost::json::value_to_t..

[MongoDB] C/C++ BSON 한글 문자열 입출력

MongoDB는 BSON을 사용합니다. BSON에서 문자열은 UTF-8을 사용합니다. UTF-8과 ANSI의 관계상 영문만 사용한다면 별도의 변환은 필요 없습니다. 그러나 일반적으로 사용하는 한글과 같은 멀티 바이트 문자열이나 유니코드 문자열은 별도로 UTF-8로 인코딩하여야 합니다. 또한 MongoDB에 저장된 문자열을 사용하기 위하여 UTF-8문자열을 한글과 같은 멀티 바이트 문자열이나 유니코드로 디코딩해야 합니다. 참고로 MongoDB C/C++ Driver API에 한글과 같은 멀티 바이트 문자열을 인자로 넣으면 바이트 수가 틀리다는 류의 에러가 나면서 API가 실행되지 않습니다. C/C++에서 한글과 같은 멀티바이트 문자열을 UTF-8로 변환하는 방법은 아래와 같습니다. 우선, boost 라이브..

boost locale을 이용한 C++에서의 Multi Byte와 UTF8간의 문자열 변환

영문만 있는 경우는 문자열은 C/C++에서 UTF-8로 별도의 변환을 필요로 하지 않습니다. 하지만 한글과 같이 멀티 바이트를 사용하는 경우는 별도로 UTF-8로 인코딩 및 디코딩을 해주어야 합니다. 이런 경우 사용할 수 있는 라이브러리가 boost local입니다. 간단한 Multi Byte와 UTF8간의 문자열 변환 예제는 아래와 같습니다. #include #include #include using namespace std; int main(int argc, char* argv[]) { string str = "{\"name\": {\"first\":\"그레이스\", \"last\":\"Hopper\"}}"; cout

동적 라이브러리(DLL)를 사용할 것인가? 아니면 정적 라이브러리(LIB)를 사용할 것인가?

일정 규모 이상의 프로그램을 만들다보면 공통적으로 참조하는 공통 라이브러리를 만들고 여러 프로그램에서 참조하게 하는 경우가 종종 있습니다. 공통 라이브러리는 프로그램에 내용이 포함되는 정적 라이브러리와 DLL, SO등의 별도 확장자로 필요에 따라 로딩되어 참조되는 동적 라이브러리가 있습니다. C++이나 기타 언어의 서적을 보게 되면 실행 파일이 참조하는 라이브러리로 보통은 동적 라이브러리를 많이 추천합니다. 동적 라이브러리의 장점은 아래와 같습니다. 첫째로 여러 프로그램이 참조하더라도 라이브러리 사용 메모리는 하나의 프로그램의 사용에 필요한 만큼만 필요합니다. 덕분에 메모리는 여러개의 프로그램에서 참조하더라도 (사용 프로그램 수 N개 - 1) * 사용 메모리 크기 만큼 절약하게 됩니다. 둘째로 라이브러리..

C++ 프로그래밍 2021.11.18

평면과 두 점 사이에 만나 점 구하기

평면의 방정식은 아래와 같습니다. ax + by + cz + d = 0 면의 방정식과 두 점을 아는 상태에서 평면과 만나는 두 점 사이의 점을 구하여 보겠습니다. 비율 r을 P – P0 / P1 – P0으로 정의하겠습니다. 비율 r을 구하기 위하여 분모 및 분자에 평면에 수직한 법선 벡터 n을 내적하면 비율 r은 아래와 같습니다. 참고로 벡터 n은 평면을 방정식을 응용하면 (a, b, c)가 됩니다. r = P·벡터 n – P0 ·벡터 n / P1 ·벡터 n – P0 ·벡터 n 여기서 P는 평면과 교차함으로 평면내에 포함되어 있어 P·벡터 n은 평면의 방정식에 의하여 –d가 됩니다. r과 관련된 수식에서 P의 값 만을 알 수 없었으므로 P·벡터 n을 –d값으로 치환하여 r을 구합니다. P는 P0 + r ..

세 점을 포함하는 평면의 방정식 구하기

평면의 방정식은 아래와 같습니다. ax + by + cz + d = 0 평면이 세 점 P0, P1, P2를 그림과 같이 포함한다고 하겠습니다. 해당 세 점을 바탕으로 벡터 V1 = P1 – P0과 벡터 V2 = P2 – P0을 정의할 수 있습니다. 그리고 벡터 V1과 벡터 V2의 외적를 구한 후 정규화하여 벡터 V를 구할 수 있습니다. 이 때 벡터 V의 x, y, z은 평면의 방정식의 a, b, c가 됩니다. 구한 벡터 V에 P0을 내적하면 평면의 방정식에 의하여 0이 되어야 함으로 이를 바탕으로 아래와 같이 d를 구할 수 있습니다. 벡터 V·P0 + d = 0 d = - (벡터V·P0) 마지막으로 위에서 구한 a, b, c, d를 대입하여 평면을 방정식을 구하면 됩니다.

C++ boost 메모리풀 강좌 #5: boost 메모리풀 할당자를 적용하여 STL 컬렉션의 성능 향상시키기

STL 컬렉션은 템플릿 지정자를 이용하여 메모리 할당자를 설정할 수 있습니다. 참고로 메모리 할당자란 컬렉션에 요소에 대해서 메모리 new / delete하는 객체를 말합니다. STL 컬렉션에 메모리 할당자를 메모리풀을 사용하도록 하여 성능을 향상 시킬 수 있습니다. boost에는 이 STL 컬렉션 관련 메모리 풀 지원 할당자가 pool_allocator와 fast_pool_allocator이 있습니다. 두 할당자 모두 어느 STL 컬렉션에나 사용할 수 있습니다. 특징적으로 pool_allocator는 vector처럼 연속된 메모리 할당 및 해제가 일어나는 STL 컬렉션에서 성능이 좋습니다. fast_pool_allocator는 list처럼 단일 메모리 할당 및 해제가 일어나는 STL 컬렉션에서 성능이 ..

강좌 2021.11.15

C++ boost 메모리풀 강좌 #4: object_pool 클래스를 이용하여 new 재정의 없이 일반 클래스에 메모리풀 적용하기

object_pool은 pool의 클래스 할당 및 해제 버전으로 보면 이해하기 쉽습니다. pool과 사용법이 유사한데 틀린점은 construct와 destory 함수를 이용하여 할당 및 해제를 한다는 점입니다. 또한 construct 함수를 호출할 때 생성 인자를 넣어서 생성할 수도 있습니다. 단, 아쉽게도 생성인자는 3개까지 지원합니다. new 재정의로 메모리 풀을 적용하지 않은 클래스에 대하여 생성시점에서 메모리풀을 사용하기에 좋습니다. 간단한 예를 살펴보도록 하겠습니다. #include #include using namespace std; class test_mpa2 { private: char test_[256]; public: test_mpa2(const char* str) { strcpy_s(..

강좌 2021.11.14

C++ boost 메모리풀 강좌 #3: singleton_pool 클래스를 이용하여 일반 클래스에 메모리풀 적용하기

singleton_pool 클래스도 기본적으로 이전에 설명한 pool과 비슷합니다. 이 클래스는 템플릿 주요 인자로 할당 크기를 구분하는 태그 인자와 할당 크기를 받습니다. 태크 인자와 할당 크기라는 인자 특성 때문에 일반 클래스에 operator new / delete를 재정하여 적용하기에 쉽습니다. 이 외에 singleton_pool은 기본적으로 멀티쓰레드에서 안전합니다. 싱글쓰레드에서 사용할 때는 성능을 올리기 위하여 mutex 인자 부분에 boost::details::pool::null_mutex을 넣어주면 좋습니다. 간단한 사용법 예를 살펴보겠습니다. #include #include using namespace std; template class memory_pool_allo..

강좌 2021.11.13

C++ boost 메모리풀 강좌 #2: pool 클래스를 이용하여 버퍼에 메모리풀 적용하기

boost 메모리풀 관련 클래스 중 pool은 메모리풀을 활용하여 C 스타일로 메모리를 할당 및 해제할 때 사용할 수 있는 클래스입니다. 이런 특성을 가진 관계로 C++에서 C스타일로 메모리를 할당 및 해제하는 버퍼에 적용하기 좋습니다. 이 클래스를 버퍼에 활용하면 메모리풀이 적용되어 성능 향상에 좋습니다. 간단히 아래 예제를 통하여 살펴보겠습니다. #include #include using namespace std; int main(int argc, char* argv[]) { boost::pool pool(sizeof(char) * 32); char* test = (char*)pool.malloc(); strcpy_s(test, sizeof(char) * 32, "test test test test"..

강좌 2021.11.12
반응형