ID3DXSprite Interface (LPD3DXSPRITE) 사용하기

LPD3DXSPRITE
 

LPD3DXSprite
(이하 스프라이트) Interface
는 다이렉트 엑스에서 2D이미지를 그리기 편하게 해주는 인터페이스 입니다.
주로 UI를 그리거나 하는 평면 이미지를 그릴때 사용하는데, 3D상의 카메라에 2D이미지가 붙어 있다고 생각하시면 편합니다. 카메라를 움직이면 3D공간의 물체는 이동하지만 카메라에 붙은 2D이미지는 변함이 없는 것이지요. 여기서는 이 유용한 스프라이트 객체의 사용법에 대하여 알아보겠습니다.

 

1. 스프라이트 객체 생성과 해제

// 생성하기

LPD3DXSPRITE  pSprite;


D3DXCreateSprite(pd3dDevice, &pSprite);

 

스프라이트를 생성할때는 D3DXCreateSprite함수를 사용합니다.
함수를 간단히 살펴보면

 

HRESULT WINAPI D3DXCreateSprite(LPDIRECT3DDEVICE9 pDevice,
                                                    LPD3DXSPRITE *ppSprite);

 

인자로 디바이스와 생성할 스프라이트 객체를 넣어줍니다.

즉 생성할때 주의 하실점은 이상없이 생성된 장치(디바이스) 객체가 필요하며, 생성후에 디바이스에 이상(장치소실)이 생긴다면 스프라이트도 수정을 해주어야 합니다.

 

다이렉트 엑스 9.0c 버전의 프레임 워크에서는 ResetDevice() 에서 스프라이트를 만들어주고 LostDevice()에서 스프라이트 Release()를 실행합니다. 프레임워크를 사용하시는 분들은 이 부분만 주의해서 작성해 주시면 문제없이 스프라이트 사용을 하실 수 있습니다.

 

// 해제하기

pSprite->Release();

 

위에서 언급했듯이 Release를 호출하면 됩니다.

 

 

2. 스프라이트 사용하기

 

사용하기를 알아보려면 어떠한 메소드들이 있나 알아봐야겠죠. 다음은 DirectX SDK 도움말 문서입니다.

 

ID3DXSprite Interface


The ID3DXSprite interface provides a set of methods that simplify the process of drawing sprites using Microsoft Direct3D.

ID3DXSprite Members

Begin Prepares a device for drawing sprites.
Draw Adds a sprite to the list of batched sprites.
End Calls ID3DXSprite::Flush and restores the device state to how it was before ID3DXSprite::Begin was called.
Flush Forces all batched sprites to be submitted to the device. Device states remain as they were after the last call to ID3DXSprite::Begin. The list of batched sprites is then cleared.
GetDevice Retrieves the device associated with the sprite object.
GetTransform Gets the sprite transform.
OnLostDevice Releases all references to video memory resources and deletes all stateblocks.
OnResetDevice Should be called after the device has been reset.
SetTransform Sets the sprite transform.
SetWorldViewLH Sets the left-handed world-view transform for a sprite. A call to this method is required before billboarding or sorting sprites.
SetWorldViewRH Sets the right-handed world-view transform for a sprite. A call to this method is required before billboarding or sorting sprites.

Remarks

The ID3DXSprite interface is obtained by calling the D3DXCreateSprite function.

The application typically first calls ID3DXSprite::Begin, which allows control over the device render state, alpha blending, and sprite transformation and sorting. Then for each sprite to be displayed, call ID3DXSprite::Draw.ID3DXSprite::Draw can be called repeatedly to store any number of sprites. To display the batched sprites to the device, call ID3DXSprite::End or ID3DXSprite::Flush.

The LPD3DXSPRITE type is defined as a pointer to the ID3DXSprite interface. 

역시 도움말 보면 다 나오긴 합니다..ㅎ 위의 도움말은 9.0c버전인데, 9.0b와 약간 다릅니다. 

그러면 주어진 메소드를 가지고 스프라이트를 사용해 보도록 하겠습니다.

 

 

// 사용하기

pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 
                        D3DCOLOR_ARGB(0, 200, 200, 200), 1.0f, 0 );
if(SUCCEEDED(pd3dDevice->BeginScene()))
{
    pSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE ); 

    pSprite->Draw();

    pSprite->End();
    pd3dDevice->EndScene();
}
pd3dDevice->Present (NULL,NULL,NULL,NULL);

 

위의 소스는 간단하게 흐름을 알아보기 위한 것입니다. 흐름은

 

디바이스(BeginScene) =>
스프라이트(Begin) =>
스프라이트(Draw)=>
...=>
(Draw)

=>
스프라이트(End) =>
디바이스(EndScene) =>
디바이스(Present)

 

HRESULT D3DXCreateSprite
    LPDIRECT3DDEVICE9 pDevice,
    LPD3DXSPRITE *ppSprite
);

 
pDevice : IDirect3DDevice9 인터페이스의 포인터.
 
ppSprite : ID3DXSptrite 인터페이스의 포인터 주소. 사용자는 이 인터페이스를 사용해 스프라이트 함수에 액세스 한다.

이렇게 됩니다. 그럼 스프라이트의 Begin, Draw, End 메소드에 대해 간단히 알아보겠습니다.

 




 

HRESULT Begin( DWORD Flags );

 

플래그로 저는 보통 D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE  이렇게 넣습니다. 다른 인자들도 있는데, 텍스쳐의 정렬 방식과 그밖의 다른기능들이 있는데 UI로써의 사용은 위의 인자 정도면 충분히 사용가능하므로 넘어가겠습니다^^; 궁금하신분은 직접 도움말을...ㅎ (사실 딴 인자는 저도 잘 모르겠어요..-0- 빌보드 어쩌구 써있는거랑 보면 3D 공간상에서 스프라이트를 사용할 수 있는것 같은데^^;;)

 - LPD3DXSPRITE  : 스프라이트를 드로잉 하는 프로세스

- LPDIRECT3DTEXTURE9 : 텍스처 소스를 조작하기 위한 변수

 


ex) g_psImage->Draw( g_ptImage, NULL, NULL, NULL, 0, &D3DXVECTOR2( 0.0f, 0.0f ), D3DCOLOR_ARGB( 255, 255, 255,255 ) );

 

HRESULT Draw(      
    LPDIRECT3DTEXTURE9 pTexture,        // 그리기를 원하는 텍스쳐의 포인터


    CONST RECT *pSrcRect,                   // 텍스쳐의 그릴부분의 영역


    CONST D3DXVECTOR3 *pCenter,       // 정확한 의미는-_- 저는 그냥

                                                          // D3DXVECTOR3 ( 0.f, 0.f, 0.f) 를 넣습니다.


    CONST D3DXVECTOR3 *pPosition,     // 디바이스가 설정된 화면 영역의 좌상을

                                                          // D3DXVECTOR3 ( 0.f, 0.f, 0.f)으로 하여

                                                          // D3DXVECTOR3 ( x축, y축, 0.f)입니다.


    D3DCOLOR Color                             // 텍스쳐의 투명도와 색의 표현을 결정
);

 

이 Draw 함수를 이용해서 다양한 효과를 연출 할수 있는데요.

우선 Rect와 position을 이용해서 텍스쳐의 그릴부분을 조정하고 화면상에서 이동할수 있게 할수 있고, color를 이용해서 텍스쳐의 투명도를 조절할수 있습니다. (0xFFFFFFFF를 입력하면 텍스쳐 원래의 색이 나옵니다.)

 

이 Draw 함수를 이용해서 다양한 효과를 연출 할수 있는데요.

우선 Rect와 position을 이용해서 텍스쳐의 그릴부분을 조정하고 화면상에서 이동할수 있게 할수 있고, color를 이용해서 텍스쳐의 투명도를 조절할수 있습니다. (0xFFFFFFFF를 입력하면 텍스쳐 원래의 색이 나옵니다.)

 

HRESULT End(VOID);

 

이건 그냥 사용하시면 됩니다.

 

이정도면 UI를 그리고 배치하는데에는 별 문제 없으실 꺼에요

한가지 추가하자면 텍스쳐의 크기를 변경할때 제가 쓰는 방법인데 
 
스프라이트의 메소드 중에

 

HRESULT SetTransform(      
    CONST D3DXMATRIX *pTransform
);

 

SetTransform 이있습니다. 여기에 행렬을 넣어주면 월드행렬이 바뀐다고 생각하시면 됩니다.

여기에 스케일 값을 조절한 행렬을 넣어주면 그리려는 텍스쳐의 크기를 조절할수 있습니다.

문제는 텍스쳐의 크기만 바뀌는 것이 아니라 월드좌표가 바뀌는 것이라 위치값도 조정해 주어야 한다는 아주 귀찮은 문제가 있습니다...-_-;;
더 좋은 방법이 있으시면 알려주세요.

출저: 
ID3DXSprite Interface (LP.. :: 네이버블로그

이 글을 공유하기

댓글

Designed by JB FACTORY