용책 100p 에서 시작
struct ColorVertex
{
float _x, _y, _z; //위치
DWORD _Color;
};
//또는
struct NormalTexVertex
{
float _x, _y, _z;
float _nx, _ny, _nz; //법선
float _u, _v;//텍스쳐 좌표
};
{위치, 색상} 또는 {위치, 법선벡터, 텍스쳐 좌표}
#define FVF_COLOR (D3DFVF_XYZ | D3DFVF_DEFFUSE)
// 또는
#define FVF_NORMAL_TEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
주의 : 버텍스 구조체에 정의된 데이터의 순서와 FVF의 정의된 순서는 반드시 일치해야 한다.
두르기 순서 : 도형을 만들 때 버텍스를 지정하는 순서
3D 장면을 구성한 뒤 모니터에 2D로 표현하는 과정을 랜더링 파이프라인이라고 한다.
랜더링 파이프라인 순서
- 로컬 스페이스
- 월드 스페이스
- 뷰 스페이스
- 후면 추려내기
- 조명
- 클리핑
- 투영
- 뷰포트
- 래스터라이즈
우리가 삼각형 리스트를 정의하는데 사용하는 좌표공간
다수의 오브젝트를 구성한 뒤 로컬에서 월드 변환을 통해 월드 좌표로 옮긴 공간
여기서 말하는 변환은 선형변환을 말한다.(크자이공부 순서로 해야됨)
월드 스페이스를 카메라를 기준으로 변환한 공간
D3DXMATRIX* D3DXMatrixLookAtLH
{
D3DXMATRIX* pOut, // 결과 행렬을 받을 포인터
CONST D3DXVECTOR3* pEye, // 월드에서 카메라 위치
CONST D3DXVECTOR3* pAt // 카메라가 보는 지점
CONST D3DXVECTOR3* pUp //월드의 업 벡터 - (0,1,0)
};
//사용할때
Device->SetTransform(D3DTS_VIEW, &V);
Device->SetRenderState(D3DTS_CULLMODE, Value);
완전한 내부 : 완전히 카메라 절두체 내부에 있으면 통과
완전한 외부 : 절두체 밖이면 추려내짐
부분적 내부 : 부분적으로 내부에 있으면 그만큼 삼각형을 분리해서 부분적으로 추려낸다.
D3DXMATRIX* D3DXMatrixPerspectiveFovLH(
D3DXMATRIX* pOut, //투영 행렬을 리턴
FLOAT forY, // 시야각의 수직 영역(라디안)
FLOAT Aspect, //종횡비 = 너비/높이
FLOAT zn, // 가까운 평면까지의 거리
FLOAT zf, // 먼 평면까지의 거리
)
/*
D3DTS_PROJECTION에 변환 타입을 전달하고
IDirect3DDevice9::SetTrensform 매서드를 호출하면 투영 행렬을 얻을 수 있다.
*/
D3DXMATRIX proj;
D3DXmatrixPerspectiveFovLH(
&proj, PI * 0.5f,
(float)width / (float)height, 1.0, 1000.0f);
Device->SetTransform(D3DTS_PROJECTION, &proj);
typedef struct _D3DVIEWPORT9{
DWORD X;
DWORD Y;
DWORD Width;
DWORD Height;
DWORD MinZ; // 최소 깊이 버퍼 (D3D 에서 버퍼 범위 = [0,1])
DWORD MaxZ; // 최대 깊이 버퍼 ([0,1])
} D3DVIEWPORT9;
D3DVIEWPORT9 vp = {0, 0, 640, 480, 0, 1};
Device->SetViewport(&vp);

출처 용책
// 버텍스 버퍼
HRESULT IDirect3DDevice9 :: CreateVertexBuffet(
UNIT Length, // 버퍼에 할당할 바이트 수
DWORD Usage, // 버퍼 이용 옵션
DWORD FVF, // 버퍼에 보관될 버텍스의 유연한 버텍스 포멧
D3DPOOL Pool // 버퍼가 위치할 메모리 풀
IDirect3DVertexBuffer9** ppVertxBuffer, // 만들어질 버텍스 버퍼를 받을 포인터
HANDLE* pSharedHandle // 안쓰는거임 (0 넣으면 됨)
);
// 인덱스 버퍼
HERSULT IDirect3DDevice9::CreateIndexBuffer(
UNIT Length,
DWORD Usage,
DWORD FVF,
D3DFIRMAT Format, // 인덱스 크기
D3DPOOL Pool
IDirect3DVertexBuffer9** ppVertxBuffer, //만들어질 인덱스 버퍼를 받을 포인터
HANDLE* pSharedHandle
- 0 : 옵션 없음
- D3DUSAGE_DYNAMIC : 버퍼를 동적으로 만든다.
- D3DUSAGE_POINTS : 버퍼가 포인트 기본형을 보관함.
- D3DUSAGE_SOFTWARPROCESSING : 버텍스 프로세싱을 소프트웨어로 처리함
- D3DUSAGE_WRITEONLY : 쓰기 전용
정적 버퍼 : 연산이 빠르지만 갱신이 느림 -> 잘 안 변하는 지형 등에 씀
동적 버퍼 : 갱신이 빠르지만 비디오 메로리로 전송해야 돼서 연산이 느림 : 자꾸 변하는 플레이어 등의 오브젝트에 씀
D3DVERTEXBUFFER_DESC vbDescription;
_vertexBuffer->GetDesc(&vbDescription); // 버텍스 버퍼 정보를 얻는다.
D3DINDEXBUFFER_DESC ibDescription;
_indexBuffer->GetDesc(&ibDescription); // 인덱스 버퍼 정보를 얻는다.
렌더 상태 변경
HRESULT IDirect3DDevice9::SetRenderState(
D3DRENDERSTATETYPE State, // 변경할 상태
DWORD Value //새로운 상태 값
인덱스 정보를 안 쓰는 기본형 그리기
HRESULT IDirect3DDevice9::DrawPrimitive(
D3DPRIMITIVETYPE PrimitiveType, //그릴 기본형 타입
UNIT StartVertex, //버텍스 읽기를 시작할 버텍스 스트림 요소로의 인덱스
UNIT PrimitiveCount // 그릴 기본형의 수
);
인덱스 정보를 쓰는 기본형 그리기
HRESULT IDirect3DDevice9::DrawIndexedPrimitive(
D3DPRIMITIVETYPE Type, //그릴 기본형 타입
INT BaseVertexIndex, // 이번 호툴에 이용할 인덱스에 더해질 기반 번호
UINT MinIndex, // 참조할 최소 인덱스 값
UINT NumBertices, // 참조할 버텍스의 수
UINT StartIndex, // 인덱스 버퍼 내에서 읽을 인덱스
UINT PrimitiveCount //그릴 기본형 수
);
=========================
모든 드로잉은 IDirect3DDevice9::BeginScene 과 IDirect3DDevice9::EndScene 호출 내부에 포함되어야 한다.
===================
_device->BeginScene();
mesh->DrawSubset(0); // 매쉬 랜더링
_device->ENdScene();
...
//메쉬 다썼으면 해제하기
_mesh->Release();
_mesh = 0;
D3DCOLOR birghtRed = D3DCOLOR_ARGB(255, 255, 0, 0);
typedef struct _D3DCOLORVALUE{
float r; float g; float b; float a; //범위 [0,1]
}D3DCOLORVALUE;
오버로딩된거
- 형변환
- += 같은 할당연산자
- 단항연산자
- 이항연산자
struct ColorVertex
{
float _x, _y, _z;
D3DCOLOR _color;
static const DWORD FVF;
}
const DWORD ColorVertex::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
참고로 FVF 는 Flaxible Vertrx Format : 각 정점의 버텍스를 나타내는 방식이라고 함.
///플랫 셰이딩 모드로 지정
Device->SetRenderState(D3DRS_SGDEMODE, D3DSHADE_FLAT);
///그라우드 셰이딩 모드로 지정
Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
재질에 따라 흡수하는 색을 정할 수 있게 할 수 있다.
typedef struct _D3DMATRIAL9
{
D3DCOLORVALUE Diffuse; // 표면이 반사하는 난반사광의 양
D3DCOLORVALUE Ambient; // 표면이 반사하는 환경광의 양
D3DCOLORVALUE Specular; // 표면이 반사하는 정반사광의 양
D3DCOLORVALUE Emissive; // 전반적인 표면의 컬러를 더하는데 사용함.
float Power; // 정반사광의 sharpness 를 지정하며, 높을수록 하이라이트가 강조됨.
} D3DMATRIAL9;
face normal : 면의 법선벡터
버텍스 법선 : ㅋㅋ점에 법선이 어딨냐, 법선이 속한 face 들의 법선들의 평균 정도로 생각하면 된다.(다른 경우도 있긴 한데 뭐..)
앞으로 버텍스의 색을 계산하는 데 조명을 이용할 것이기 때문에 버텍스 구조체에서 컬러 맴버변수는 제거한다.
무슨 도형을 쓸지, 복잡한 경우 어떤 모양일지 아에 모르니까 걍 버텍스 세개 가지고 면의 법선을 구하는 방식이 사용된다.
void ComputeNormal(D3DXVECTOR3* p0,
D3DXVECTOR3* p1,
D3DXVECTOR3* p2,
D3DXVECTOR3* out) //시계방향 두르기 유지하기
{
D3DXVECTOR3 u = *p1 - *p0;
D3DXVECTOR3 v = *p2 - *p0; // 점 세개로 벡터 두개 구하고 외적할거임
D3DXVec3Cross(out, &u, &v);
D3DXVec3Normalize(out, out);
}
변환 단계에서 버텍스 법선이 왜곡되는 현상이 발생할 수 있으므로, D3DRS_NORMALIZENORMALS 랜더 상태를 활성화하여 변환 단계 이후에 Direct3D가 모든 법선을 다시 정리하도록 하는 것이 안전하다.
Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
D3D는 세 가지 타입의 광원을 지원한다.
- 점 광원 : 월드 스페이스 내에 위치를 가지며, 모든 방향으로 빛을 발산한다.
- 방향성 광원 : 위치는 가지지 않지만, 지정된 방향으로 평행하게 빛을 발산한다.
- 스포트(spot) 광원 : 손전등 빛처럼 위치를 가지며 특정한 방향으로 원뿔 형태의 빛을 발산한다. 안쪽의 원뿔(Theta)과 바깥쪽의 원뿔(phi) 두 가지 각도에 의해 원뿔의 모양이 결정된다.
typedef sturct _D3DLIGHT9
{
D3DLIGHTTYPE Type; //만들려는 광원의 타입
D3DCLOLRVALUE Diffuse; // 난반사광의 색
D3DCLOLRVALUE Specular; // 정반사광의 색
D3DCLOLRVALUE Ambient; // 환경광의 색
D3DVECTOR Position; // 광원의 위치 (없는경우 의미 없음)
D3DVECTOR Direction; // 빛의 방향 (점 광원에선 안씀)
float Range; // 빛이 진행 가능한 최대거리
float Falloff; // (소프트 광원에서) 밖과 안 원뿔의 빛 세기 차이
float Attenuation0; // 거리에 따라 빛의 세기가 약해지는 정도
float Attenuation1;
float Attenuation2;
float Theta; //안쪽 원뿔의 각도
float Phi //바깥쪽 원뿔의 각도
}D3DLIGHT9;
Attenuation 은 점 광원과 스폿 광원에서만 이용한다.
세 변수는 차례대로 상수감소, 선형감소, 이차감소를 정의한다.
D3DLIGHT9 객체를 만든 후 D3D가 관리하는 내부 리스트에 등록해야 한다.
Device->SetLight(
0, // 지정할 광원 리스트 내의 요소, 범위는 0~최대 광원
&light // 설정하려는 D3DLIGHT9 구조체의 주소
)
Device->LightEnavble(
0, // 활성,비활성화 하려는 광원 리스트 내의 요소
true // true = 활성, false = 비활성
);
D3D에서는 u = (1,0), v = (0,1) 축을 사용한다. 참고로 윈도우 좌표계랑 동일하게 위에서 v는 아래로 뻗으며, 텍스처 좌표공간이라고도 한다.
struct Vertex
{
float _x, _y, _z;
float _nx _ny, _nz;
flaot _u, _v; // 텍스처 좌표\
static const DWORD FVF;
};
const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
// D3DFVF_TEX1 : 버텍스 구조체에 한 쌍의 텍스처 좌표가 조함됨을 지정
이제 이 세 개의 버텍스로 만들어지는 삼각형들은 텍스처 좌표에서의 텍스처 삼각형으로도 정의된다.
텍스처 데이터 읽기
HRESULT D3DXCreateTextureFromFile(
LPDIRECT3DDEVICE9 pDevice, //텍스처를 만들어낼 장치
LPCSTR pSrcFile, // 이미지를 읽어들일 파일명
LPDIRECT3DTEXTURE9* ppTexture // 만들어진 텍스처를 받을 포인터
) // 읽혀진 이미지 파일은 IDirect3DTexture9 객체로 반환된다.
현재 텍스처를 지정하는 매서드
HRESULT IDirect3DDevice9::SetTexture(
DWORD Stage, // [0,7] 범위의 값으로 텍스처를 지정한다.
// stage - 이어지는 노트를 참고한다.
IDirect3DBaseTexture9* pTexture // 지정할 텍스처의 포인터
)
- 근접점(Nearset) 샘플링 : 디폴트 필터링 방식이며 가장 품질이 떨어진다(빠르다)
- 선형 필터링 : 비교적 높은 품질의 결과물을 만들어내며, 최근 하드웨어를 생각하면 실행도 빠른 편이다.(권장)
- 비등방성(Anisotropic) 필터링 : 가장 높은 품질 But 느림
//근접점 샘플링
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
Device->SetSamplerState(0, D3DSAMP_MINFILTERM, D3DTEXF_POINT);
//선형 필터링
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_Linear);
Device->SetSamplerState(0, D3DSAMP_MINFILTERM, D3DTEXF_Linear);
//비등방성 필터링
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC);
Device->SetSamplerState(0, D3DSAMP_MINFILTERM, D3DTEXF_ANISOTROPIC);
Device->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 4);
참고로 smapler 클래스는 텍스처 구성 정보라고 생각하면 됨. SetSamplerState 함수로 필터 정보를 바꾸는거
// 밉맵 필터 지정하기
Device->SetSamplerState(0, D3DSAMP_MIPFILTER, Filter);
Filter 매개변수
D3DTEXF_NONE : 밉맵을 이용하지 않는다.
D3DTEXF_POINT : 스크린 삼각형과 가장 비슷한 크기의 밉맵 레벨을 선택한다. 일단 레벨이 선택되면 지정된 min과 mag 태그에 따라 선택된 레벨을 필터링한다.
D3DTEXF_LINER : 가장 비슷한 두 개의 밉맵 레벨에 min과 mag 필터에 따른 필터링을 적용한다. -> 선형적으로 조합된 두 개의 레벨을 이용해 최종 픽셀 컬러를 계산해낸다.
D3D에서 밉맵 자동으로 해주는거라 대충 하면 된다.
wrap : 이미지를 넘어가면 이미지를 반복적으로 출력함.
border color : 지정된 좌표까지만 그리고 넘어가는 부분은 지정된 스크린 색으로 채워진다.(default 검정)
cloamp : 넘어가면 이미지 끝부분을 쭉 출력한다.
mirror : 이미지를 넘어가면 대칭으로 이미지를 출력한다.
//wrap 어드레스 모드
if(::GetAsyncKetState('W') & 0x8000f)
{
Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
}
// border color 모드
if(::GetAsyncKetState('B') & 0x8000f)
{
Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
Device->SetSamplerState(0, D3DSAMP_BORDERCOLOR, 0x000000ff); // 스크린 색
}
//clamp 모드
if(::GetAsyncKetState('W') & 0x8000f)
{
Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
}
//mirror 모드
if(::GetAsyncKetState('W') & 0x8000f)
{
Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
}
반드시! 블렌딩하지 않는 물체를 먼저 그려야 한다.
블렌딩하는 물체는 카메라 거리 기반 정렬을 해야 한다.
멀리 있는 물체부터 그린다. 왜냐면 버퍼 체크 하다가 뒤에 있는 물체를 못 그리게 되면 섞이지 않으니까.
outputPixel = SourcePixel SourceBlendFactor + DestPixel DestBlendFactor
Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
Device->SetRenderState(D3DRS_SRCBLEND, Source);
Device->SetRenderState(D3DRS_DESTBLEND, Destination);

RGBA에서 불투명도를 의미하는 A값으로 투명도를 조절한다. 범위는 [0,255]
0일때 투명, 255일때 불투명하다.
원본 블렌드 인수를 D3DBLEND_SRCALPHA, 목적지 인수를 D3DBLEND_INVSRCALPHA로 지정해야 한다.
텍스처의 알파 채널에서 알파 정보를 가져올 수도 있다. 각 픽셀마다 들어있는거 꺼내서 쓴다는 말임.
디폴트로, 현재 텍스처가 알파 채널을 가지고 있는 경우 알파 채널에서 알파를 가져오고, 없다면 버텍스 컬러에서 알파를 얻는다.
//셰이드 과정에서 난반사 컬러로 알파를 계산한다.
Device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
//알파 채널에서 알파를 얻는다.
Device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
스텐실 버퍼 : 특수한 효과를 위한 오프 스크린 버퍼
일부 영역의 렌더링을 막을 수 있다.
Device->SetRenderState(D3DRS_STENCILENABLE, true)
false 로 설정하면 비활성화된다.
스텐실 버퍼를 디폴트 값으로 되돌리기 -> iDirect3DDevice9::Clear
Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL,
0xff000000,
1.0f,
0);// 스텐실 버퍼를 소거하는데 이용될 값을 지정
- D3DFMT_D24S8 - 32비트 깊이/스텐실 버퍼를 만들고 깊이 버퍼에는 픽셀 당 24비트를. 스텐실 버퍼에는 픽셀 당 8비트를 할당한다.
- D3DFMT_D24X4S4 - 32비트 깊이/스텐실 버퍼를 만들고 깊이 버퍼에는 픽셀 당 24비트를. 스텐실 버퍼에는 픽셀 당 4비트를 할당한다, 나머지 4비트는 안쓴다.
- D3DFMT_D15S1 - 16비트 깊이/스텐실 버퍼를 만들고 깊이 버퍼에는 픽셀 당 15비트를. 스텐실 버퍼에는 픽셀 당 1비트를 할당한다.
결국 true면 후면 버퍼의 픽셀을 출력, false면 출력하지 않는다. + 깊이 버퍼에도 안 기록된다.
Device->SetRenderState(D3DRS_STENCILREF, 0x1); //16진수가 비트연산에 좋다.
스텐실 마스크 바꾸기
Device->SetRenderState(D3DRS_STENCILMASK, 0x0000ffff);
스텐실 값 수정 -> 이건 불가능하다.
비교연산자 지정
D3DRS_STENCILFUNC : 랜더 상태를 이용해서 비교 연산자를 지정할 수 있으며, 다음 열거형의 맴버를 선택해서 사용한다.
//LHS는 좌측 비교연산자, RHS는 우측 비교연산자를 의미함
typedef enum _D3DCMPJUNC
{
D3DCMP_NEVER = 1, //스텐실 테스트가 항상 실패
D3DCMP_LESS, // LHS<RHS 일 경우 스텐실 테스트가 성공
D3DCMP_EQUAL, // LHS == RHS 일 경우 스텐실 테스트가 성공한다.
D3DCMP_LESSEQUAL, // LHS <= RHS일 경우 스텐실 테스트가 성공한다.
D3DCMP_GREATER, // LHS > RHS일 경우 스텐실 테스트가 성공한다.
D3DCMP_NOTEQUAL, // LHS != RHS 일 경우 스텐실 테스트가 성공한다.
D3DCMP_GREATEREQUAL, //LHS >= RHS 일 경우 스텐실 테스트가 성공한다.
D3DCMP_ALWAYS, // 테스트가 항상 성공
D3DCMP_FORCE_DWORD = 0x7fffffff
} D3DCMPFUNC;
ㄹㅇ 먼소린지 모르겠음 ㅋㅋ;
Device->SetRenderState(D3Drs_StenCILWRITEMASK, 0x0000ffff);
D3DX 는 ID3DXFONT 인터페이스를 제공한다.
HRESULT D3DXVreateFontIndirect
{
LPDIRECT3DDEVICE9 pDevice, //글꼴과 연결된 장치
CONST LOGFONT* pLogFont, //글꼴을 나타내는 LOGFONT 구조체
LPD3DXFONT* ppFont //만들어진 글꼴을 리턴
}
//LOGFONT에 글씨의 굵기 등 글꼴에 대한 정보가 들어있어서 그거 설정한뒤 적용하면 된다.
INT ID3DXFONT::DrawText
(
LPCSTR pString, //그리고자 하는 문자열
INT Count, // 문자열 내에 포함된 문자의 수, 문자열이 null로 끝나는 경우 -1 을 지정할 수 있다.
LPRECT pRect, // 텍스트가 그려질 화면 상의 영역을 정의하는 RECT 구조체를 가리키는 포인터
DWORD Format, // 텍스트 포맷을 지정하는 플래그
D3DCOLOR Color // 텍스트 컬러
);
CD3Font(
const TCHAR* strFontName, // 글꼴의 이름을 지정하는 null로 끝나는 문자열
DWORD dwheight, // 글꼴의 높이
DWORD dwFlogs=0L); // 선택적 생성 플래그들 : ㅋㅋ0말고 넣긴 할거임?
Font = new CD3DFOnt("Times New Roman", 16, 0); // 인스턴스화
Font->InitDeviceObjects(Device);
Font->RestoreDeviceObjects();
HRESULT CD3DFont::DrawText(
FLOAT x, //텍스트 그리기를 시작할 화면의 x축 좌표
FLOAT y, //텍스트 그리기를 시작활 화면의 y축 좌표
DWORD dwColot, //텍스트의 색
Const TCHAR* strText, //그리고자 하는 문자열의 포인터
DWORD dwFlags=0L) //선택적 렌더링 플래그들
/*플래그 인자에는 0을 지정하거나
D3DFONT_CENTERED, D3DFONT_TWOSIDED, D3DFONT_FILTERED 플래그들의 조합을 지정할 수 있다.*/
D3DFont 객체를 삭제하기 전에 약간의 정리 루틴을 호출해야 한다.
Font->InvalidateDeviceObjects();
Font->DeleteDeviceObjects();
delete Font;
HRESULT D3DXCreateText(
LPDIRECT3DDEVICE9 pDevice, //메쉬와 연결될 장치
HDC hDC, // 메쉬를 생성하는데 이용될 글꼴 정보를 포함하는 장치 컨텍스트로의 핸들
LPCTSTR pText, //메쉬로 만들 텍스트를 포함하는 null로 끝나는 문자열
FLOAT Deviation, // true타입 글골 외곽선에서의 최대 편차.
FLOAT Extrusion, // -z축 방향으로 잰 글꼴의 깊이
LPD3DXMESH* ppMesh, //만들어진 메쉬 리턴
LPD3DXBUFFER* ppAdjacency, // 만들어진 메쉬의 근접 정보를 리턴한다. (필요없으면 null)
LPGLYPHMETRICSFLOAT PGlyphmetrics /* 장식 거리 데이터를 포함하는
LPGLYPHMETRICSFLOAT 구조체 배열의 포인터, 장식 거리 데이터가 상관 없으면 0
)
Deviation값은 0 이상이어야 되며, 0일때 편차는 원본 글꼴의 한 디자인 단위와 같아진다.
ID3DXMesh 인터페이스는 기능의 상당 부분을 부모인 ID3DXBaseMesh에서 상속받는다. 중요한 사실인데 ID3DXPMesh와 같은 다른 인터페이스들도 ID3DXBaseMesh에서 상속받기 때문.
// 버텍스 버퍼의 포인터 얻어오기
HRESULT ID3DXMesh::GetVertexBuffer(LPDIRECT3DVERTEXBUFFER9* ppVB);
// 인덱스 버퍼 포인터 얻어오기
HRESULT ID3DXMesh::GetIndexBuffer(LPDIRECT3DVERTEXBUFFER9* ppVB);
ID3DXMesh 인터페이스는 순수한 정보를 제공하기 위한 목적으로 기본형 타입의 인덱스화된 삼각형 리스트를 지원한다.
//lock 함수들
HRESULT ID3DXMesh::LockVertexBuffer(DWORD Flags, BYTE** ppData);
HRESULT ID3DXMesh::LockIndexBuffer(DWORD Flags, BYTE** ppData);
//unlock 함수들
HRESULT ID3DXMesh::UnlockVertexBuffer();
HRESULT ID3DXMesh::UnlockIndexBuffer();
기하 관련 정보를 얻을 수 있는 ID3DXMesh 매서드들
DWORD GetFVF(); // 버텍스의 버텍스 포맷을 나타내는 DWORD를 리턴한다.
DWORD GetNumVertices(); // 버텍스 버퍼 내의 버텍스의 수를 리턴한다.
DWORD GerNumBytesPerVertex(); // 버텍스 당 바이트의 수를 리턴한다.
DWORD GetNumFaces(); // 메쉬 내의 면(삼각형)의 수를 리턴한다.
ID3DXMesh 인터페이스는 AttribId 인자로 지정한 특정 서브셋의 삼각형을 그리는 DrawSubset(DWORD AttribId) 메서드를 제공한다.
Mesh->DrawSubset(0);
for(int i = 0; i < numSubsets; i++)
{
Device->SetMaterial(mtrls[i]);
Device->SetTexture(0, textures[i]);
Mesh->DrawSubset(i);
}
메쉬 최적화 : 효과적인 렌더링을 위해 버텍스와 인덱스를 재구성하는 것-
HRESULT ID3DXMesh::OptimizeInplace
(
DWORD Flags, // 수행할 최적화의 종류 플래그
COnst DWORD* pAdjacencyIn, //최적화되지 않은 메쉬의 인접 배열로의 포인터
DWORD* pAdjacencyOut,
DWORD* pFaceRemap,
LPD3DXBUFFER* ppVertexRemap
);
비슷한 메서드로 Optimize가 있다. 얜 매게변수인 메쉬 객체를 최적화해주는게 아니라 최적화된걸 리턴한다.
HRESULT ID3DXMesh::Optimize
(
DWORD Flags,
CONST DWORD* pAdjacencyIn,
DWORD* pAdjacenecyOut,
DWORD* pFaceRemap,
LPD3DXBUFFER* ppVertexRemapm,
LPD3DXMESH* ppOptMesh // 최적화된 메쉬
);
D3DXMESHOPT_ATTSORT 플래그를 설정하여 메쉬를 초기활화하면 메쉬의 기하정보가 그 속성에 따라 정렬되므로, 버텍스/인덱스 버퍼 내에 있는 특정 부분의 기하정보가 연속된 블록에 위치하게 된다.