470 likes | 725 Views
3D Game Programming. 2 장 01 ~ 05 최하늘. 기초 용어. 3 차원 좌표계 ( 3D Coordinate System ) D3D 는 왼손 좌표계를 사용한다 . 이는 Z 축이 모니터의 안쪽으로 들어가는 방향이다 . 3DS-MAX 의 경우는 오른손 좌표계를 사용 한다 . 데이터를 출력할때 , 왼손 좌표계로 변환해 주어야 한다 . Y, Z 축을 바꾸어 주면 된다. 벡터 ( Vector )
E N D
3D Game Programming 2장01 ~ 05 최하늘
기초 용어 • 3차원 좌표계( 3D Coordinate System ) • D3D는 왼손 좌표계를 사용한다. 이는 Z축이 모니터의 안쪽으로 들어가는 방향이다. 3DS-MAX의 경우는 오른손 좌표계를 사용 한다. 데이터를 출력할때, 왼손 좌표계로 변환해 주어야 한다. Y, Z 축을 바꾸어 주면 된다.
벡터( Vector ) 속력처럼 하나의 값으로 표기 가능한 숫자들을 스칼라( Scalar )라고 하며, 가속도나 속도처럼 크기와 방향을 동시에 표현해야만 정확히 표현할 수 있는 수치를 벡터라고 한다. 2차원 평면상의 벡터와 3차원 평면상의 벡터가 있다. 정점( Vertex ) 2차원이나 3차원 공간에서의 위치( Position )를 나타내는 점( Point )을 정점( Vertex )이라고 한다. 화면상에 실제로 보이게 되는 물리적인 점을 화소( Pixel )라고 한다
변환( Transform ) 이동( Transition ), 회전( Rotation ), 크기( Scale ) 변환이 있다. 행렬( Matrix ) 변환을 할 때에 행렬을 사용한다. 3차원 그래픽에서 데이터량이 많아질수록 유용하다. 폴리곤( Polygon ) 3개의 정점이 모이면 하나의 면( Face )을 만들 수 있는데, 이 삼각형을 폴리곤이라고 한다. 변( Edge ) 폴리곤에서 정점과 정점을 연결하는 직선을 변( Edge )라고 한다. 그림자 볼륨 기법처럼 변을 사용해야 하는 기술이 있다. 메시( Mesh ) 폴리곤들이 모여서 하나의 3차원 물체를 만들어 내는데, 이를 메시라고 한다. 메시는 폴리곤이 모여서 만들어진 3차원 공간의 객체( Object )다.
셰이딩( Shading ) • 셰이딩이란폴리곤에 음영을 넣는 작업을 말한다. 플랫 셰이딩, 고로 셰이딩, 퐁 셰이딩, 라디오시티, 광선추적등이 있다. 이 중 대부분의 비디오 카드에서 지원하는 하드웨어 가속은 플랫 셰이딩과 고로 셰이딩2가지 이다. HLSL등의 정점 셰이더등을 통하여 GPU 수준에서 구현할 수 있다. • 정점 셰이딩이란 정점의 위치를 계산하는 것이고 픽셀 셰이딩이란 화면의 픽셀의 색을 변환하는 것이다.
[DirectX] 행렬과 벡터의 곱, 회전 행렬 다이렉트x 는 행 우선이다.
D3D 의 회전 행렬 X축 Y축 Z축
기초 용어 • 3차원 좌표계( 3D Coordinate System ) • D3D는 왼손 좌표계를 사용한다. 이는 Z축이 모니터의 안쪽으로 들어가는 방향이다. 3DS-MAX의 경우는 오른손 좌표계를 사용 한다. 데이터를 출력할때, 왼손 좌표계로 변환해 주어야 한다. Y, Z 축을 바꾸어 주면 된다.
벡터( Vector ) 속력처럼 하나의 값으로 표기 가능한 숫자들을 스칼라( Scalar )라고 하며, 가속도나 속도처럼 크기와 방향을 동시에 표현해야만 정확히 표현할 수 있는 수치를 벡터라고 한다. 2차원 평면상의 벡터와 3차원 평면상의 벡터가 있다. 정점( Vertex ) 2차원이나 3차원 공간에서의 위치( Position )를 나타내는 점( Point )을 정점( Vertex )이라고 한다. 화면상에 실제로 보이게 되는 물리적인 점을 화소( Pixel )라고 한다
변환( Transform ) 이동( Transition ), 회전( Rotation ), 크기( Scale ) 변환이 있다. 행렬( Matrix ) 변환을 할 때에 행렬을 사용한다. 3차원 그래픽에서 데이터량이 많아질수록 유용하다. 폴리곤( Polygon ) 3개의 정점이 모이면 하나의 면( Face )을 만들 수 있는데, 이 삼각형을 폴리곤이라고 한다. 변( Edge ) 폴리곤에서 정점과 정점을 연결하는 직선을 변( Edge )라고 한다. 그림자 볼륨 기법처럼 변을 사용해야 하는 기술이 있다. 메시( Mesh ) 폴리곤들이 모여서 하나의 3차원 물체를 만들어 내는데, 이를 메시라고 한다. 메시는 폴리곤이 모여서 만들어진 3차원 공간의 객체( Object )다.
셰이딩( Shading ) • 셰이딩이란폴리곤에 음영을 넣는 작업을 말한다. 플랫 셰이딩, 고로 셰이딩, 퐁 셰이딩, 라디오시티, 광선추적등이 있다. 이 중 대부분의 비디오 카드에서 지원하는 하드웨어 가속은 플랫 셰이딩과 고로 셰이딩2가지 이다. HLSL등의 정점 셰이더등을 통하여 GPU 수준에서 구현할 수 있다. • 정점 셰이딩이란 정점의 위치를 계산하는 것이고 픽셀 셰이딩이란 화면의 픽셀의 색을 변환하는 것이다.
Transform Direct3D에서는 변환을 표현하기 위해 4x4 행렬과 1x4 벡터를 사용한다. v = (2, 6, -3, 1) T = x-축으로 10-단위 이동 v’ = v T = (12, 6, -3, 1) 왜 4x4 행렬을 사용하는가? 우리가 원하는 모든 변환(이동, 투영, 반사등을 포함하여)을 행렬로 표현할 수 있기 때문 또한 변환 수행을 위한 벡터-행렬 곱을 일정하게 할 수 있기 때문 Non-homogeneous/Homogeneous coordinates convert (x, y, z) = (x, y, z, 1) (x/w, y/w, z/w) = (x, y, z, w)
[DirectX] 행렬과 벡터의 곱, 회전 행렬 다이렉트x 는 행 우선이다.
D3D 의 회전 행렬 X축 Y축 Z축
이동행렬스케일행렬 S(1/qx, 1/qy, 1/qz) D3DXMATRIX* D3DXMatrixScaling(D3DXMATRIX* pOut, FLOAT sx, FLOAT sy, FLOAT sz); D3DXMATRIX* D3DXMatrixTranslation(D3DXMATRIX* pOut, FLOAT x, FLOAT y, FLOAT z);
WinMain, Direct 3D 초기화, Rendering, Interface 해제 디바이스 생성
WinMain D3D 프로그램의 구조 • RegisterClassEx()로 생성하고자 하는 윈도우의 클래스를 등록 • CreateWindow() 로 윈도우 생성 • InitD3D함수에서 Direct3D 를 초기화 • ShowWindow, UpdateWindow()로 윈도우를 화면에 표시한다. • GetMessage(), TranslateMessage(), DispatchMessage()로 이루어진 루프를 수행한다. • 메시지루프를 빠져나올 경우 초기화한 Direct3D를메모리에서 해제한다. • 프로그램종료.
DirectX 인터페이스는 초기화 시점에서 HWND 핸들을 필요로 하기때문에CreateWindow()로 윈도우를 생성한 다음에 InitD3D()를호출한다. • WM_CLOSE, WM_DESTORY에서 Direct3D를해제하면 문제가 생긴다.
Direct 3D 초기화 함수 • Direct3DCreate9(): Direct3D객체를 생성해서 그 객체의 인터페이스 IDirect3D9를 리턴 해주는 함수. • IDirect3D9는 IDirect3DDevice9을 생성할 때까지만 의미가 있다. • IDirect3D9 인터페이스의 주된 역학을 디바이스 생성이다.
D3DPRESENT_PARAMETERS에 필요한 정보들을 채워 넣는다. • ZeroMemory()위 구조체의 내부를 깨끗이 0으로 지우는 것이다. • IDirect3D9 -> CreateDevice() 윈도우창에출력할것인지 등등의 정보를 초기화한 뒤 CreateDevice()함수에 넘긴다. • CreateDevice() 실제 디바이스를 생성하는 함수이다.
CreateDevice g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice )
CreateDevice HRESULT CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice** ppReturnedDeviceInterface );
Adapter 디바이스를 생성할 화면의 순서 번호 D3DADAPTER_DEFAULT는 기본화면을 나타낸다. 모니터가 한 개 이상인 경우에만 해당된다. DeviceType 출력디바이스의 종류를 결정한다. D3DTYPE_HAL, D3DTYPE_SW, D3DTYPE_REF가 있는데, 이중 D3DDEVICE_HAL이 하드웨어 가속을 지워하는 디바이스이다.
hFocusWindow 디바이스가 출력할 윈도우의 핸들이다. 전체화면 모드일 경우 최상위 윈도우(부모가 없는 윈도우)만이 가능하다. BehaviorFlags 셰이더를지원할때 하드웨어 가속을 사용할 것인지,소프트웨어 가속을 사용할 것인지 결정하는 것. D3DCREATE_HARDWARE_VERTEXPROCESSING과 D3DCREATE_SOFTWARE_VERTEXPROCESSING이 중요하다.
pPresentationParameters 디바이스를 생성할 구조체의 포인터이다. ppReturnedDeviceInterface 전역변수로 선언한 렌더링에 사용될 D3D 디바이스의 값이다. IDirect3DDevice9의 인터페이스를 갖고 있는 포인터가 담겨서 돌아온다.
주의할점 • NVIDIA의 GeForce2 기종은 하드웨어 셰이더를 지원하지 않으므로 D3DCREAT_HARDWARE_VERTEXPROCESSING과 같은 전달인자를 사용할 경우 디바이스가 생성되지 않느다. -> 따라서, 전달인자의 의미를 명확히 알 고 있어야 한다.
Rendering Clear() :먼저 화면을 깨끗이 지운다. BeginScene() : 이제부터 폴리곤을 그리겠다고 D3D에게 알린다. EndScene() : 폴리곤을 다 그렸다고 D3D에게 알린다. Present() :화면에 나타나게 한다.
Present() 의의미 • 실시간 3차원의 그래픽은 2개 이상의 화면으로 구성되어있다. • 내려진 명령들이 후면버퍼에 그려지고, 특정한 명령에 의하여 후면버퍼를 보이는 화면인 전면 버퍼로 전송하게 한다. • 만약, 전면에서 지우고 다시 그리게 되면 깜박임 현상이 나타난다. • 사용자에게 보이지 않는 후면버퍼에서 그리기 작업을 완료한 뒤 Present()를이용해서 전면 버퍼와 바꿔 치는 것이다.
필요 없는 인터페이스 해제 • 해제 순서가 중요하다. • 디바이스는 인터페이스보다 나중에 생성되었다.해제 시, 인터페이스 해제 후 디바이스를 해제한다.
WinMain 윈도우프로시저 정점 버퍼 초기화 함수 사용자정의 정점 구조체 선언 정점구조체에 값 할당 정점 버퍼에 값쓰기 화면에 렌더링하기 Vertex
WinMain • RenderWinMain()의 핵심 부분인 메시지 루프안에 Render()를 넣음. • 이유? 게임의 경우 반응속도가 빨라야 하기 때문이다. • PeekMessageGetMessage() 가PeekMessage()로 바뀜.GetMessage() : 새로운 메시지가 발생할 때까지 대기상태임.PeekMessage() : 메시지가 있으면 처리하고, 없으면 다음 문장 실행.
정점 버퍼 초기화 함수 • D3D 8.0 FVF를 사용해야 정점 셰이더를 사용할 수 있음. • FVF : Flexible Vertex Format 사용자가 직접 정점 구조체를 정의해서 사용하는 방식.
CUSTOMVERTEX • 사용자 정의 구조체 선언 • 구조체와 함께 반드시 플래그 선언도 해주어야 한다. • 구조체 선언부의 내용과 플래그 선언부의 내용이 다를 경우 작동하지 않는다.
정점 구조체에 값 할당 • 정점 버퍼 : D3D에서 가장 중요한 개념중 하나이다.하드웨어 가속을 위해 좋은 것. • 정점버퍼의 메모리: 비디오 메모리, 시스템메모리로 두 가지의 메모리를 사용한다. • 비디오 메모리에 생성된 정점 버퍼 : GPU 의 도움으로 강력한 하드웨어 가속 가능. 하지만 비디오 카드 자체의 메모리 용량은 벗어 날 수 없다. • 시스템 메모리에 생성된 정점 버퍼: 풍부한 용량으로 상대적으로 많은 정점 버퍼를 관리 할 수 있다.
정점 버퍼의 생성 CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL )
정점 버퍼의 구성요소 CreateVertexBuffer( UINT Length, DWORD Usage, DWORD FVF, D3DPOOL pool IDirect3DVertexBuffer9** ppVertexBuffer HANDLE pSharedHandle )
광원 재질의 종류와 기능
광원의 종류 주변광원 (Ambient Light) • 3차원 공간 내에서 메시의 배치나 위치와 상관 없이 똑같은 양으로 모든 곳을 비추는 빛의 강도를 말한다. • 방향, 위치가 없으며 색과 강도 만이 존재한다 g_pd3dDevice-> SetRenderState( D3DRS_AMBIENT, 0x00202020 );
D3DLIGHT9 light; /// 광원 구조체 light.Type = D3DLIGHT_POINT; light.Diffuse.r = 1.0f; /// 광원의 색깔과 밝기 light.Diffuse.g = 1.0f; light.Diffuse.b = 1.0f; g_pd3dDevice->SetLight( 0, &light );// 광원 설치 g_pd3dDevice->LightEnable( 0, TRUE ); // 0번 광원을 켠다 • 점광원(Point Light) • 직관적으로 가장 쉽게 생각할수 있는 빛 • 백열전구.. 광원의 위치에 따라 빛의 감쇠가 발생 • D3DLIGHT_POINT
방향성 광원 (Directional Light) • 모든 광원의 방향이 하나의 방향을 갖는 것으로 ㅎ완벽하지는 않지만 태양을 예로들 수 있다. • 광원의 위치는 상관없고, 방향이 가장 중요한 요소다 • D3DLIGHT_DIRECTIONAL; 점적 광원 (Spot Light) • 정해진 위치와 범위에만 비추는 특수한 조명을 말한다. • 스포트라이트를 생각하면 된다. • D3DLIGHT_SPOT;
SetupLight() SetLight() : 광원설치 LightEnable() : 광원키기 SetRenderState(D3DRS_LIGHTING,TRUE)) : D3D 로하여금 광원 연산을 하도록하는메인스위치 DrawPrimitve() : 재질 설정 재질은 디바이스에 단 하나만 설정 가능
// 광원 설정 VOID SetupLights() { // 재질(material)설정 // 재질은 디바이스에 단하나만 설정 될 수 있다. D3DMATERIAL9 mtrl; ZeroMemory( &mtrl, sizeof(D3DMATERIAL9) ); mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f; mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f; mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f; mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f; g_pd3dDevice->SetMaterial( &mtrl);
// 광원 설정 D3DXVECTOR3 vecDir; // 방향성 광원이 향할 빛의 방향 D3DLIGHT9 light; // 광원 구조체 ZeroMemory(&light,sizeof(D3DLIGHT9)); // 구조체를0으로지운다. light.Type =D3DLIGHT_DIRECTIONAL; // 광원의 종류 light.Diffuse.r =1.0f;// 광원의 색깔과밝기 light.Diffuse.g =1.0f; light.Diffuse.b =1.0f; vecDir =D3DXVECTOR3(cosf(timeGetTime()/350.0f),// 광원의방향