728x90

 

※ 제 개인 공부이므로 풀 소스 코드는 작성하지 않습니다.

※ 생략 되어 있는 부분이 많습니다.

 

 

struct VtxD
 {
      D3DXVECTOR3 p;
      DWORD d;

      VtxD() : p(0, 0, 0), d(0xFFFFFFFF) {}
      VtxD(FLOAT X, FLOAT Y, FLOAT Z, DWORD D) : p(X, Y, Z), d(D) {}

      enum { FVF = (D3DFVF_XYZ | D3DFVF_DIFFUSE), };
 };

 

LPDIRECT3DVERTEXSHADER9  m_pVs; 
LPDIRECT3DVERTEXDECLARATION9  m_pFVF; 

LPD3DXCONSTANTTABLE  m_pTbl;

VtxD  m_pVtx[4];

 

정점은 포지션과, 색상(Diffuse)를 갖고 잇고, 사각형을 만들꺼니까 정점 4개가 필요하다.

 

*shader.fx*

 

// Output Vertex Processing
struct SvsOut
{
    float4 Pos : POSITION; // oPos
    float4 Dif : COLOR0; // oD0
};


float4x4 m_mtWld;     // World * View * Projection Matrix
float4x4 m_mtViwPrj;     // View * Projection Matrix

 

SvsOut VtxPrc( float3 Pos: POSITION, float4 Dif: COLOR0 )
{
     float4 P;
     SvsOut Out = (SvsOut)0;    // Initialized to 0

 

     P  = float4(Pos,1);   // Expand into float4 and setting w=1
     P  = mul(P, m_mtWld);   // Transform World
     P  = mul(P, m_mtViwPrj);  // Transform View * Projection

 

     Out.Pos = P;      // Copy Output Position
     Out.Dif = Dif;      // Copy Output Diffuse

 

     return Out;
}

 

SvsOut 정점 구조체를 이용하여 출력 시켜주고 있다. 이전까지와의 다른 점이라면 정점의 위치가 될 float4형 p 변수에 월드행렬(m_mtWld), 뷰*투영행렬(m_mtViwPrj)을 mul함수를 사용하여 곱해줌으로써 정점을 변환하고 있다.

 

입력으로 받는 정점의 포지션은 float3 형 이지만 파이프라인은 float4형을 사용하기 때문에 float4형으로 만들어주고 마지막 인수인 w에 1을 입력해 준다.

 

m_pVtx[0] = VtxD(-50, 0, 0, D3DXCOLOR(1, 0, 0, 1));
m_pVtx[1] = VtxD(50, 0, 0, D3DXCOLOR(0, 1, 0, 1));
m_pVtx[2] = VtxD(50, 80, 0, D3DXCOLOR(0, 0, 1, 1));

m_pVtx[3] = VtxD(-50, 80, 0, D3DXCOLOR(1, 0, 1, 1));

 

m_pdev->SetRenderState(D3DRS_LIGHTING, FALSE);
m_pdev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

 

D3DXMATRIX  mtWld;   // World Matrix
D3DXMATRIX  mtViw;   // View Matrix
D3DXMATRIX  mtPrj;   // Projection Matrix

 

float fAngle = D3DXToRadian(GetTickCount()*0.1f);
D3DXMatrixRotationY(&mtWld, fAngle);
mtWld._43 -= 1.f;

 

m_pdev->GetTransform(D3DTS_VIEW, &mtViw);    // Device에서 뷰 행렬을 가져온다.
m_pdev->GetTransform(D3DTS_PROJECTION, &mtPrj);   // Device에서 투영 행렬을 가져온다.

 

m_pdev->SetVertexShader(m_pVs);
m_pdev->SetVertexDeclaration(m_pFVF);

 

// 전역 변수 값 설정: 상수 테이블 사용
m_pTbl->SetMatrix(m_pdev, "m_mtWld", &mtWld);    // World Matrix
m_pTbl->SetMatrix(m_pdev, "m_mtViwPrj", &(mtViw * mtPrj)); // View * Projection Matrix

 

m_pdev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, m_pVtx, sizeof(VtxD));

 

m_pdev->SetVertexShader(NULL);
m_pdev->SetVertexDeclaration(NULL);

 

D3DRS_CULLMODE 모드를 NONE으로 해주면 컬링을 하지 않아 앞면 뒷면 다 보이게 된다. 우린 사각형을 Y축을 기준으로 계속해서 돌릴꺼니까 양면이 보여야 되니까.

 

GetTransform() 를 이용해서 각각의 행렬을 가져오고, SetMatrix()을 이용하여 셰이더 파일의 m_mtWld와, m_mtViwprj에 접근하여 값을 설정해준다.

 

D3DXToRadian(GetTickCount()*0.1f)을 이용해서 움직일 각도를 계산하고 D3DXMatrixRotationY() 을 이용해서 월드행렬에 적용해줌으로써 계속해서 Y각도가 바뀌는 사각형이 랜더링 되는 것이다.

 

mtWld._43 -= 1.f; 이 부분은 딱히 쓰이는 부분은 없는거 같은데. 월드 행렬의 _43이라고 하면 z축을 나타내는것으로 z축에 -1만큼 움직여라 라고 보면 된다.

 

마지막으로 월드 행렬(m_mtWld)와, 뷰*투영 행렬(m_mtViwPrj)를 따로 사용할 필요없이 셋다 곱해서 하나의 행렬로 사용해도 된다.

 

여기서는 월드행렬에 계속해서 로테이션Y를 해주기 위해서 따로 사용한거 같다. 셰이더 파일에도 보면 그렇기 때문에 float4x4형을 2개 만들어 각각 월드, 뷰*투영 행렬로 사용하고 있는듯 하다.

 

뭐 결론은.. 특별히 처리할 내용이 없는 부분이라면 미리 행렬들을 곱해서 사용하면 된다는것.

728x90
Posted by 정망스
,


맨 위로
홈으로 ▲위로 ▼아래로 ♥댓글쓰기 새로고침