Tutorial5- 텍스쳐

텍스쳐의 기초

폴리곤, 조명, 카메라 등의 조합만으로는 현실감이 없는 밋밋한 3D밖에 맛 볼수 없다. 
이러한 3D에 활력을 불어 넣어주는 것이 바로 텍스쳐이다.  
폴리곤들의 조합(메시)에 옷을 입히는 작업이라고 보면 쉽게 이해될 것이다.

 <사진출저: 한국콘텐츠 진흥원>

 

텍스쳐의 종류는 1차원, 2차원, 3차원 등이 있다. 
각 텍스쳐에는 텍스쳐를 제어하기 위한 텍스쳐만의 좌표계가 필요하다. 
일반적으로 가장 많이 사용하는 좌표계는 2차원 u, v 좌표계이다. 모든 텍스쳐 좌표계는 기본적으로 0.0 ~ 1.0사이의 실수값을 갖게 되고, 이 값의 범위를 넘게되면 다른 처리를 해줘야만 다양한 효과를 낼 수 있다. 그러한 효과에는 Clamp, Mirror, Wrap, Border 등이 있다.
u.v좌표 : (x값 0.0~1.0) (y값 0.0~1.0) 

 <사진출저: 한국콘텐츠아카데미>



텍스쳐를 사용하기 위한 준비


1. IDirect3DTexture9 인터페이스 선언

LPDIRECT3DTEXTURE9      g_pTexture   = NULL;    // 텍스쳐 정보
 

2. 텍스쳐 좌표를 갖는 정점 선언

struct CUSTOMVERTEX
{
    D3DXVECTOR3    position
; // 3차원 좌표
    D3DCOLOR    color;  // 색깔
    FLOAT       tu, tv;   // 텍스쳐 좌표
};

/// 사용자 정점 구조체에 관한 정보를 나타내는 FVF값
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
 

3. 텍스쳐 생성( 파일을 로드하는 방법과, 라이트맵핑과 같이 직접 생성도 한다. )

D3DXCreateTextureFromFile( g_pd3dDevice, "banana.bmp", &g_pTexture )
 

4. 텍스쳐 스테이지 설정(텍스쳐 스테이지는 여러장의 텍스쳐와 색깔정보를 섞어서 출력할때 사용된다.)

g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, 

                                                   D3DTOP_MODULATE );

5. 그려질 텍스쳐 지정

g_pd3dDevice->SetTexture( 0, g_pTexture ); // 0번 텍스쳐 스테이지에 텍스쳐 고정
 

6. 메시 그리기

g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2*50-2 );

 

텍스쳐를 사용하기 위해서는 많은 전처리 및 설정이 필요하면 별도의 정점도 선언해야 한다.
또한 메시의 형태에 따라 텍스쳐이미지의 제작방법도 다르다. 이러한 부분은 차후에 좀더 알아보도록 하자. 


<텍스쳐 소스분석>
 


 

//  1. InitGeometry()

//  기하 정보 초기화 

//  정점 버퍼와 텍스처 생성

 

HRESULT InitGeometry()
{

   
/// D3DX계열 함수를 사용해서 파일로부터 텍스쳐 생성(banana.bmp)
    if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "banana.bmp",

                                                         &g_pTexture ) ) )
    {

   
       /// 현재폴더에 파일이 없으면 상위폴더 검색
        if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice,

                                               "..\\banana.bmp", &g_pTexture ) ) )
        {

              /// 텍스쳐 생성 실패
            MessageBox(NULL, "Could not find banana.bmp", "Textures.exe",

                              MB_OK);
            return E_FAIL;
        }
    }
 

    /// 정점버퍼 생성
    if( FAILED( g_pd3dDevice->CreateVertexBuffer(

                                                  50*2*sizeof(CUSTOMVERTEX),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    {
        return E_FAIL;
    }

    /// 정점버퍼를 값으로 채운다.
    /// 텍스쳐의 u,v좌표값을 0.0 ~ 1.0 사이의 값으로 채워넣고 있다.

    CUSTOMVERTEX* pVertices;

    if( FAILED( g_pVB->Lock( 0, 0, (void**)&pVertices, 0 ) ) )
        return E_FAIL;

    for( DWORD i=0; i<50; i++ )
    {
        FLOAT theta = (2*D3DX_PI*i)/(50-1);

        pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );
        pVertices[2*i+0].color    = 0xffffffff;
 


        pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );

        pVertices[2*i+1].color    = 0xff808080;
 


    }

    g_pVB->Unlock();

    return S_OK;
}


// 2. Render()

// 화면에 그려주기 

 

VOID Render()
{
     
// 후면버퍼와 Z버퍼를 지운다.
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
                         D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );

      // 렌더링 시작
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {

          // 월드,뷰,프로젝션 행렬을 설정한다.
        SetupMatrices();
 

          // 생성한 텍스쳐를 0번 텍스쳐 스테이지에 올린다.
          // 텍스쳐 스테이지는 여러장의 텍스쳐와 색깔정보를 섞어서 출력할때 사용된다.
          // 여기서는 텍스쳐의 색깔과 정점의 색깔정보를 modulate연산으로 섞어서 출력한다.
 

          // 0번 텍스쳐 스테이지에 텍스쳐 고정
        g_pd3dDevice->SetTexture( 0, g_pTexture );         

         
          // MODULATE연산으로 색깔을 섞음
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,  

                                                           D3DTOP_MODULATE ); 

          // 첫번째 섞을색은 텍스쳐 색
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1,

                                                           D3DTA_TEXTURE ); 

          // 두번째 섞을색은 정점 색
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2,

                                                           D3DTA_DIFFUSE ); 

          // alpha연산은 사용하지 않음
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,  

                                                           D3DTOP_DISABLE ); 

   

          // 정점버퍼의 내용을 그린다.
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0,

                                                     sizeof(CUSTOMVERTEX) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2*50-2 );
 

          // 렌더링 종료
        g_pd3dDevice->EndScene();
    }

    // 후면버퍼를 보이는 화면으로!
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

전체 소스를 받아보면 #ifdef문은 주석으로 막아준 #define SHOW_HOW_TO_USE_TCI를 열고 컴파일 해보면 무엇인지 알수있을 것이다. 그 부분은 반사맵핑이라는 기법이다

 
 

이 글을 공유하기

댓글

Designed by JB FACTORY