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), };
 };

 

LPDIRECT3DPIXELSHADER9  m_pPs;    // Pixel Shader
LPD3DXCONSTANTTABLE  m_pTbl;    // Constant Table

 

D3DXMATRIX  m_mtWld;   // World Matrix

 

INT   m_iNvx;    // Vertex Number
VtxDUV1* m_pVtx;    // Vertex Buffer
LPDIRECT3DTEXTURE9  m_pTx0;

 

포지션(xyz), 색상(diffuse), 텍스처(tex1)로 구성된 정점 데이터이다.

 

*shader.fx*

 

sampler smp0 : register(s0);

 

float4 PxlPrc( in float4 Dif : COLOR0, in float4 Tex0 : TEXCOORD0 ) : COLOR0
{

float4 Out;

Out = tex2D(smp0, Tex0);   // Sampling Texture with Sampler
Out *= Dif;       // Modulate Diffuse
Out *= 2;       // Modulate2X

 

return Out;

}

 

1. 다중 텍스처 처리일 경우 샘플러를 샘플러 레지스터에 명시적으로 선언을 해주어야 한다.

pDevice->SetTexture(StageIndex, pTexture)와 같은 함수를 실행 할 때 stageIndex에 해당하는 레지스터에 텍스처 포인터가 자리 잡고 이 텍스처를 샘플러가 샘플링 한다.

 

2. 모든 샘플링 함수는 샘플러와, 텍스처 좌표를 인수로 받는다. 따라서 픽셀 처리의 함수는 텍스처 좌표의 정보를 받아야한다.

 

3. 래스터라이즈 이후 만들어진 색상과, 텍스처의 색상을 modulate 한다.

 

*Update()*

 

static float c = 0;

 

c = 10.f * GetTickCount();

 

if (c>360.f)
  c -= 360.f;

 

D3DXMATRIX mtY;
D3DXMATRIX mtZ;


// 월드 행렬 갱신
D3DXMatrixIdentity(&m_mtWld);
D3DXMatrixRotationY(&mtY, D3DXToRadian(-c));
D3DXMatrixRotationZ(&mtZ, D3DXToRadian(-23.5f));

 

m_mtWld = mtY * mtZ;

 

구를 회전 시키기 위한 처리. z축은 고정값,  y축은 일정 시간 기준으로 계속해서 회전값을 바꾸면서 월드행렬에 적용시키고 있다.

 

*Render()*

 

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);

 

m_pdev->SetTransform(D3DTS_WORLD, &m_mtWld);


// Render
m_pdev->SetPixelShader(m_pPs);

 

m_pdev->SetFVF(VtxDUV1::FVF);
m_pdev->SetTexture(0, m_pTx0);
m_pdev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, m_iNvx - 2, m_pVtx, sizeof(VtxDUV1));

 

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


D3DXMATRIX mtI(1, 0, 0, 0,
                        0, 1, 0, 0,
                        0, 0, 1, 0,
                        0, 0, 0, 1);

 

m_pdev->SetTransform(D3DTS_WORLD, &mtI);

 

셰이더 파일에서 샘플러를 StageIndex 0번에 해당하는 레지스터에 등록했으므로 SetTexture 함수의 StageIndex에 0을 설정해준다.

 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), };
 };

 

LPDIRECT3DPIXELSHADER9  m_pPs;    // Pixel Shader
LPD3DXCONSTANTTABLE  m_pTbl;    // Constant Table

 

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

 

포지션(xyz), 색상(diffuse), 텍스처(tex1)로 구성된 정점 데이터이다. 이번엔 사각형이므로 정점은 4개로 구성되고 , 3개의 텍스처(m_pTx0, m_pTx1, m_pTx2)를 사용한다. 

 

 *shader.fx*

// SetTexture에 해당하는 샘플러 ==> 레지스터에 지정
//sampler smpDif0 : register(s0); // pDev->SetTexture(0, ...)
//sampler smpDif1 : register(s1); // pDev->SetTexture(1, ...)


// Smapler state를 이용한 샘플러 객체 선언
sampler smpDif0 : register(s0) = sampler_state
{
    MinFilter = POINT;  // Filtering
    MagFilter = POINT;
    MipFilter = POINT;
    AddressU = Wrap;  // Addressing
    AddressV = Wrap;
};

sampler smpDif1 : register(s1) = sampler_state
{
    MinFilter = NONE;
    MagFilter = NONE;
    MipFilter = NONE;
    AddressU = Wrap;
    AddressV = Wrap;
};

sampler smpDif2 : register(s2) = sampler_state
{
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    MipFilter = LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};


float4 PxlPrc( in float4 Dif : COLOR0, in float2 Tx0 : TEXCOORD0 ) : COLOR0
{
     float4 Out;
     float4 t0;
     float4 t1;
     float4 t2;

 

     t0 = tex2D(smpDif0, Tx0); // Sampling Texture0
     t1 = tex2D(smpDif1, Tx0); // Sampling Texture1
     t2 = tex2D(smpDif2, Tx0); // Sampling Texture2

 

     Out = t0 *.6 + t1 * .8;
     Out *= (t2*1.3f);

 

     Out = pow(Out, 1.5) * 1.5;

 

     Out.w = 1;     // Setup alpha = 1

 

     return Out;
}

 

sampler_state를 사용하여 샘플러를 레지스터에 등록함과 동시에 샘플러에 대해서 필터링과 어드레싱을 할수있다.

 

t0 = 지구, t1 = 다이렉트x 로고, t2 = 중간에 흰색으로 된 산모양  의 세가지 텍스처를 이용한다.

 

D3DXCreateTextureFromFile(m_pdev, "Texture/earth.bmp", &m_pTx0);
D3DXCreateTextureFromFile(m_pdev, "Texture/dx5_logo.bmp", &m_pTx1);
D3DXCreateTextureFromFile(m_pdev, "Texture/env0.png", &m_pTx2);

 

m_pVtx[0] = VtxDUV1(-1.05F, 1.02F, 0, 0, 0, D3DXCOLOR(1, 0, 0, 1));
m_pVtx[1] = VtxDUV1(1.05F, 1.02F, 0, 1, 0, D3DXCOLOR(0, 1, 0, 1));
m_pVtx[2] = VtxDUV1(1.05F, -1.02F, 0, 1, 1, D3DXCOLOR(0, 0, 1, 1));
m_pVtx[3] = VtxDUV1(-1.05F, -1.02F, 0, 0, 1, D3DXCOLOR(1, 0, 1, 1));

 

세 개의 텍스처 파일을 가져오고 정점 4개 각각 위치, uv좌표, 색상을 설정하고 있다.

 

*Render()*

m_pdev->SetRenderState(D3DRS_LIGHTING, FALSE);

 

m_pdev->SetPixelShader(m_pPs);

 

m_pdev->SetFVF(VtxDUV1::FVF);

 

m_pdev->SetTexture(0, m_pTx0);
m_pdev->SetTexture(1, m_pTx1);
m_pdev->SetTexture(2, m_pTx2);

 

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


m_pdev->SetTexture(0, NULL);
m_pdev->SetTexture(1, NULL);
m_pdev->SetTexture(2, NULL);

 

m_pdev->SetPixelShader(NULL);

 

StageIndex( 0, 1, 2 )에 3개의 텍스처를 설정해주고 있다.

 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), };
 };

 

LPDIRECT3DPIXELSHADER9  m_pPs;    // Pixel Shader
LPD3DXCONSTANTTABLE  m_pTbl;    // Constant Table

 

LPDIRECT3DTEXTURE9  m_pTx0;    // Texture 0
LPDIRECT3DTEXTURE9  m_pTx1;    // Texture 1

 

포지션(xyz), 색상(diffuse), 텍스처(tex1)로 구성된 정점 데이터이다. 2개의 텍스처(m_pTx0,m_pTx1)를 사용한다. 

 

*shader.fx*

 

// Multi Texturing Type
int  m_nMulti;


// Sampler
sampler SampDif0 : register(s0) = sampler_state
{
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    MipFilter = LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

sampler SampDif1 : register(s1) = sampler_state
{
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    MipFilter = LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

 

// Pixel Shader Main Function
float4 PxlPrc(float4 Tx0 : TEXCOORD0) : COLOR0
{
     float4 Out= 0;
     float4 t0 = tex2D( SampDif0, Tx0 );   // Sampling m_TxDif0
     float4 t1 = tex2D( SampDif1, Tx0 );   // Sampling m_TxDif1

 

     if (0 == m_nMulti)  Out = t0;
     else if (1 == m_nMulti) Out = t1;
     else if (2 == m_nMulti) Out = t0 * t1;   // Modulate
     else if (3 == m_nMulti) Out = t0 * t1 * 2;  // Modulate 2x
     else if (4 == m_nMulti) Out = t0 * t1 * 4;  // Modulate 4x
     else if (5 == m_nMulti) Out = t0 + t1;   // Add
     else if (6 == m_nMulti) Out = t0 + t1 - .5;  // Add signed
     else if (7 == m_nMulti) Out =(t0 + t1 - .5)*2; // Add signed
     else if (8 == m_nMulti) Out = t0 + t1 - t0*t1; // add smooth
     else if (9 == m_nMulti) Out = t0 - t1;   // sub
     else if (10== m_nMulti) Out = t1 - t0;   // sub
     else if (11== m_nMulti) Out = 1 - t0;   // Inverse t0
     else if (12== m_nMulti) Out = 1 - t1;   // Inverse t1
     else if (13== m_nMulti) Out = 1 - (t0 + t1); // Inverse (t0+t1)

 

     return Out;
}

 

다중 텍스처 처리1,2 과정을 함께 이용하여 if-else문을 사용하서 m_nMulti의 값과 일치하는 조건문에 해당하는 산술 연산을 하여 처리하고 있다.

 

t0 (지구), t1 (다이렉트x 로고) 2가지 텍스처를 사용하고 있다. 

 

*Render()*

 

HRESULT  hr = -1;

 

m_pdev->SetRenderState(D3DRS_LIGHTING, FALSE);

 

m_pdev->SetPixelShader(m_pPs);

 

m_pdev->SetFVF(VtxDUV1::FVF);
m_pdev->SetTexture(0, m_pTx0);
m_pdev->SetTexture(1, m_pTx1);

 

VtxDUV1 pVtx[4];

 

for (int i = 0; i <= 13; ++i)
{
  float x = -1.f + float(i % 4) / 2.f;
  float y = 1.f - float(i / 4) / 2.f;

 

  pVtx[0] = VtxDUV1(x + 0.f, y - 0.f, 0, 0, 0, D3DXCOLOR(1, 0, 0, 1));
  pVtx[1] = VtxDUV1(x + .5f, y - 0.f, 0, 1, 0, D3DXCOLOR(0, 1, 0, 1));
  pVtx[2] = VtxDUV1(x + .5f, y - .5f, 0, 1, 1, D3DXCOLOR(0, 0, 1, 1));
  pVtx[3] = VtxDUV1(x + 0.f, y - .5f, 0, 0, 1, D3DXCOLOR(0, 0, 1, 1));

 

  hr = m_pTbl->SetInt(m_pdev, "m_nMulti", i);
  hr = m_pdev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, pVtx, sizeof(VtxDUV1));
}

 

m_pdev->SetPixelShader(NULL);

 

m_nMulti값 (0~13) 총 14개의 텍스처 처리 연산의 종류가 있고 for문을 이용하여 사각형에 1개씩 처리하여 그리고 있다.

728x90

'Shader' 카테고리의 다른 글

17. Effect의 상태 설정.  (0) 2017.03.10
16. D3DEffect  (1) 2017.02.14
14. 텍스처 처리(단색화, 흐림효과)  (0) 2017.02.09
13. 픽셀 처리 사용자 함수  (0) 2017.02.09
12. 알록달록 사각형(간단한 픽셀 처리)  (0) 2017.02.09
Posted by 정망스
,


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