728x90

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

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

struct VtxD
 {
   D3DXVECTOR3 p;
   DWORD d;

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

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


 LPDIRECT3DVERTEXSHADER9  m_pVs;    // Vertex Shader
 LPDIRECT3DVERTEXDECLARATION9  m_pFVF;    // Declarator
 LPD3DXCONSTANTTABLE  m_pTbl;

 

 D3DXMATRIX  m_mtWld;   // World Matrix

 

 INT   m_iNvx;    // Vertex Number
 VtxD*  m_pVtx;    // Vertex Buffer

 

정점들의 포지션 p와, 색상값 d로 구성된 정점 구조체, m_iNvx는 구를 형성하는 정점의 갯수이다.

 

*shader.fx*

 

float4x4 m_mtWorld; // World Matrix
float4x4 m_mtView; // View Matrix
float4x4 m_mtProj; // Projection Matrix

 

float4 m_FogColor; // Fog 색상
float m_FogEnd; // Fog 끝 값
float m_FogBgn; // Fog 시작 값

 

// For Vertex Processing Output
struct SvsIn
{
  float3 Pos : POSITION ; // dcl_position0
  float4 Dif : COLOR0  ; // dcl_color0
};

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


SvsOut VtxPrc( SvsIn In)
{
  float4 vcOut;
  float FogFactor;

  SvsOut Out = (SvsOut)0;    // Initialized to 0

 

  // 정점의 변환: 월드, 뷰
  vcOut = float4(In.Pos, 1);
  vcOut = mul(vcOut, m_mtWorld);
  vcOut = mul(vcOut, m_mtView);

 

  // 정점의 뷰 변환 과정의 z/(Fog 끝 값 - Fog 시작 값)을 Fog Factor로 저장
  FogFactor = vcOut.z/(m_FogEnd - m_FogBgn);

 

  // 정점의 정규 변환
  vcOut = mul(vcOut, m_mtProj);

 

  // 출력 Diffuse를 정점 Diffuse와 포그 색상과 혼합
  float4 Fog = m_FogColor * FogFactor + In.Dif * (1.0 - FogFactor);

 

  // 혼합 값을 출력 색상으로 지정
  Out.Dif = Fog;
  Out.Pos = vcOut;


  return Out;
}

안개 효과를 나타내는데 있어 여러 방법이 있는듯 하다 그중에서 대표적으로는,

선형 포그(Linear Fog), 지수 포그(Exponential Fog)로 분류 된다.

선형 포그는 전체적으로 선형적으로 변화하고, exp 포그는 급격히 변화하다가 천천히, exp2는 천천히 변화하다가 급격히 변화 하는 것을 볼수 있다.

 

선형 포그와, 지수 포그 계산법엔 각각의 공식이 있고, 필요한 값들 또한 조금씩은 다른것 같다.

 

선형 포그는 포그가 적용되는 시작거리(start), 종료되는 종료거리(end)가 필요하고,

지수 포그는 포그의 밀도를 나타내는 (Density (0 ~ 1.0)) 필요하다.

 

기본적으로 포그는 물체가 멀리 있으면 포그의 색상에 가까워야 하고, 가까울수록 물체의 색상에 가까워야 된다는 개념 하에 FogFactor 라고 하는 거리에 정도에 따라 계산되는 값인 포그 계수를 이용하여 계산 하는듯 하다.

 

현재 셰이더 파일에서 사용하고 있는 방법은 선형 포그이고 빨간색으로 된 부분이 선형 포그 계산 공식 부분이다.

 

지수 포그(exp, exp2) 공식은 다음과 같다.

 

Fog Factor EXP = 1/exp(뷰 변환 후 정점의 z  * Fog Density)

Fog Factor EXP2 = 1/exp( pow(뷰 변환 후 정점의 z  * Fog Density, 2)

 

이러한 과정을 통해 fog값을 구하게 되면 출력 Diffuse에 이 값을 설정해주어 안개 효과가 나타나도록 한다는 것이다.

 

Render()

 

HRESULT hr = 0;
 
m_pdev->SetRenderState(D3DRS_LIGHTING, FALSE);


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

 

D3DXCOLOR FogColor(1.0F, 1.0F, 0.2F, 1); // Fog Color
FLOAT  FogEnd = 120.f; // Fog End
FLOAT  FogBgn = 0.f;  // Fog Begin

 

m_pdev->GetTransform(D3DTS_VIEW, &mtViw);
m_pdev->GetTransform(D3DTS_PROJECTION, &mtPrj);
 
// Render
m_pdev->SetVertexShader(m_pVs);
m_pdev->SetVertexDeclaration(m_pFVF);

 

hr = m_pTbl->SetMatrix(m_pdev, "m_mtWorld", &m_mtWld);
hr = m_pTbl->SetMatrix(m_pdev, "m_mtView", &mtViw);
hr = m_pTbl->SetMatrix(m_pdev, "m_mtProj", &mtPrj);
hr = m_pTbl->SetVector(m_pdev, "m_FogColor", (D3DXVECTOR4*)&FogColor);
hr = m_pTbl->SetFloat(m_pdev, "m_FogEnd", FogEnd);
hr = m_pTbl->SetFloat(m_pdev, "m_FogBgn", FogBgn);

 

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

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

 

지금 이 코드에서는 정점의 diffuse 값에 안개 효과를 적용하고 있기 때문에 나중에 텍스처가 적용되면 안개가 재대로 표현되지 못한다. 그래서 안개 표현은 픽셀 셰이더에서 처리하는 것이 좋다고 한다.


728x90
Posted by 정망스
,
728x90

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

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

struct VtxDUV1
 {
   D3DXVECTOR3 p;
   DWORD d;
   FLOAT u, v;

   VtxDUV1() : p(0, 0, 0), d(0xFFFFFFFF) {}
   VtxDUV1(FLOAT X, FLOAT Y, FLOAT Z,
   FLOAT U, FLOAT V, DWORD D = 0xFFFFFFFF) : p(X, Y, Z), u(U), v(V), d(D) {}

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

 

LPDIRECT3DVERTEXSHADER9  m_pVs;    // Vertex Shader
LPDIRECT3DVERTEXDECLARATION9  m_pFVF;    // Declarator
LPD3DXCONSTANTTABLE  m_pTbl;

 

VtxDUV1  m_pVtx[4];   // Vertex Buffer
LPDIRECT3DTEXTURE9  m_pTx0;

 

이번에는 텍스처가 추가 되면서, u,v좌표를 나타낼 float u,v와, FVF의 D3DFVF_TEX1, 그리고 텍스처 데이터가 저장될 LPDIRECT3DTEXTURE9 형의 m_pTbl이 추가 되었다.

 

*shader.fx*

 

float4x4 m_mtWVP;    // World * View * Projection Matrix


// For Vertex Processing Output
struct SvsOut
{
  float4 Pos : POSITION ; // oPos
  float4 Dif : COLOR0  ; // oD0
  float2 Tx0 : TEXCOORD0 ; // oT0
};


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

 

  Out.Pos = mul(float4(Pos, 1), m_mtWVP); // Transform
  Out.Dif = Dif;


  Out.Tx0 = Tx0;

  return Out;
}

 

텍스처를 나타내는 TEXCOORDO0이 추가 되었다. 그 외에는 이전 내용들과 같다.

 

m_pVtx[0] = VtxDUV1(-0.95F, 0.95F, 0, 0, 0, D3DXCOLOR(1, 0, 1, 1)); //색깔
m_pVtx[1] = VtxDUV1(0.95F, 0.95F, 0, 1, 0, D3DXCOLOR(1, 1, 0, 1));  //색깔
m_pVtx[2] = VtxDUV1(0.95F, -0.95F, 0, 1, 1, D3DXCOLOR(0, 1, 1, 1)); //색깔
m_pVtx[3] = VtxDUV1(-0.95F, -0.95F, 0, 0, 1, D3DXCOLOR(1, 1, 1, 1)); //색깔(하얀색)

 

D3DXCreateTextureFromFile(m_pdev, "Texture/earth.bmp", &m_pTx0);

 

D3DXCreateTextureFromFile 함수를 사용해서 텍스처 이미지를 읽어온다.

현재 작성대로의 정점들의 색깔로 지정하고 텍스처와 함께 랜더링 하면 왼쪽

정점들의 색깔을 모두 하얀색으로 하면 오른쪽과 같이 나온다.

 

Render()

 

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

 

D3DXMatrixIdentity(&mtWld);

 

m_pdev->GetTransform(D3DTS_VIEW, &mtViw);
m_pdev->GetTransform(D3DTS_PROJECTION, &mtPrj);

 

m_pdev->SetRenderState(D3DRS_LIGHTING, FALSE);

 

m_pdev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
m_pdev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
m_pdev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

 

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

 

// Setup Constant Register
D3DXMATRIX mtWVP = mtWld * mtViw * mtPrj;
m_pTbl->SetMatrix(m_pdev, "m_mtWVP", &mtWVP);

 

m_pdev->SetTexture(0, m_pTx0);
m_pdev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, m_pVtx, sizeof(VtxDUV1));

 

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

 

텍스처를 사용하기때문에. SetSamplerState 함수를 통해 필터링 보간을 해준다. 여기선 종류를 보여주기 위해 3개를 다 작성한것 같다. 이후엔 똑같이 변환 과정과, SetTexture 함수를 통해 텍스처를 적용하고 랜더링 한다.

728x90
Posted by 정망스
,
728x90

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

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

 

 

struct VtxIdx
 {
      WORD a, b, c;

      VtxIdx() : a(0), b(1), c(2) {}
      VtxIdx(WORD A, WORD B, WORD C) : a(A), b(B), c(C) {}
 };

 

 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;    // Vertex Shader
LPDIRECT3DVERTEXDECLARATION9  m_pFVF;    // Declarator

LPD3DXCONSTANTTABLE  m_pTbl;

D3DXMATRIX  m_mtWld;   // World Matrix

 

VtxIdx  m_pIdx[12];   // Index Buffer
VtxD  m_pVtx[24];   // Vertex Buffer

 

이번엔  m_pldx의 인덱스 버퍼와, 인덱스 구조체인 VtxIdx가 추가 되었다.

 

*shader.fx*

 

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


float4x4 m_mtWld;   // World Matrix
float4x4 m_mtViw;   // View Matrix
float4x4 m_mtPrj;   // Projection Matrix


SvsOut VtxPrc( float3 Pos : POSITION, float4 Dif: COLOR0 )
{
     float4 P;

     SvsOut Out = (SvsOut)0;    // Initialized to 0

 

     P = float4(Pos, 1);     // Expand intto float4 and Setting w=1
     P = mul(P, m_mtWld);    // Transform World
     P = mul(P, m_mtViw);    // Transform View
     P = mul(P, m_mtPrj);    // Transform Projection

 

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

 

     return Out;
}

 

입력받는 정점좌표와, 색상 데이터를 이용하여 출력 해주는 것은 여태까지와 똑같다 다만 추가 된것은 월드, 뷰, 투영 행렬을 mul 함수를 이용하여 각각 적용해주면서 변환 화는 과정을 보여주고 있다.

 

                             -----정점 데이터-----

// front
 m_pVtx[0] = VtxD(-1.f, -1.f, -1.f, D3DXCOLOR(1.0F, 0.0F, 0.0F, 1.0F));
 m_pVtx[1] = VtxD(-1.f, 1.f, -1.f, D3DXCOLOR(0.0F, 1.0F, 0.0F, 1.0F));
 m_pVtx[2] = VtxD(1.f, 1.f, -1.f, D3DXCOLOR(0.0F, 0.0F, 1.0F, 1.0F));
 m_pVtx[3] = VtxD(1.f, -1.f, -1.f, D3DXCOLOR(1.0F, 0.0F, 1.0F, 1.0F));

 

 // back
 m_pVtx[4] = VtxD(-1.f, -1.f, 1.f, D3DXCOLOR(1.0F, 1.0F, 0.0F, 1.0F));
 m_pVtx[5] = VtxD(1.f, -1.f, 1.f, D3DXCOLOR(0.0F, 1.0F, 1.0F, 1.0F));
 m_pVtx[6] = VtxD(1.f, 1.f, 1.f, D3DXCOLOR(1.0F, 0.0F, 0.0F, 1.0F));
 m_pVtx[7] = VtxD(-1.f, 1.f, 1.f, D3DXCOLOR(1.0F, 0.0F, 1.0F, 1.0F));

 

 // top
 m_pVtx[8] = VtxD(-1.f, 1.f, -1.f, D3DXCOLOR(0.0F, 0.0F, 1.0F, 1.0F));
 m_pVtx[9] = VtxD(-1.f, 1.f, 1.f, D3DXCOLOR(0.0F, 1.0F, 0.0F, 1.0F));
 m_pVtx[10] = VtxD(1.f, 1.f, 1.f, D3DXCOLOR(1.0F, 0.0F, 1.0F, 1.0F));
 m_pVtx[11] = VtxD(1.f, 1.f, -1.f, D3DXCOLOR(0.0F, 1.0F, 1.0F, 1.0F));

 

 // bottom
 m_pVtx[12] = VtxD(-1.f, -1.f, -1.f, D3DXCOLOR(1.0F, 1.0F, 0.0F, 1.0F));
 m_pVtx[13] = VtxD(1.f, -1.f, -1.f, D3DXCOLOR(0.0F, 1.0F, 0.0F, 1.0F));
 m_pVtx[14] = VtxD(1.f, -1.f, 1.f, D3DXCOLOR(0.0F, 0.0F, 1.0F, 1.0F));
 m_pVtx[15] = VtxD(-1.f, -1.f, 1.f, D3DXCOLOR(1.0F, 0.0F, 0.0F, 1.0F));

 

 // left
 m_pVtx[16] = VtxD(-1.f, -1.f, 1.f, D3DXCOLOR(1.0F, 1.0F, 0.0F, 1.0F));
 m_pVtx[17] = VtxD(-1.f, 1.f, 1.f, D3DXCOLOR(1.0F, 0.0F, 1.0F, 1.0F));
 m_pVtx[18] = VtxD(-1.f, 1.f, -1.f, D3DXCOLOR(0.0F, 1.0F, 1.0F, 1.0F));
 m_pVtx[19] = VtxD(-1.f, -1.f, -1.f, D3DXCOLOR(1.0F, 0.0F, 1.0F, 1.0F));

 

 // right
 m_pVtx[20] = VtxD(1.f, -1.f, -1.f, D3DXCOLOR(1.0F, 1.0F, 0.0F, 1.0F));
 m_pVtx[21] = VtxD(1.f, 1.f, -1.f, D3DXCOLOR(0.0F, 1.0F, 0.0F, 1.0F));
 m_pVtx[22] = VtxD(1.f, 1.f, 1.f, D3DXCOLOR(1.0F, 0.0F, 1.0F, 1.0F));
 m_pVtx[23] = VtxD(1.f, -1.f, 1.f, D3DXCOLOR(0.0F, 0.0F, 1.0F, 1.0F));

 

                            -----인덱스 데이터-----

 

// front
 m_pIdx[0] = VtxIdx(0, 1, 2);
 m_pIdx[1] = VtxIdx(0, 2, 3);

 

 // back
 m_pIdx[2] = VtxIdx(4, 5, 6);
 m_pIdx[3] = VtxIdx(4, 6, 7);

 

 // top
 m_pIdx[4] = VtxIdx(8, 9, 10);
 m_pIdx[5] = VtxIdx(8, 10, 11);

 

 // bottom
 m_pIdx[6] = VtxIdx(12, 13, 14);
 m_pIdx[7] = VtxIdx(12, 14, 15);

 

 // left
 m_pIdx[8] = VtxIdx(16, 17, 18);
 m_pIdx[9] = VtxIdx(16, 18, 19);

 

 // right
 m_pIdx[10] = VtxIdx(20, 21, 22);
 m_pIdx[11] = VtxIdx(20, 22, 23);  

 

정점 데이터, 인덱스 데이터 설정, 사각형은 앞,뒤,위,아래,왼쪽,오른쪽 총 6면이고,

면당 삼각형 2개(정점 4개)이므로 정점 데이터는 6 x 4 = 24개, 인덱스 데이터는 6 x 2 =12개 이다.

 

update()

 

D3DXMATRIX mtRotX;   // Rotation Matrix X
D3DXMATRIX mtRotY;   // Rotation Matrix Y
D3DXMATRIX mtRotZ;   // Rotation Matrix Z

 

        // 회전하는 월드 행렬 구성
FLOAT  fAngle = D3DXToRadian(GetTickCount() * 0.1f);
D3DXMatrixRotationY(&mtRotY, fAngle*1.f);
D3DXMatrixRotationZ(&mtRotZ, fAngle*1.f);
D3DXMatrixRotationX(&mtRotX, fAngle*1.f);

 

m_mtWld = mtRotY * mtRotZ * mtRotX;
m_mtWld._42 = 40.f;
m_mtWld._43 = -30.f;

 

 

월드 행렬에 X축, y축, Z축에 대해 회전값을 설정해주고 계속 해서 호출해주면서 계속 세 개의 축을 기준으로 회전하게 되는 사각형을 만들게 된다.

 

Render()

 

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

 

D3DXMatrixIdentity(&mtWld);

 

m_pdev->GetTransform(D3DTS_VIEW, &mtViw);
m_pdev->GetTransform(D3DTS_PROJECTION, &mtPrj);


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

 

// 상수 연결: 상수 테이블 사용
m_pTbl->SetMatrix(m_pdev, "m_mtWld", &m_mtWld);
m_pTbl->SetMatrix(m_pdev, "m_mtViw", &mtViw);
m_pTbl->SetMatrix(m_pdev, "m_mtPrj", &mtPrj);

 

m_pdev->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 24, 12, m_pIdx, D3DFMT_INDEX16, m_pVtx, sizeof(VtxD));

 

m_pdev->SetVertexShader(NULL);

 

 

셰이더 파일에 있는 m_mtWld(월드 행렬), m_mtViw(뷰 행렬), m_mtPrj(투영 행렬)에 각각 상수 테이블을 이용하여 설정해주고.

 

DrawIndexedPrimitiveUP 함수를 이용하여 인덱스와, 정점 데이터를 통한 사각형을 그려준다.

728x90
Posted by 정망스
,
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 정망스
,
728x90

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

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

 

 

struct VtxD
 {
      D3DXVECTOR3 p;
      DWORD d;

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

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

 

LPDIRECT3DVERTEXSHADER9  m_pVs;
LPDIRECT3DVERTEXDECLARATION9  m_pFVF;
LPD3DXCONSTANTTABLE  m_pTbl;

VtxD  m_pVtx[3];

 

이번엔 색상값이 들어가므로 DWORD d와, FVF에서 Diffuse가 추가 되었다.

 

*shader.fx*

 

// For Vertex Processing Input
struct SvtxIn
{
     float3 Pos : POSITION;
     float3 Nor : NORMAL;
     float4 Dif : COLOR;
     float2 Tex : TEXCOORD;
};

// For Vertex Processing Output
struct SvtxOut
{
     float4 Pos : POSITION;
     float4 Dif : COLOR;
     float2 Tex : TEXCOORD0;
     float4 Nor : TEXCOORD7; // 법선 벡터는 출력 레지스터가 없으므로 TEXCOORD 이용
};


SvtxOut VtxPrc(SvtxIn In)
{
     SvtxOut Out = (SvtxOut)0;  // Initialized to 0

     Out.Pos = float4(In.Pos, 1);
     Out.Dif = In.Dif;

     return Out;
}

 

이번 셰이더 파일은 구조체를 이용하여 정점의 입력,출력을 처리하고 있다.

VtxPrc 정점 셰이더 함수 안에서 입력받는 포지션과, diffuse 색상값을 출력 데이터로 설정해서 리턴해주고 있다.

 

m_pVtx[0] = VtxD(-1, -1, 0, D3DXCOLOR(1, 0, 0, 1)); //빨강
m_pVtx[1] = VtxD(0, 1, 0, D3DXCOLOR(0, 1, 0, 1)); //초록
m_pVtx[2] = VtxD(1, -1, 0, D3DXCOLOR(0, 0, 1, 1));  //파랑

 

이번엔 픽셀 셰이더에서의 시맨틱을 알아보자.

 

정점 셰이더 시맨틱과 동일하게 데이터의 출처에 대한 식별을 위해 사용한다.

시맨틱 위치는 구조체 멤버 뒤, 함수의 인수 뒤, 함수 뒤 등에 붙여서 사용한다.

 

1. 픽셀 셰이더 입력 시맨틱s

 

COLOR, COLOR[0, 1]: 정점 처리 과정에서 만들어진 Diffuse(0) Specular(1)

TEXCOORD, TEXCOORD[0~7]: 텍스처 좌표

2. 픽셀 셰이더 출력 시맨틱s

 

COLOR[n] 색상 → oC[n], COLOR =COLOR0

TEXCOORD[n]: → 텍스처 좌표

DEPTH[n]:  oDepth[n], DEPTH = DEPTH0

 

*shader.fx*

 

1.

float4x4 mtWorld : register(c0 ); // 전역 변수 mtWorld를 상수 레지스터 c0에 바인딩
float4   vcLight : register(c10); // 전역 변수 vcLight를 상수 레지스터 c10에 바인딩

 

2.
// Pixel Shader Main Function
//float4 PxlPrc(float2 vTex : TEXCOORD0) : COLOR0
//{
// return tex2D(DiffuseSampler, vTex);
//}

 

3.
// Vertex Shader Main Function
void VtxPrc( in float3 iPos : POSITION // dcl_position
   , in float4 iDif : COLOR0 // dcl_color0
   , out float4 oPos : POSITION // oPos
   , out float4 oDif : COLOR0 // oD0
)
{
 oPos = float4(iPos, 1);
 oDif = iDif;
}

 

1. 레지스터를 명시해서 바인딩하면 상수 테이블을 이용하지 않고 디바스의 SetVertexShaderConstantF() 함수를 이용해서 c0, c10 레지스터의 값을 변경할수 있으므로 결과적으로 mtWorld, vcLight를 수정한 것과 동일한 결과가 된다고 한다. (짤 사용하는것 같지는 않음..)

 

2. 사용자가 정의한 픽셀 셰이더 함수, tex2D 함수를 이용한 리턴 값의 타입이 COLOR0 이라고 보면 되는 사용자 정의 함수 사용법.

 

3. 사용자가 정의한 정점 셰이더 함수, 이번엔 함수가 void 형이다 void 형일 경우엔 인수 앞에 in/out 키워드를 넣어서 입 출력을 지정할수 있는 함수 사용법.

(함수의 인수 값을 내부에서 변경 못하게 하려면 uniform 키워드 사용)

 

728x90
Posted by 정망스
,


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