DirectX 에서는 벡터를 변환하는 함수인


1
2
3
4
5
D3DXVECTOR3* WINAPI D3DXVec3TransformCoord
    ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM );
 
D3DXVECTOR3* WINAPI D3DXVec3TransformNormal
    ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM );
cs

함수가 있다.


일단 이 두함수의 공통점은 2번째 인자인 벡터와 3번째 인자인 행렬을 곱하는 함수라는 것이다.


우선 3차원 벡터와 4x4 행렬은 곱해질 수 없다 왜냐하면 행렬을 곱할때는 앞 행렬의 열과 뒤 행렬의

행이 같아야지만 곱할 수 있다


그래서 이 함수는 3차원 벡터를 4차원 벡터로 변환하여 행렬과 곱해주는데 여기서 차이점이 발생한다


3차원 벡터 가 있다면


이 3차원 벡터를


D3DXVec3TransformCoord 함수는 

로 바꿔주고


D3DXVec3TranformNormal 함수는

로 바꿔준다.


둘의 차이는 4차원 벡터의 4번째 요소  가 다르다는 점인데 


 이라면 포인터(좌표) 개념이 되어 이동이 적용되고

 이라면 벡터의(방향) 개념이 되어 이동이 적용되지 않는다


이유는 


DirectX 의 4x4 행렬의 마지막 열은 이동을 담당하는것을 알고 있다면 이해하기 쉽다


------------------------------------------------------------ 

이 식에서 


이라면

  이므로 이동이 적용되는걸 알 수 있다.


 이라면 

      이므로 이동이 적용 안되는 걸 알 수 있다.


-------------------------------------------------------------

그러므로


 벡터와 행렬을 곱하여 


 이동, 회전, 스케일, 을 변환하고 싶다면 D3DXVec3TransformCoord를 쓰고

 이동은 변환하고싶지 않고 회전,스케일만 변환하고 싶다면 D3DXVec3TransformNormal을 쓰면된다








'programing > directX' 카테고리의 다른 글

LPD3DXMESH 쓰는법  (0) 2018.10.13
LPD3DXFONT  (0) 2018.02.13

전체소스코드는 맨 아래있습니다.


DirectX 3D를 공부하던 중 Obj 모델링을 로드하고 그 정보를 저장하기 위해 LPD3DXMESH를 사용했다


LPD3DXMESH를 사용하기 위해 해야할 것들은...


1. LPD3DXMESH 초기화 해주기


D3DXCreateMeshFVF(

삼각형의 갯수,

정점의 갯수,

D3DXMESH_MANAGED,

FVF 포멧,

device,

LPD3DXMESH의 포인터);     위 함수를 이용하여 메쉬를 초기화 한다.


2. VertexBuffer 초기화 하기

일단 정점들을 저장한 배열이나 STL::Vector에 저장한다.

vector<CustomVertex> vVertexs;


버퍼 포인터를 받을 void 포인터 변수를 선언한다.

void * Vertices = nullptr;


락을 걸어준다.

lpD3DXMesh->LockVertexBuffer(0, Vertices);


그리고 배열이나 STL::Vector의 저장된 정점들을 복사해준다.

memcpy(Vertices, &vVertexs[0], sizeof(CustomVertex) * vVertexs.size());


락을 풀어준다.

lpD3DXMesh->UnlockVertexBuffer();


2. IndexBuffer 초기화 하기.

초기화할 인덱스 정보를 배열이나 STL:Vector에 저장한다.

vector<WORD> vIndexs;


버퍼 포인터를 받을 void 포인터 변수를 선언한다

void * Indices = nullptr;


락을 걸어준다.

lpD3DXMesh->LockIndexBuffer(0, &Indices))


그리고 배열이나 STL::Vector의 저장된 정점들을 복사해준다

memcpy(Indices, &vIndexs[0], sizeof(WORD) * vIndexs.size());


락을 풀어준다.

lpD3DXMesh->UnlockIndexBuffer();


2. AttributeBuffer 초기화 하기.

초기화할 속성 정보를 배열이나 STL:Vector에 저장한다.

vector<DWORD> vAttribute;


버퍼 포인터를 받을 DWRD 포인터 변수를 선언한다

DWRD * Attribute= nullptr;


락을 걸어준다.

lpD3DXMesh->LockAttributeBuffer(0, &dwAttribute))


그리고 배열이나 STL::Vector의 저장된 정점들을 복사해준다

memcpy(dwAttribute, &vAttribute[0], sizeof(DWORD) * vAttribute.size());


락을 풀어준다.

    lpD3DXMesh->UnlockAttributeBuffer();



이렇게 설정해주고 그릴때 lpD3DXMesh->DrawSubset(SubsetNum); 이렇게 그려주면 메쉬가 그려진다.


전체 소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
bool cMeshRenderer::CreateMesh()
{
    if (FAILED(D3DXCreateMeshFVF(
        vVertexs.size() / 3
        vVertexs.size(), 
        D3DXMESH_MANAGED, 
        CustomFVF, 
        g_device, 
        &lpD3DXMesh)))
    {
        MessageBox(nullptr, L"Failed CreateMesh ", L"Error", MB_OK);
        return false;
    }
 
    void * Vertices = nullptr;
 
    if (FAILED(lpD3DXMesh->LockVertexBuffer(0&Vertices)))
    {
        MessageBox(nullptr, L"Failed Mesh->LockVertexBuffer", L"Error", MB_OK);
        return false;
    }
    
    memcpy(Vertices, &vVertexs[0], sizeof(CustomVertex) * vVertexs.size());
 
    lpD3DXMesh->UnlockVertexBuffer();
 
    void * Indices = nullptr;
 
    if (FAILED(lpD3DXMesh->LockIndexBuffer(0&Indices)))
    {
        MessageBox(nullptr, L"Failed Mesh->LockIndexBuffer", L"Error", MB_OK);
        return false;
    }
    
    memcpy(Indices, &vIndexs[0], sizeof(WORD) * vIndexs.size());
 
    lpD3DXMesh->UnlockIndexBuffer();
 
    DWORD * dwAttribute = nullptr;
 
    if (FAILED(lpD3DXMesh->LockAttributeBuffer(0&dwAttribute)))
    {
        MessageBox(nullptr, L"FAiled Mesh->LockAttributeBuffer", L"Error", MB_OK);
        return false;
    }
 
    memcpy(dwAttribute, &vAttribute[0], sizeof(DWORD) * vAttribute.size());
 
    lpD3DXMesh->UnlockAttributeBuffer();
 
    return true;
}
 
cs



틀린 것이나 조언할것이 있다면 댓글로 해주세요 감사합니다

'programing > directX' 카테고리의 다른 글

DirectX D3DXVec3TransformCoord와 D3DXVec3TransformNormal 함수  (0) 2018.10.15
LPD3DXFONT  (0) 2018.02.13

directX 게임 프로그래밍을 공부하던 중 UI를 만들때 쓴 LPD3DXFONT이다.


사용법

1.  D3DXFONT_DEST 구조체를 초기화해준다 (LPD3DXFONT를 쓰기 위해 설정하는 구조체 같다.)

D3DXFONT_DESC dese =

{

50, 0

, FW_BOLD, 1, FALSE

, HANGUL_CHARSET

, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_DONTCARE

, TEXT("양재블럭체")

};

   

   

아는 것만 써본다.(D3DX에서 가져옴)

   

INT Height; // 글자 높이

   

 UINT Width; // 글자 폭

   

 UINT Weight; // 폰트의 굵기 (현재 설정된것은 FW_BOLD = 굵음)

FW_THIN                얇은

FW_NORMAL           보통

FW_SEMIBOLO        조금 굵게

FW_EXTRABOLO      많이 굵게


 UINT MipLevels;   

 BOOL Italic;

 BYTE CharSet;    

 BYTE OutputPrecision;

 BYTE Quality;

 BYTE PitchAndFamily;

 WCHAR FaceName[LF_FACESIZE]; // TEXT("양재블럭체) : 폰트설정.



2. LPD3DXFONT 를 만들어준다

D3DXCreateFontIndirect(g_Device, &dese, &m_Font2);

// 각각 디바이스 , 설정구조체 포인터, LPD3DXFONT 포인터


3. 화면에 쓴다

m_Font->DrawText(sprite, string, count, &drawPos, DT_NOCLIP, color);

// 각각 sprite객체 , 

출력할 문자열(LPTSTR), 

문자의 갯수(int), 

위치(RECT ->left : x , top : y 나머지는 0(DT_NOCLIP을 쓴다면) ) , 

출력 플레그(현재 플레그는 사각영역을 넘어가도 자르지 않는다. ),

글자색






'programing > directX' 카테고리의 다른 글

DirectX D3DXVec3TransformCoord와 D3DXVec3TransformNormal 함수  (0) 2018.10.15
LPD3DXMESH 쓰는법  (0) 2018.10.13

+ Recent posts