DirectX9 프로그래밍의기초
목 차 DirectX9 프로그래밍의기초 DirectX 그래픽의역사 HAL 과 COM 에대한개요 DirectX9 에서의그리기 Win32API 프로그래밍의개요 Direct3D 초기화 정점 / 인덱스버퍼를이용한그리기 D3DX 기하물체 메쉬의이용 애니메이션및게임실습 2
DirectX 그래픽의역사 DirectX 2.0 1995. DirectX Windows 드라이버제공 DirectX API + Reality Lab(RenderMorphics) + 3D-DDI(Michael Abrash) 1996. Direct3D 3D 가속하드웨어의향상된그래픽능력사용 각하드웨어에대한공통인터페이스지원 장치독립적이고추상화된접근가능 애니메이션및게임실습 3
DirectX 그래픽의역사 DirectX 6/7 즉시모드 (Immediate Mode) 저수준 API 유지모드 (Retained Mode) 즉시모드기반 프레임계층구조및애니메이션기능제공 하드웨어가속변환, 조명, 광원의재조정, 뷰포트객체의지원 텍스처사용의용이성제공 애니메이션및게임실습 4
DirectX 그래픽의역사 DirectX 8 Direct Draw와 Direct3D의통합 데이터의초기화, 할당, 관리의단순화 포인트스프라이트 하드웨어스프라이트사용가능 : 스파크, 폭발, 비 3D 텍스처 3D 볼륨을가지는텍스처사용 정확한픽셀단위조명효과, 포인트광원, 스포트광원, 대기환경효과지원 유틸리티라이브러리 벡터및행렬연산, 이미지파일읽기및텍스처생성단순화 버텍스와픽셀셰이더 어셈블리를이용한하드웨어제어 애니메이션및게임실습 5
DirectX 그래픽의역사 DirectX 9 HLSL(High-Level Shader Language) C 언어와유사한문법, NDIVIA 와공동개발 Scissor Test, Line Anti-Aliasing 텍스처좌표자동생성지원 양면구조의스텐실지원 다중렌더링지원 애니메이션및게임실습 6
HAL 과 COM 에대한개요 하드웨어추상계층 (HAL) Hardware Abstraction Layer 하드웨어와 Direct3D 의중간매개체 애플리케이션 애플리케이션 Direct3D HAL GDI 디바이스드라이버인터페이스 그래픽카드 애니메이션및게임실습 7
HAL 과 COM 에대한개요 플러그블소프트웨어장치 하드웨어에뮬레이션계층 : 하드웨어가 3D 기능을제공하지않는경우 레퍼런스래스터라이저 DirectX SDK에서만제공 하드웨어미지원기능테스트 디바이스제어하기 애니메이션및게임실습 8
Win32API 프로그래밍의개요 New Projects 애니메이션및게임실습 9
Win32API 프로그래밍의개요 An empty pyproject 애니메이션및게임실습 10
Win32API 프로그래밍의개요 New Files c++ source file 애니메이션및게임실습 11
Win32API 프로그래밍의개요 Project Settings Link d3d9.lib d3dx9.lib winmm.lib 애니메이션및게임실습 12
Win32API 프로그래밍의개요 Tools Options Directories Include files 애니메이션및게임실습 13
Win32API 프로그래밍의개요 Tools Options Directories Library files 애니메이션및게임실습 14
Direct3D 초기화 예제 1 애니메이션및게임실습 15
용어및기본함수정리 표면 (surface) Direct3D 가주로 2D 이미지데이터를보관하는데이용하는픽셀의행렬 IDirect3DSurface9 인터페이스이용 LockRect : 표면메모리로의포인터제공 UnlockRect : LockRect 를호출하고표면메모리에대한작업이끝난뒤에는이메서드를호출하여표면의잠금해제 GetDesc : 표면에대한정보를 D3DSURFACE_DESC DESC 구조체를통해획득 애니메이션및게임실습 16
용어및기본함수정리 멀티샘플링 (Multisampling) 픽셀로이미지를표현할때나타나는거친이미지를부드럽게만드는기술 안티알리아싱 D3DMULTISAMPLE_TYPE : 표면에적용할멀티샘플링레벨지정 D3DMULTISAMPLE_NONE : 멀티샘플링미지정 D3DMULTISAMPLE_1_SAMPLE ~ D3DMULTISAMPLE_16_SAMPLE : 1 ~ 16 멀티샘플링레벨지정 애니메이션및게임실습 17
용어및기본함수정리 픽셀포맷 D3DFMT_R8G8B8 : 24bit 포맷 D3DFMT_X8R8G8B8 : 32bit 포맷 D3DFMT_A8R8G8B8 : 32bit 포맷 D3DFMT_X16B16G16R16F : 64bit 포맷 D3DFMT_A32B32G32R32F : 128bit 포맷 애니메이션및게임실습 18
용어및기본함수정리 메모리풀 D3DPOOL_DEFAULT 자원의타입과이용방식에가장적합한자원들을메모리에보관하도록 Direct3D 에요청, ( 비디오메모리, AGP 메모리, 시스템메모리 ) D3DPOOL_MANAGED 관리풀에보관된자원은 Direct3D 에의해관리. 즉, 필요에따라자동으로비디오메모리나 AGP 메모리로이전, 부가적으로자원의백업복사본이시스템메모리내에보관 D3DPOOL_SYSTEMMEM 시스템메모리내에보관될자원지정 D3DPOOL_SCRATCH 시스템메모리내에보관될자원지정 장치는이풀내의자원에직접접근불가능, 그러나자원을두풀사이에서로복사하는것은가능 애니메이션및게임실습 19
용어및기본함수정리 스왑체인 Direct3D 는 2, 3 개의표면을하나의컬렉션으로관리 IDirect3DSwapChain9 인터페이스 스왑체인과플리핑기술 표면 1 표면 2 전면버퍼 후면버퍼 표면 1 표면 2 표면 2 표면 1 전면버퍼 후면버퍼 전면버퍼 후면버퍼 표면 1 표면 2 전면버퍼 후면버퍼 애니메이션및게임실습 20
용어및기본함수정리 깊이버퍼 (Depth buffer) 특정픽셀의깊이정보저장 해상도가 640X480 이면, 깊이버퍼의크기도 640X480 의크기를가짐 깊이버퍼링혹은 z- 버퍼링에이용 D3DFMT_D32 : 32비트깊이버퍼지장 D3DFMT_D24S8 : 24비트깊이버퍼, 8비트스텐실버퍼지정 D3DFMT_D24X8 : 24비트깊이버퍼지장 D3DFMT_D24X4S4 : 24비트깊이버퍼, 4비트스텐실버퍼지정 D3DFMT_D16 D16 :16 비트깊이버퍼지정 애니메이션및게임실습 21
Direct3D 초기화 초기화과정 IDirect3D9 인터페이스의포인터획득 기본디스플레이어댑터 ( 기본그래픽카드 ) 의하드웨어버텍스프로세싱지원여부확인 D3DPRESENT_PARAMETERS 구조체인스턴스초기화 IDirect3DDevice9 생성 애니메이션및게임실습 22
Direct3D 초기화 예제 1 d3dutility.h d3dutility.cpp d3dinit.cpp 애니메이션및게임실습 23
Direct3D 초기화 초기화함수 HRESULT IDirect3DDevice9::Clear ( DWORD Count, // prects 배열내사각형의수 const D3DRECT* prects, // 소거하려는화면사각형의배열 DWORD Flags, // 어떤표면을소거할지지정 D3DCOLOR Color, // 렌더대상을소거할색상 float Z, // 깊이버퍼지정값 DWORD Stencil // 스텐실버퍼지정값 ) Flags D3DCLEAR_TARGET : 렌더대상표면, 보통은후면버퍼 D3DCLEAR_ZBUFFER : 깊이버퍼 D3DCLEAR_STENCIL : 스텐실버퍼 애니메이션및게임실습 24
정점 / 인덱스버퍼를이용한그리기 정점 (vertex) 포맷 Flexible Vertex Format (FVF) x, y, z 좌표 변환정점 블렌딩가중치 법선벡터 정점포인트크기 분산반사색상 반영반사색상 텍스처좌표 1-8 애니메이션및게임실습 25
정점 / 인덱스버퍼를이용한그리기 정점 (vertex) 포맷 struct ColorVertex { float _x, _y, _z; // 위치 DWORD _color; // 색상 } #define FVF_COLOR (D3DFVF_XYZ D3DFVF_DIFFUSE) struct NormalTexVertex { float _x, _y, _z; // 위치 float _nx, _ny, _nz; // 법선벡터 float _u, _v; // 텍스처좌표 } #define FVF_COLOR (D3DFVF_XYZ D3DFVF_NORMAL D3DFVF_TEX1) 애니메이션및게임실습 26
정점 / 인덱스버퍼를이용한그리기 삼각형의정의 Vertex rect[6] = {v0, v1, v2, // 삼각형 0 v0, v2, v3}; // 삼각형 1 v1 v2 삼각형 0 삼각형 1 v0 v3 애니메이션및게임실습 27
정점 / 인덱스버퍼를이용한그리기 인덱스 Vertex vertexlist [4] = {v0, v1, v2, v3}; WORD indexlist [6] = {0, 1, 2, 0, 2, 3}; v1 v2 삼각형 0 삼각형 1 v0 v3 애니메이션및게임실습 28
정점 / 인덱스버퍼를이용한그리기 정점버퍼 정점데이터를보관하는연속적인메모리덩어리 IDirect3DVertexBuffer9 인덱스버퍼 인덱스데이터를보관하는연속적인메모리덩어리 IDirect3DIndexBuffer9 버퍼사용이유 비디오메모리에저장가능 애니메이션및게임실습 29
정점 / 인덱스버퍼를이용한그리기 버퍼만들기 HRESULT IDirect3DDevice9::CreateVertexBuffer( UINT Length, // 버퍼에할당할바이트수 DWORD Usage, // 버퍼가이용되는방법 DWORD FVF, // 유연한정점포맷 D3DPOOL Pool, // 버퍼가위치할메모리풀 IDirect3DVertexBuffer9** t ppvertexbuffer, // 정점버퍼를받을포인터 HANDLE* psharedhandle // 0 ); HRESULT IDirect3DDevice9::CreateIndexBuffer( UINT Length, DWORD Usage, DWORD Format, // 인덱스의크기지정 (D3DFMT_INDEX16, 32) D3DPOOL Pool, IDirect3DIndexBuffer9** ppvertexbuffer, HANDLE* psharedhandle ); 애니메이션및게임실습 30
정점 / 인덱스버퍼를이용한그리기 버퍼메모리에접근하기 HRESULT IDirect3DVertexBuffer9::Lock( UINT OffsetToLock, // 잠금을시작할버퍼위치 UINT SizeToLock, // 잠글바이트의수 BYTE** ppbdata, // 잠근메모리의시작을가리키는포인터 DWORD Flags // 잠금방법 ); HRESULT IDirect3DIndexBuffer9::Lock( UINT OffsetToLock, UINT SizeToLock, BYTE** ppbdata, DWORD Flags ); 버퍼메모리 OffsetToLock SizeToLock OffsetToLock + SizeToLock 애니메이션및게임실습 31
정점 / 인덱스버퍼를이용한그리기 캡슐화 렌더링되는방식을결정하는다양한렌더링상태를캡슐화 렌더상태변경함수 D3DRS_ZENABLE, ALPHATESTENABLE, LIGHITING, HRESULT IDirect3DDevice9::SetRenderState( D3DRENDERSTATETYPE State, DWORD value ) // 변경할상태 // 새로운상태값 _device->setrenderstate(d3drs_fillmode, D3DFILL_WIREFRAME); 애니메이션및게임실습 32
정점 / 인덱스버퍼를이용한그리기 스트림소스지정 스트림소스를정점버퍼와연결하여버퍼의기하정보를렌더링파이프라인에보냄 HRESULT IDirect3DDevice9::SetStreamSource( UINT StreamNumber, IDIRECT3DVertexBuffer9* pstreamdata, UINT OffsetInBytes, UINT Stride ) // 스트림소스지정 // 정점버퍼포인터 // 시작오프셋 // 바이트수 _device->setstreamsource( S S (0, vb, 0, sizeof(vertex) )); 애니메이션및게임실습 33
정점 / 인덱스버퍼를이용한그리기 정점포맷지정 _device->setfvf(d3dfvf_xyz D3DFVF_DIFFUSE D3DFVF_TEX1) 인덱스버퍼지정 _device device->setindices(ib); 애니메이션및게임실습 34
정점 / 인덱스버퍼를이용한그리기 정점버퍼를이용한그리기 기하정보를렌더링파이프라인으로보내는실질적인드로잉과정수행 HRESULT IDirect3DDevice9::DrawPrimitive( D3DPRIMITIVETYPE Pi PrimitiveType, ii // 기본형타입 UINT StartVertex, // 읽기시작할정점스트림 UINT PrimitiveCount // 기본형의수 ) _device->drawprimitive(d3dpt_trianglelist, 0, 4); 애니메이션및게임실습 35
정점 / 인덱스버퍼를이용한그리기 인덱스를이용한그리기 typedef enum _D3DPRIMITIVETYPE { D3DPT_POINTLIST = 1, D3DPT_LINELIST = 2, D3DPT_LINESTRIP = 3, D3DPT_TRIANGLELIST TRIANGLELIST = 4, D3DPT_TRIANGLESTRIP = 5, D3DPT_TRIANGLEFAN = 6, D3DPT_FORCE_DWORD = 0x7fffffff } D3DPRIMITIVETYPE; 애니메이션및게임실습 36
정점 / 인덱스버퍼를이용한드로잉 인덱스를이용한그리기 HRESULT IDirect3DDevice9::DrawIndexedPrimitive( D3DPRIMITIVETYPE Pi PrimitiveType, ii // 기본형타입 INT BaseVertexIndex, // 호출될기반번호 UINT MinIndex, // 참조할최소인덱스값 UINT NumVertices, // 정점의수 UINT StartIndex, // 인덱스버퍼내의시작점 UINT PrimitiveCount // 기본형의수 ) _device->drawindexedprimitive(d3dpt_trianglelist, 0, 0, 8, 0, 12); 애니메이션및게임실습 37
정점 / 인덱스버퍼를이용한드로잉 예제 애니메이션및게임실습 38
D3DX 기하물체 메쉬생성함수 D3DX 라이브러리에서지원하는함수 D3DXCreateBox D3DXCreateSphere D3DXCreateCylinder D3DXCreateTeapot D3DXCreatePolygon D3DXCreateTorus 애니메이션및게임실습 39
D3DX 기하물체 예제 : Box 애니메이션및게임실습 40
D3DX 기하물체 예제 : Teapot 애니메이션및게임실습 41
D3DX 기하물체 예제 : Sphere, Cylinder, Torus, Teapot, Box 애니메이션및게임실습 42
메쉬 (Mesh) 정의 정점및삼각형들의모음 + 텍스처 필요성 구성 정점및삼각형들을하나의객체로묶을수있음 다양한객체들의효율적관리용이 장면을구성하는객체 객체들사이의관계 애니메이션및게임실습 43
기하정보 ID3DXBaseMesh 정점버퍼와인덱스버퍼 HRESULT ID3DXMesh::GetVertexBuffer(LPDIRECT3DVERTEXBUFFER9* ppvb); HRESULT ID3DXMesh::GetIndexBuffer(LPDIRECT3DINDEXBUFFER9* ppib); 버퍼의사용 IDirect3DVertexBuffer9* vb = 0; Mesh->GetVertexBuffer(&vb); IDirect3DIndexBuffer9* ib = 0; Mesh->GetIndexBuffer(&ib); 애니메이션및게임실습 44
기하정보 ID3DXBaseMesh 버퍼의잠금 / 해제 HRESULT ID3DXMesh::LockVertexBuffer(LPDIRECT3DVERTEXBUFFER9* e 3 V ppvb); HRESULT ID3DXMesh::LockIndexBuffer(LPDIRECT3DINDEXBUFFER9* ppib); HRESULT ID3DXMesh::UnLockVertexBuffer(); HRESULT ID3DXMesh::UnLockIndexBuffer(); 부가적인기하관련정보 DWORD GetFVF() DWORD GetNumVertices() DWORD GetNumBytesPerVertex() DWORD GetNumFaces() : 정점의정점포맷리턴 : 정점버퍼내의정점의수리턴 : 정점당바이트수리턴 : 메쉬내의삼각형의수리턴 애니메이션및게임실습 45
서브셋과속성버퍼 서브셋 동일한속성을이용해렌더링할수있는메쉬내삼각형의그룹 속성 : 재질, 텍스처, 렌더상태 집 서브셋 0 : 바닥바닥속성을이용해서브셋내의삼각형들을렌더링한다. 서브셋 1 : 벽벽속성을이용해서브셋내의삼각형 서브셋 2 : 천정천정속성을이용해서브셋내의삼각형들을렌더링한다. 서브셋 3 : 창문창문속성을이용해서브셋내의삼각형 들을렌더링한다. 들을렌더링한다. 애니메이션및게임실습 46
서브셋과속성버퍼 속성버퍼 속성 ID : DWORD 속성버퍼내의항목 : 인덱스버퍼에정의된삼각형 속성버퍼 0 1 n 삼각형 0 삼각형 1 삼각형 n 인덱스버퍼 0 1 2 0 2 3 20 22 23 애니메이션및게임실습 47
서브셋과속성버퍼 속성버퍼 잠금 / 해제 DWORD* buffer = 0; Mesh->LockAttributeBuffer(lockingFlags, &buffer); Mesh->UnlockAttributeBuffer(); 애니메이션및게임실습 48
드로잉 DrawSubset() 속성 ID 로지정한특정서브셋의삼각형그리기 Mesh->DrawSubset(0); for(int i=0;i<numsubsets;i++) { Device->SetMaterial(mtrls[i]); Device->SetTexture(0, textures[i]); Mesh->DrawSubset(i); } 애니메이션및게임실습 49
최적화 메쉬최적화 효과적인메쉬렌더링을위해서점과인덱스재구성 HRESULT ID3DXMesh::OptimizeInplace( DWORD Flags, CONST DWORD* padjacencyin, DWORD* padjacencyout, DWORD* pfaceremap, LPD3DXBUFFER* ppvertexremap ); // 최적화플래그 // 최적화전인접정보 // 최적화후인접정보 // 면리맵정보 // 정점리맵정보 애니메이션및게임실습 50
최적화 메쉬최적화 Flags D3DXMESHOPT_COMPACT D3DXMESHOPT_ATTRSORT D3DXMESHOPT_VERTEXCACHE D3DXMESHOPT_STRIPREORDERSTRIPREORDER D3DXMESHOPT_IGNOREVERTS 설명 이용하지않는정점과인덱스제거 속성으로삼각형정렬, 속성테이블생성효율증대 정점캐시의히트율향상 삼각형스트립이가능한길어지도록인덱스재구성 정점을무시하고인덱스정보만을최적화 애니메이션및게임실습 51
최적화 메쉬최적화사용예 // 최적화되지않은메쉬의인접정보획득 DWORD adjacencyinfo[mesh->getnumfaces()*3]; Mesh->GenerateAdjacency(0.0f, adjacencyinfo); // 최적화된인접정보를보관할배열 DWORD optimizedadjacencyinfo[mesh->getnumfaces()*3]; Mesh->OptimizeInplace( D3DXMESHOPT_ATTRSORT D3DXMESHOPT_COMPACT D3DXMESHOPT_VERTEXCACHE, adjacencyinfo, optimizedadjacencyinfo, 0, 0 ); 애니메이션및게임실습 52
최적화 Optimize 최적화된메쉬반환 HRESULT ID3DXMesh::Optimize( DWORD Flags, CONST DWORD* padjacencyin, DWORD* padjacencyout, DWORD* pfaceremap, LPD3DXBUFFER* ppvertexremap, LPD3DXMESH* ppoptmesh ) 애니메이션및게임실습 53
속성테이블 D3DXMESHOPT_ATTRSORT 메쉬기하정보가속성에따라정렬 정점버퍼및인덱스버퍼내에있는특정부분의기하정보가연속된블록에위치 속성테이블생성 삼각형 0 삼각형 0 삼각형 0 속성버퍼 0 0 0 1 1 1 1 1 2 2 인덱스버퍼 Tri : 0 Tri : 1 Tri : 2 Tri : 3 Tri : 4 Tri : 5 Tri : 6 Tri : 7 Tri : 8 Tri : 9 애니메이션및게임실습 54
속성테이블 속성테이블 D3DXATTRIBUTERANGE 구조체 테이블의각항목은메쉬의각서브셋과대응 서브셋의기하정보들의보관되는정점 / 인덱스버퍼내의메모리블록지정 typedef struct _D3DATTRIBUTERANGE { DWORD AttribId; // 서브셋 ID DWORD FaceStart; // 현재서브셋의인덱스버퍼오프셋 DWORD FaceCount; // 삼각형의수 DWORD VertexStart; // 현재서브셋의정점버퍼오프셋 DWORD VertexCount; // 서브셋내의정점의수 } D3DXATTRIBUTERANGE; 애니메이션및게임실습 55
속성테이블 속성테이블의접근 HRESULT ID3DMesh::GetAttributeTable( D3DXATTRIBUTERANGE* pattribtable, DWORD* pattribtablesize ) 속성테이블내의속성의수반환 DWORD numsubsets = 0; Mesh->GetAttributeTable(0, &numsubsets); 속성데이터로구조체의배열채우기 D3DXATTRIBUTERANGE table = new D3DXATTRIBUTERANGE[numSubsets]; Mesh->GetAttributeTable(table, GtAttibtTbl(t bl &numsubsets); Sb t) 애니메이션및게임실습 56
근접정보 인접정보 주어진삼각형과인접한다른삼각형에대한정보 Tri : 2 Tri : 1 Tri : 0 Tri : 0-1 -1 1 Tri : 1 0-1 2 Tri : 2-1 -1 1 애니메이션및게임실습 57
근접정보 인접정보의생성 HRESULT ID3DXMesh::GenerateAdjacency( FLOAT fepsilon, // 유사도 : 거리근사값 DWORD* padjacency // 인접정보포인터 ) DWORD adjacencyinfo[mesh->getnumfaces()*3]; Mesh->GenerateAdjacency(0.001f, adjacencyinfo); 애니메이션및게임실습 58
복제 CloneMeshFVF HRESULT ID3DXMesh::CloneMeshFVF( DWORD Options, // 플래그 DWORD FVF, // 유연한정점포맷 LPDIRECT3DDEVICE9 pdevice, // 복제된메쉬와연계될장치 LPD3DXMESH* ppclonemesh // 복제된메쉬 ) Options D3DXMESH_32BIT D3DXMESH_MANAGEDMANAGED D3DXMESH_WRITEONLY D3DXMESH_DYNAMICDYNAMIC 설명 32비트인덱스이용관리메모리풀내에보관쓰기전용동적생성 애니메이션및게임실습 59
메쉬만들기 빈메쉬만들기 HRESULT D3DXCreateMeshFVF( DWORD NumFaces, DWORD NumVertices, DWORD Options, DWORD FVF, LPDIRECT3DDEVICE9 pdevice, LPD3DXMESH* ppmesh ); // 면의수 // 정점의수 // 플래그 // 유연한정점포맷 // 생성할메쉬와연계될장치 // 생성된메쉬 애니메이션및게임실습 60
메쉬만들기 빈메쉬만들기 HRESULT D3DXCreateMesh( DWORD NumFaces, // 면의수 DWORD NumVertices, // 정점의수 DWORD Options, // 플래그 CONST LPD3DVERTEXELEMENT9* pdeclaration, // 정점포맷 LPDIRECT3DDEVICE9 pdevice, // 생성할메쉬와연계될장치 LPD3DXMESH* ppmesh // 생성된메쉬 ); 애니메이션및게임실습 61
메쉬만들기 순서 빈메쉬만들기 상자의기하정보로메쉬채우기 메쉬의각면이존재하는서브셋지정 메쉬의인접정보만들기 메쉬최적화 메쉬그리기 애니메이션및게임실습 62
메쉬만들기 예제 애니메이션및게임실습 63
Question? 애니메이션및게임실습 64