Shader 21.12.03

김주현·2021년 12월 3일

셰이더

목록 보기
8/18

하이어라키 로더

CreateFrame이 뼈의 갯수만큼 출력되고

CreateMeshConstainer가 호출됨

CreateFrame에서 메시를 구성하는 뼈대정보를 로드한다.
(로드는 DirectX가하고 나는 정리를한다)

D3DXFrame_Derived의 CombinedTransfromationMatrix
부모뼈대의 컴바인드(기준을 부모로 바꿔준다고 생각하자) * TransformationMatrix(부모를 기준으로 나를 표시)

D3DXFRAME이 값들은 알아서 채워준다.(Name값은 전해줘야한다.)
내가만든 변수는 안채워준다.

D3DXFRAME

-D3DXMESHCOTAINER 메쉬와 크게 다르지않음
메쉬들이 여러개가 모여서 애니메이션 메쉬가된다.

애니메이션메쉬를 로드하게되면 여러개의 메쉬컨테이너를 로더해서 하나의 메쉬를 이루고.
첫번째 메쉬컨터이너는 사람의 몸전체를 표현하는경우가많다

뼈가 메쉬를 가지고있는 식으로 표현된다.
->기본적으로 뼈가있는 메쉬는 움직임이 있다고 볼수있다.

첫번째 뼈대에만 메쉬컨테이너를 담아준다.

시블링과 차일드는 자식과 형제 뼈대를 의미한다.

CreateFrmae에선 아직 컴바인드행렬을 채워줄수없다(아직 모든 뼈의 값이 채워지지않았기 때문)

CreateFrmae 함수의 ppNewFrame은 아웃풋값은 넣어준다.

뼈의 이름을 채워보자

memcpy로 해주기엔 이름이없는애들이 있을수있다.
(루트프레임은 차일드값만을 가진다->이름이없다)

Name이 nullptr이 아닐때를 검사해주자.
(이름을 넣어주는 부분은 추후에 사용한다. 함수로 빼주자)

Allocate_Name(const char* pSourName, char** ppDestName);
ex )Allocate_Name(Name,&pFrame->Name)
:인자로 받은 네임을 프레임에 넣어주자.

{
1. pSourName 의 길이를 strlen으로 재고 +1(널문자) 해서
동적할당해주자.
2. strcpy()로 문자열을 복사해서 넣어주자.
}

이름을 채워줬다면 pFrame의 행렬들을 항등행렬로 만들어주자.
D3DXMatrixIdentity();

CombinedTransfromationMatrix의 값을 채워보자.

Update_CombinedTransfromationMatries(LPD3DXFrame pFrame, _matrix ParentCTM)함수를 만들어주자

모든 Frame의 CombinedTransfromationMatrix값을 채워주는 함수이다.

D3DLoadMeshHierarchyFromx()의 마지막 인자는 애니메이션 컨트롤러이다. 이는 모든뼈의 트랜스폼을 갱신해준다. 이때 실제 뼈를 그려주는것은 컴바인으로 그려야하고 ->결국뼈는 정점들에게 값을 전달해주기위한 역할이니 이때 컴바인을 넘겨줘야한다.

즉 매프레임마다 각 프레임의 트랜스폼행렬로 컴바인 행렬을 갱신해줘야한다(느리지만 필수이다)

루트프레임을 가지고있으니 모든 뼈들을 호출하기위해 재귀함수의 형태를 가진다.

인자로 뼈를 받는다.(네컨_프로토에서 인자로 루트프레임을 전달한다)
{
1.컴바인 행렬에 접근하기위해 pFrame을 D3DXFRAME_DERIVED로 캐스팅하자
2.컴바인매트릭스 에 인자로 받은 컴바인매트릭스와 자신의 트랜스폼매트릭스를 곱해서 넣어주자.
3.만약 자식값이 있다면(자식,내 컴바인)을 호출해주고
만약 형제값이 있다면 (형제,부모의 컴바인)을 호출해주자.

}

초기행렬값을 항등으로줘도 되지만 각도나 스케일을 조정해주고 싶으면 그 행렬을 넣어주면 모든 뼈에 이값이 적용된다.

D3DXMeshContainer

D3DXMESHDATA : 공용체로 구현되어있다 원하는 타입으로 쓰면된다
LPD3DXMATERIAL : 스태틱메시에선 버퍼였는데 그냥 머테리얼로되어있다. 포인터형식이다.
pEffect : 사용하지않는다
NumMaterials,pAjacenct : 스태틱메쉬와 똑같다.

LPD3DXMATERIAL로 텍스처를 로드해서 텍스처형대로 저장했다.

D3DXMeshContainerDerived안에 pMaterials을 동적배열로 할당하자.

CreateMeshContainer()

pMeshContainer를 동적할당해주고

1.미리만들어둔 이름 할당함수 allocate_Name함수를 호출해주자.
2.Mesh를 복제해서 넣어주자.
{
//현재 메시를 구성하고있는 정점의 멤버를 표현한 배열
//배열하나가 정점멤버하나
//정점메버가 세개라면 배열도 세개선언
D3DVERTEXELEMENT9이 필요하다.
//정점이라면 위치,노멀,텍스처uv가 있을것이다.
//내가 정리한형태로 복제한 메쉬를 만들어주겠다.

{
{스트림,오프셋,타입,메소드,usage,usage인덱스} // 정점을구성하는 멤버변수중 하나의 정보를 기입.
스트림 : 몇번째 버텍스인지.
오프셋 : 실제 정점구조체의 몇바이 뒤에 위치하는지
ex) 위치는 맨앞이니 0 노말은 앞에서 위치벡터(float*3)가있으니 12바이트뒤에있다.
타입 : 해당 벡터가 어떤 타입을 가지고있는지
메소드는 : 디폴트
용도 : 위치를 표현하는거야라고 명시
용도인덱스 : 용도가 여러개사용될떄 (텍스처,컬러) 이를 증가시켜서 전달하자

버텍스버퍼를 두개사용할때 스트림으로 명시해준다.
여기서 정의한 정보들이 바로 셰이더로 전달된다.

D3DCEL_END()로 끝을 알려줘야한다.

복사한 메쉬가 가졌으면 하는 데이터를 직접정의한것이다.
}

CloneMeshfvf cloneMesh이 더 디테일하게 변수를 추가해줄수있다.
ex)TANGECT는 FVF형식에없지만 USAGE에는 있다.

pMeshData->pMesh->CloneMesh()로 메시를 복제한다.
(겟옵션,엘리먼트,장치,메시컨테이너->메시데이타.메시
}

만약에 원본메시에 노말이없더라고 상관없다(데이터는 안채우고 공간만 잡아준다.)

Getdeclartion으로 가지고있는지 등의 정보를 알수있다.

D3DXComputeNormals() ->메시에 노말을 담을수있는 공간만 할당해놓으면 메시를 인자로 전달하면 노말을 알아서 계산해준다.

0개의 댓글