블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2794)
Unity3D (852)
Programming (478)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (11)
3DS Max (3)
Game (12)
Utility (68)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

#################
 컨테이너 종류
#################

표준 STL 시퀀스 컨테이너 : vector, string, deque, list
표준 STL 연관 컨테이너 : set, multiset, map, multimap

비표준 시퀀스 컨테이너 : slit, rope
비표준 연관 컨테이너 : hash_set, hash_multiset, hash_map, hash_multimap

string 대한 vector<char>

표준 연관 컨테이너 대신 사용 되는 vector

STL에 속하지 않는 표준 컨테이너 : 배열, bitset, valarray, stack, queue, priority_queue

-------------------------
 연속 메모리 컨테이너
-------------------------
삽입 삭제시 메모리가 밀려 지거나 땡겨 지는 컨테이너(무효화!!! <-- 특히 이넘을 조심 해야 함.)
vector, string, deque.

---------------------
 노드 기반 컨테이너
---------------------
삽입 삭제시 메모리 포인터만 영향을 받음. 밀리는 현상 없음.
list, slist, set, multiset, map, multimap,
hash_set, hash_multiset, hash_map, hash_multimap


#######################################
STL은 복사에서 시작 하고 복사로 끝난다.
#######################################
값을 얻거나 넣거나 할때 모두 복사로 이루어 집니다.

상속된 클래스를 사용할 경우 베이스 클래스로 형 지정 했다면,
복사라는 특징 때문에 상속된 클래스는 잘리게 됩니다.(slicing problem)

이에 대한 해결 책은 클래스 포인터를 사용 하는 것입니다.(추후 설명)


배열
T w[maxT];

사이즈 0
vector<T> vw;

max T 만큼 미리 확보
vector<T> vw;
vw.reserve(maxT);


######################################
size() == 0을 쓰지 말고 empty()를 써라
######################################

size()를 제공 하지 않는 것도 있다. 예 list


######################################
단일 요소 반복 대신 범위 함수를 쓰자
######################################

void container::assign(시작, 끝)

void container::contrainer(시작, 끝)

void container::insert(삽입위치, 삽입 시작, 끝)

iterator container::erase(시작, 끝)     - 시퀀스 컨테이너

void container::erase(시작, 끝) - 연관 컨테이너(반복자의 반환으로 성능 저하 되므로...)


#####################
C++의 어이 없는 동작
#####################

 

#include <iostream>

class T {
public:
        T() { cout << "ok" << endl;}
};

int main() {
        T t1(); // 함수 선언, nothing...

        T t2;   // t 객체 생성, out "ok"
}

같은 원리로...

ifstream dataFile("ints.dat");
list<int> data(istream_iterator<int>(dataFile), istream iterator<int>());       // 단순한 함수 선언에 불과 하다.

list<int> data((istream_iterator<int>(dataFile)), istream iterator<int>());     // 해결, 범용성 떨어짐

<해결>
ifstream dataFile("ints.dat");
istream_iterator<int> dataBegin(dataFile);
istream_iterator<int> dataEnd;
list<int> data(dataBegin, dataEnd);


############################################################################
new로 생성한 포인터 컨테이너는 컨테이너가 소멸 되기 전에 포인터를 delete하자
############################################################################


vector<Widget *> vwp;

for(int i=0; i<NUM; ++i) {
        vwp.push_back(new Widget);      // new로 생성
}

//... 사용

for(vectro<Widget *>::iterator i = vwp.begin(); i!=vwp.end(); ++i)
        delete *i;              // delete로 소멸


<문제>
1. for루프는 for_each보다 명확하지 못하다.
2. 사용 중에 vwp가 예외를 던진 다음 메모리 누수 문제는 여전히 남는다.

<1번 해결>
struct Delete Object {
        template<typename T>
        void operator()(const T*ptr) const {
                delete ptr;
        }
};

for_each(vwp.begin(), vwp.end(), DeleteObject());

<2번 해결>
www.boost.org의 스마트 포인터 라이브러리를 사용 합니다.

void doSomething()
{
        typedef boost::shared_ptr<Widget> SPW;

        vector<SPW> vwp;

        for(int i=0; i<NUM; ++i)
                vwp.push)back(SPW(new Widget));
        ...
}

doSomething()함수가 끝나더라도, 예외가 발생 해도 메모리가 새지 않습니다.


##############################
auto_ptr 은 절대로 쓰지 말아라
##############################
auto_ptr은 스마트 포인터가 아니다. 자세한것은 Effective STL 참조!!!


##################
삭제의 조심 스러움
##################

무효화된 i에 대하여 ++i를 하고 있다.


AssocContainer<int> c;  // AssocContainer는 연관 컨테이너.
...
for(AssocContainer<int>::iterator i=c.begin(); i!=c.end(); ++i) {
        if(badValue(*i)) c.erase(i);
}

<해결>
AssocContainer<int> c;
...
for(AssocContainer<int>::iterator i=c.begin(); i!=c.end(); ) {
        if(badValue(*i)) c.erase(i++);
        else ++i;
}


연속 컨테이너인 경우 i++시 전체가 무효화 됩니다.

<해결>
for(SeqContainer<int>::iterator i=c.begin(); i!=c.end();) {
        if(badValue(*i)) {
                i = c.erase(i);
        }
        else ++i;
}


######################################################
STL 쓰레드는 쓰레드에 안전하지 않다.(직접 관리 해야함)



출처 : http://blog.naver.com/jinowin/6000269089

반응형
Posted by blueasa
, |
반응형
Posted by blueasa
, |

sendmessage in C#

Programming/C# / 2010. 12. 27. 01:42
1         [DllImport("user32.dll", SetLastError = true)]  
2         static extern IntPtr FindWindow(string lpClassName, string lpWindowName);  
3  
4         [DllImport("user32.dll", SetLastError = true)]  
5         static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);  
6  
7         [DllImport("user32.dll")]  
8         private static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);  
9  
10         static void Main(string[] args)  
11         {  
12             // Use this to send key strokes  
13             const int WM_KEYDOWN = 0x100;  
14             IntPtr windowHandle = FindWindow("NOTEPAD"null);  
15             IntPtr editHandle = FindWindowEx(windowHandle, IntPtr.Zero, "EDIT"null);  
16             PostMessage(editHandle, WM_KEYDOWN, 'A', 0);  
17             Console.ReadKey();  
18         }

1         [DllImport("user32.dll")]  
2         public static extern int SendMessage(int hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPStr)] string lParam);  
3  
4         [DllImport("user32.dll", SetLastError = true)]  
5         static extern IntPtr FindWindow(string lpClassName, string lpWindowName);  
6  
7         [DllImport("user32.dll", SetLastError = true)]  
8         static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);  
9  
10         static void Main(string[] args)  
11         {  
12             const int WM_SETTEXT = 0x0C;  
13  
14             IntPtr windowHandle = FindWindow("NOTEPAD"null);  
15             IntPtr editHandle = FindWindowEx(windowHandle, IntPtr.Zero, "EDIT"null);  
16             string textToSendToFile = "Input here your text";  
17             SendMessage((int)editHandle, WM_SETTEXT, 0, textToSendToFile);  
18  
19             Console.ReadKey();  
20         }


반응형
Posted by blueasa
, |

C# SendMessage Keypress

Programming/C# / 2010. 12. 26. 23:45
#region Function Imports
 
       
[DllImport("user32.dll")]
       
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
 
       
[DllImport("user32.dll")]
       
static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
 
       
#endregion
 
       
#region Constants
 
       
// Messages
       
const int WM_KEYDOWN = 0x100;
       
const int WM_KEYUP = 0x101;
       
const int WM_CHAR = 0x105;
       
const int WM_SYSKEYDOWN = 0x104;
       
const int WM_SYSKEYUP = 0x105;
 
       
#endregion
 
       
public static void SendKey(string wName, Keys key)
       
{
           
IntPtr hWnd = FindWindow(null, wName);
 
           
SendMessage(hWnd, WM_KEYDOWN, Convert.ToInt32(key), 0);
           
SendMessage(hWnd, WM_KEYUP, Convert.ToInt32(key), 0);
       
}
 
       
public static void SendSysKey(string wName, Keys key)
       
{
           
IntPtr hWnd = FindWindow(null, wName);
 
           
SendMessage(hWnd, WM_SYSKEYDOWN, Convert.ToInt32(key), 0);
           
SendMessage(hWnd, WM_SYSKEYUP, Convert.ToInt32(key), 0);
       
}
 
       
public static void SendChar(string wName, char c)
       
{
           
IntPtr hWnd = FindWindow(null, wName);
 
           
SendMessage(hWnd, WM_CHAR, (int)c, 0);
       
}


반응형
Posted by blueasa
, |

C# 배움터

Link / 2010. 12. 23. 17:09
반응형

'Link' 카테고리의 다른 글

Gamebryo 관련 사이트  (0) 2011.01.21
Programmers united develop net  (0) 2011.01.10
Download D3DX DLLs (d3dx9_xx.dll, d3dx10_xx.dll)  (0) 2010.12.23
종이천하  (0) 2010.12.20
Dot Net Perls  (0) 2010.11.08
Posted by blueasa
, |
반응형

'Link' 카테고리의 다른 글

Programmers united develop net  (0) 2011.01.10
C# 배움터  (0) 2010.12.23
종이천하  (0) 2010.12.20
Dot Net Perls  (0) 2010.11.08
CppCheck(소스 결함 예방 툴)  (0) 2010.10.06
Posted by blueasa
, |
System.String → char * (marshal_context)






■ System.String → char *

 예전 C++/CLI 에서는 System.String 문자열을 char * 형으로 변환하기 위해선
메모리를 할당하고, 할당된 메모리에 문자열을 복사하기 위해 Marshal::StringToHGlobalAuto 메소드를 호출했다.
그런 후, HGlobal 포인터를 char * 에 캐스팅 해주었다.

const char* unmanagedString = NULL;
try
{
    String^ managedString = gcnew String("managed string");
    // Note the double cast.
    unmanagedString = (char*)(void*)Marshal::StringToHGlobalAnsi(managedString);
}
finally
{
    // Don't forget to release. Note the ugly casts again. 
    Marshal::FreeHGlobal((IntPtr)(void*)unmanagedString);
}

 

 Visual Studio 2008 에서는 새로운 Marshalling Library 를 통하여 문자열을 복사하는 새로운 방법이 추가 되었다.
이 라이브러리는 Managed Code 의 System.String 과 Native Code 에서 문자열을 나타내는데 자주 쓰이는 타입
(char *, wchar_t *, BSTR, CStringT<wchar_t>, ...) 간의 변환을 쉽게 할 수 있게 해준다.

 Marshalling Library 에서는 marshal_context 라고 하는 새로운 클래스를 포함한다. 이 클래스는 문자열 변환 시
기본의 명시적으로 메모리를 해제 시켜 줘야 하는 작업을 대신 해준다. 따라서 문자열 변환 작업 시의 메모리 해제 및 누수에
대한 걱정을 덜어준다. marshal_context 클래스를 사용하는 예제는 다음과 같다.

marshal_context^ context = gcnew marshal_context();
String^ managedString = gcnew String("managed string");
const char* unmanagedString = context->marshal_as( managedString );



 기본 방법에 비해 코드가 상당히 줄어들었다. 또한 형변환을 위한 캐스팅 연산도 직접 작성하지 않아도 된다.
무엇보다도 제일 중요한 점은 char * 의 메모리 해제 시켜주는 작업을 작성하지 않아도 된다.
marshal_context 클래스는 모든 string 에 대한 참조를 유지한다. 유효 범위(scope) 를 벗어 날 때 소멸자가
그것들을 메모리 해제 시켜준다.






■ Native String → System:String




반대로 변환 하는 방법 역시 비슷하다.



System::String^ 타입을 const char *, const wchar_t *, BSTR 으로 변환하기 위해 marshal_as 를 직접 사용할 수는 없다. 왜냐하면 이러한 변환들은 사용 후에 메모리 해제를 위한 비 관리(Unmanaged) resource 를 필요로 한다. 아래와 같이 context 객체를 사용해야 한다. (즉, marshal_context 클래스의 객체 context 를 사용함으로써 marshal_context 의 소멸자가 메모리 해제를 해준다.)



context 객체는 동적 생성된 객체를 유지하다가 소멸자에서 그 메모리를 해제 시킨다. 내부적으로 할당된 객체들은 Linked-List 로 유지된다. 위의 코드에서 Console::WriteLine(context._clean_up_list.Count); 는 3을 출력 한다.




■ Extend the Marshaling Library 사용

String 타입을 변환할 때 다음과 같은 에러 메시지를 발생할 수 도 있다.

오류 1 error C4996: 'msclr::interop::error_reporting_helper<_To_Type,_From_Type>::marshal_as': This conversion is not supported by the library or the header file needed for this conversion is not included.  Please refer to the documentation on 'How to: Extend the Marshaling Library' for adding your own marshaling method.

CString 타입을 사용하려 하니까 나타난 에러 메시지 인데, MFC 사용할 때 CString 이 ATL data type 이라는 것을 얼 추 추측하긴 했지만 위와 같은 에러 메시지로 확신하게 되었다.

에러 메시지 내용대로 MSDN 의 How to:Extend the Marshaling Library 문서를 확인해 보니 ATL data type 을 위해선 marshal_atl.h 헤더 파일을 include 시켜줘야 한다.








■ 참조

1. More Tales from the Unmanaged Side - System.String -> char* : marshal_context 사용 전의 문자열 변환 방법
2. Tales from the Unmanaged Side – System.String –> char* (pt. 2)  : marshal_context 이용한 방법
3. Using marshal_as for mixed-mode string conversions : 여러 string type 의 conversion
4. Overview of Marshaling in C++
5. How to:Extend the Marshaling Library 


반응형
Posted by blueasa
, |
반응형

'Programming > C++/CLI' 카테고리의 다른 글

cli::array<t>^<t>  (0) 2011.03.24
System.String → char * (marshal_context)  (2) 2010.12.20
Arrays in C++/CLI  (0) 2010.11.26
Native C++에서 Managed C++에 접근이 필요할 때  (0) 2010.11.09
C++/CLI Singleton  (0) 2010.10.22
Posted by blueasa
, |

종이천하

Link / 2010. 12. 20. 18:44
반응형

'Link' 카테고리의 다른 글

C# 배움터  (0) 2010.12.23
Download D3DX DLLs (d3dx9_xx.dll, d3dx10_xx.dll)  (0) 2010.12.23
Dot Net Perls  (0) 2010.11.08
CppCheck(소스 결함 예방 툴)  (0) 2010.10.06
C# 관련 블로그  (0) 2010.08.18
Posted by blueasa
, |

1. NiPick에서의 충돌 검사

일반적으로 충돌 처리를 NiPick을 이용해서 많이 합니다.  그런데 NiPick에는 심각한 문제가 있습니다.  그것은 거리와 상관없이 해당 방향에 있는 모든 오브젝트에 대해서 검사를 한다는 것이죠.

 

NiPick 충돌 검사 비용을 줄이기 위해서는 트라이앵글 충돌검사비용을 줄여주어야 합니다.  그렇게 하기 위해서는 경계구에서 거리가 먼경우(경계구의 중심점과 NiPick.Ray의 origin 위치사이의 거리에서 경계구의 반지름을 뺀 값)에는 아예 그 안에 들어가지 않게 하는 것입니다.  이렇게 하면 속도향상을 상당부분 줄 수 있습니다.

 

NiPick을 이용한 충돌은 기본적으로 카메라 충돌 검사, 서있는 위치 알아오기, 이동방향에 대한 충돌 등 다양하게 적용되겠죠.

 

2. Update 비용

Update 비용은 매우 심각한 편입니다.  이 비용을 줄이기 위해서는 씬그래프를 잘 구성해주어야 합니다.  움직이지 않는 오브젝트는 업데이트가 최초 1회만 실행하면 됩니다.  UpdateSelect, UpdateRigid 등도 모두 낭비라는 사실이죠.

 

그러면 어떻게 하면 될까요? 

 

모델링을 할 때, 노드 이름을 정할 때, 다음과 같은 규칙을 정합니다.  노드 이름에 특별한 기능이 들어가 있는 경우에는 @를 붙여봅니다.  그런다음, 1 = pick, 2 = animation 라고 규정을 하죠.

 

노드이름이 @12tree 라고 한다면, pick이 되면서 animation이 되는 노드입니다.  즉 이런 노드는 따로 보관을 합니다.  그런 후에 pick이 필요하면 pick만 모아둔 트리에서 pick을 합니다.  Update가 필요하면 animation만 모아둔 트리에서 합니다.  이렇게 하면 성능을 많이 향상시킬 수 있습니다.

 

3. 캐릭터

캐릭터에는 기본적으로 skin 애니메이션이 들어가있습니다.  캐릭터쪽을 향상시키기 위해서는 Update를 최소로 불러주는 것이 좋겠죠.  이 경우 UpdateRigid와 Update를 혼용해서 사용하면 유리합니다.  위치이동은 해주어야 하니까요.  거리와 시야각에 따라서 Update 안하거나, updateRigid와 Update의 횟수를 조절해주면 도움이 될 것으로 보입니다.

 

4. 컬링 & 렌더링

이 부분은 제가 테스트해본 역사가 없습니다만, 듀얼 프로세스 시스템에서는 컬링 프로세스와 렌더링 프로세스를 분리해준다면 괄목할만한 성능 향상이 이루어질 것이라 생각됩니다.

 

5. 컬러스페이스

처음에 제작하는 사람중에서 가장 성능향상에 걸림돌이 되는 것은 컬러스페이스 문제입니다.  DDS를 사용하면 컬러스페이스 문제를 줄여줄 수 있습니다.  그러나 호환성 부분은 당연히 떨어집니다.  컬러스페이스가 서로 다른 경우 게임브리오는 텍스처를 생성할 때마다, 컬러스페이스를 변환합니다.  NiDevImgConverter가 이역할을 하고 있습니다.  컬러스페이스는 픽셀단위로 작업되기 때문에 매우 느립니다.

 

6. 그룹핑

같은 재질, 같은 텍스처를 사용한다면, 폴리곤을 합치는 것이 일반적으로 유리합니다.  그러나 폴리곤의 덩치가 커지면 그려지는 횟수가 많아지므로 이에 대해서 잘 판단해야 합니다.  이에 대해서는 게임브리오 문서에도 나와있습니다.  culling과 clipping의 싸움을 적절하게 조화해주어야 합니다.

 

7. 캐싱

거대존을 사용하는 경우에는 모델링 데이터 및 텍스처 데이터의 캐싱이 들어가게 됩니다.  일반적으로 캐싱할 관리자를 프로그램한 후에 필요한 데이터가 있는 경우 그 데이터를 Clone 함수를 이용해서 가져오게 됩니다.  그런데 여기서 문제가 있습니다.  게임브리오는 노드 트리 구조에서 보았을 때, 인스턴스 복사가 안 되고, 노드 트리 자체를 모두 복사하게 됩니다.  노드들이 많은 경우에는 메모리 낭비가 심하게 되어서 전체적으로 성능이 떨어지게 됩니다.  예를 들어서 성(castle) 오브젝트가 있다고 한다면, 성 오브젝트는 무수히 많은 노드들로 이루어질겁니다.  그런데 사용하는 것은 오직 한번뿐인데 Clone을 이용해서 가져온다면.. 두개의 복사본이 있기 때문에 그만큼 메모리 낭비가 심해집니다.

그래서 오브젝트 캐싱을 할 때에는 참조횟수를 지정해서 처음 참조가 되는 경우에는 자신의 포인터를 바로 넘겨주고, 두번째부터는 clone을 해주는 것이 좋습니다.



출처 : http://cafe.naver.com/dxgameprogramming/249

반응형
Posted by blueasa
, |