next를 눌러 다음으로


typical은 기본적으로 설정되어 있는 프로그램들만 인스톨됨.
custom은 자신이 마음대로 설치할 수 있음.
잘 아시는 분은 custom쓰시면 되구요. 잘 모르시는 분들은 typical쓰시면 됩니다.


어떤 환경에서 작업을 하실것인지 설정하는 것입니다.
debuggers는 vmware가 문제가 생겼을 경우 그 시스템을 디버깅하기 위해 있는것입니다.
visual studio쓰시는 분은 첫번재 체크
eclipse로 자바프로그래밍 하시는 분은 두번재 체크
eclipse로 c나 c++쓰시는 분은 세번째것을 체크해주세요.
프로그래밍 안하시는 분은 체크안해도 됩니다.


이건 영어읽어보면 다 알겠죠?


인스톨 되네요...


시리얼 넘버 입력해주시구요.


끝났습니다. 이제 Workstation설정하면 되겠네요.

BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin,
                                UINT wMsgFilterMax);
리턴값 - false면 윈도우 종료

BOOL PeekMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin,
                                UINT wMsgFilterMax,UINT wRemoveMsg);
리턴값 - 메시지를 가져오면 true, 가져오지 못하면 false

LPMSG lpMsg
 - 메세지 구조체의 포인터
HWND hWnd
 - 메세지 큐를 확인할 윈도우의 핸들
UINT wMsgFilterMin
 - 최소값을 넘겨주면 최소값보다 작은 메세지는 가져오지 않는다. (보통 0)
UINT wMsgFilterMax
 - 최대값을 넘겨주면 최대값보다 큰 메세지는 가져오지 않는다. (보통 0)
UINT wRemoveMsg
 - 플래그 값



차이점 - GetMessage함수는 메시지 큐에서 메시지를 받아올 때까지 계속 기다린다.
           하지만 PeekMessage함수는 메시지큐에 메시지가 없어도 기다리지 않고 false를 리턴한다.


활   용 - 메시지 큐에 메시지가 없을 때, 데드타임이 발생하는데
         GetMessage를 사용한다면 데드타임을 활용할 수 없다.
         하지만 PeekMessage를 사용할 경우 이 데드타임을 활용할 수 있다.

데드타임 - 이 때는 주로 프레임을 그려주거나 프레임을 업데이트 시켜주는 일을 시킨다.

 3D를 맨처음 공부하기 전에 꼭 한번 해주면 좋은 실습이 하나 있다. 그것이 바로 랜더링 파이프라인을 API로 직접 구현해 보는 것!!

void LocalSpace(); //물체를 생성

void WorldSpace(); //생성한 물체를 세계에 적용

void ViewSpace(); //세계를 카메라(자신의 시선)에 맞게 재배치

void Culling();  //그려질 것만 추려내고(벽 뒤에 있는 물체나 벽의 뒷면은 그려줄 필요가 없다.)

void Lighting(); //광원효과(빛)을 주고

void Projection(); //원근감을 주기 위해(z축(깊이감)을 적용하는 과정)

void ViewPort(); //보여줄 창의 크기를 잡아주고

void 래터라이즈();

//3D 이미지를 2D로(적용된 z축(깊이)을 x와 y에 적용한다. - 모니터는 x축과 y축밖에 없다.)

void Rendering(); //그림을 그려준다.

일단 이렇게 함수명만 먼저 선언해두고...
행렬클래스(4X4행렬)를 제작하고,
(행렬끼리의 덧셈 뺄셈 곱셈, 행렬과 상수의 곱셈을 operator로 만들어준다. 물론 단위행렬로 만들어주는 함수도 추가해준다.)
3차원 벡터클래스도 제작하고,
(벡터의 외적, 내적 벡터끼리의 곱셈 뻴셈 덧셈, 벡터와 상수의 곱셈 함수도 만들고...)
카메라 클래스는 해골책이네 용책에 나와있는것을 그대로 쓰면된다.

그리고 여러가지 정보를 찾아가면서 함수를 채워넣어가면 된다.

랜더링 하는 방법은 점을 이용해서 API함수에 있는 점을 잇는 함수를 쓰면 됩니다.

컬링이랑 라이트를 뺀 랜더링파이프라인으로 구현한 것이다~!!


 여러개의 쓰레드가 동시에 하나의 변수를 변경시켜줄 때, 문제가 생기는 것을 방지하기 위해 쓰레드에 순위를 매겨서 처리하는 방식의 세마포어와는 달리 뮤텍스는 쓰레드가 들어오는 순서대로 처리해 주는 방식으로 사용한다.



class CMutex
{
private:
    static HANDLE m_mutex;    //뮤텍스 핸들
    DWORD m_owner; //지금 Lock되어있는 Thread ID값
public:
    static void Init();
    static void Remove();
    CMutex();
    ~CMutex();
    void Lock();
    void Unlock();
};

void CMutex::Init()
{
    m_mutex = CreateMutex(NULL,FALSE,NULL);
    memset(&m_owner, 0, sizeof(DWORD));
}
void CMutex::Remove()
{
    WaitForSingleObject(m_mutex,INFINITE);
    CloseHandle(m_mutex);
}

CMutex::CMutex()
{
}

CMutex::~CMutex()
{
}

void CMutex::Lock()
{
 DWORD ThreadID = GetCurrentThreadId();
    if(m_owner != ThreadID)
    {
        WaitForSingleObject(m_mutex,INFINITE);
        m_owner = ThreadID;<br />
    }
}

void CMutex::UnLock()
{
    DWORD ThreadID = GetCurrentThreadId();
    if(m_owner == ThreadID)
    {
        ReleaseMutex(m_mutex);
        memset(&m_owner,0,sizeof(DWORD));
    }
}
 

 쓰레드에서 다른 쓰레드와 공유중인 변수를 쓰기전에 Lock()로 막아 놓으면 WaitForSingleObject(m_mutex,INFINITE)에 의해 다른 쓰레드는 뮤텍스가 ReleaseMutex(m_mutex)되기를 기다리게 된다.



예전에 한번 파티클을 구현해 본적이 있는데 꽤나 단순하게 구현했습니다.
 그냥 아무렇게나 규칙에 맞춰 화면에 텍스쳐 잔뜩 뿌려주고, 좌표값 바꿔주고, 색상값 바꿔주고, 로테이션값 바꿔주면 됩니다. 하지만 그냥 이렇게만 하면 자연스러운 파티클은 나오지 않습니다.

위    - 자연스럽지 못한 파티클
아래 - 자연스러운 파티클

  위쪽 사진은 그냥 텍스쳐를 부려주는 것이고, 아래쪽의 사진은 텍스쳐를 뿌려주며 텍스쳐들의 색상값을 겹치게 하여 뿌리는 것입니다.

DXUTGetD3D9Device()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
DXUTGetD3D9Device()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
DXUTGetD3D9Device()->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);

 Draw하기 전에 위의 세줄을 입력하여 출력결과를 보십시요. 아마... 배경색과 합쳐져서 보이게 될 것입니다. 하지만 배경의 색이 검은색이라면 색이 전혀 합쳐지지 않고 그대로 출력되는 것을 볼 수 있습니다. 하지만 항상 배경색이 검은색으로 돼있을리는 없습니다.


void SetRenderTarget(LPDIRECT3DTEXTURE9 pTexture)
{
 LPDIRECT3DSURFACE9 pSurface;
 HRESULT hr = pTexture->GetSurfaceLevel(0, &pSurface);
 DXUTGetD3D9Device()->SetRenderTarget(0, pSurface);
 pSurface->Release();
}

void SetRenderTargetToOrigin(LPDIRECT3DSURFACE9 pTexture, bool EXIT)
{
 static LPDIRECT3DSURFACE9 _Origin = pTexture;
 DXUTGetD3D9Device()->SetRenderTarget(0,_Origin);
 if(EXIT)
  _Origin->Release();
}

 위의 두 함수는 사용자 정의 함수입니다. 첫번째 역할은 백버퍼를 자신이 원하는 LPDIRECT3DTEXTURE9형을 가진 변수로 바꾸는 것이고, 두번째 함수의 역할은 백버퍼를 원래의 백버퍼로 돌려놓는 것입니다. 
 SetRenderTarget을 이용해 어떤 텍스처에 그릴지 선택하고 그 텍스처에 r:0 g:0 b:0 a:0으로 색을 맞춰서 클리어해줍니다. 그리고 자신이 그리고 싶은 그림(Texture)을 그립니다(render). 그 다음SetRenderTargetToOrigin함수를 이용해 원래의 백버퍼로 렌더타겟을 잡습니다. 그리고 거기에 아까전에 Render를 마친 텍스쳐를 한번 더 뿌려줍니다.

하루에 6시간 3일 총 18시간을 투자해서 그래퍼&프로그래머 각각 한명씩해서 단 2명이 만든 리듬게임...
처음 만들기 시작했을 땐 불가능 할 줄 알았는데 막상 제작이 완료되니...


일단 메뉴.. 심플하다..ㅋㅋㅋ 저 오른쪽 아래 보이는 X버튼이 나가기버튼
게임 스타트 누르면 다음으로 넘어간다. 제작 기간은 30분??도 안걸렸을 것이다.

게임 세팅부분... 음악 선택하고 속도조절 난이도 조절 음악 미리듣고 랭킹도 보여주고
이 부분은 뭐 2시간만에 만들었던가... 나름 쉬웠다. 그냥 파일입출력이 제일 어려웠음.

그냥 미친듯이 막 코딩하다보니 나왔다... 그다지 어려운 부분은 없었는데 작업분량이 제일 많아서.... 제길..ㅜ;;



어려워 어려워 어려워..ㅜ;; 노트찍는게 제일 어려웠음.. 툴만들어서 음악들으면서 리듬에 맞춰 탁탁찍어줘야하니... 리듬게임 잘 못해서 노트찍는것도 꽤나 걸렸다. 노트 제작기간 2시간?

이거 이거 이거 만드는거 상당히 짜증났다..ㅡ;;
그냥 대충 코딩하다보니까 소스가 몇줄인지도 모르겠고... 어디에 뭐가있는지 짐작으로만 알뿐...
이거 끼워넣는데 버그가 좀 발생해서 그거 잡느라 짜증이 짜증이...

후후후.. 타이틀과 마찬가지로 엄청 쉬웠던 부분... 몇분걸렸더라??


우와 이부분 뭔가 상당히 많아서 효과넣어주고 하느라....
x누르면 랭킹등록창으로 넘어가고 또 누르면 타이틀로 간다.
제작기간은 몇시간이더라.. 좀 걸렸다...


이거 만드는게 제일 힘들었다...
랭킹등록... 제일 못하는 파일입출력..ㅜ;;
저거 만드는데만 몇시간 아직도 못잡은 버그가...


이렇게 게임 제작 완료 ㅋㅋㅋ