반응형

1 ID3DXSprite 란? #

d3d 내에서 2D를 표현하기 위한 인터페이스


2 ID3DXSprite 의 사용법 #

Begin스프라이트를 드로잉(Drawing) 할 수 있도록(듯이) 장치를 준비한다.
Draw스크린 공간에 단순한 스프라이트를 드로잉(Drawing) 한다.
DrawTransform지정한 행렬에 의해 변환 한 스프라이트를 드로잉(Drawing)하기 위한 구조를 제공한다.
EndID3DXSprite::Begin 가 불려 간 시점의 장치 스테이트를 복원한다.
GetDevice스프라이트 개체에 관련지을 수 있는 Direct3D 장치를 얻어온다.
OnLostDevice비디오 메모리 리소스에의 참조를 모두 릴리즈 해, 모든 스테이트 블록을 삭제한다.
OnResetDevice장치가 리셋 된 후에 호출할 필요가 있다.|

위의 표는 다이렉트X 헬프에 있는 내용이다. 사용법을 간단히 말하면 IDirect3DDevice9::BeginScene 과 IDirect3DDevice9::EndScene 사이에 ID3DXSprite::Begin 과 ID3DXSprite::End 를 호출하고 그 사이에 그리면 된다.


           IDirect3DDevice9::BeginScene
          
           ID3DXSprite::Begin
          
           << 여기다가 그리는걸 호출 >>>
          
           ID3DXSprite::End
          
           IDirect3DDevice9::EndScene
          


코드가 대충 이런 형태가 된다. 그릴때는 Draw 메소드를 호출해서 사용하는데


           HRESULT Draw(LPDIRECT3DTEXTURE9 pSrcTexture,
          
           CONST RECT *pSrcRect,
          
           CONST D3DXVECTOR2 *pScaling,
          
           CONST D3DXVECTOR2 *pRotationCenter,
          
           FLOAT Rotation,
          
           CONST D3DVECTOR2 *pTranslation,
          
           D3DCOLOR Color
          
           );
          


드로우 함수의 인자들 설명을 하자면
  • 첫번째 인자는 스프라이트에 사용할 텍스쳐이다. 스프라이트는 2D 게임프로그래밍을 해본사람이라면 느낌일 팍 올테니...
  • 두번째 RECT 구조체의 인자는 덱스쳐중에 어느 부분을 사용할것이가를 의미한다.
  • 세번째 D3DXVECTOR2 는 스케일링 인자라고하는데 x, y가 각각 가로 세로로 얼마나 늘려서 아니면 줄여서 사용할 것인지를 나타낸다. 뭐 기본값은 1.0f , 1.0f 다. 두배로 늘릴려면 2.0f, 2.0f 로 쓸수 있다. 음 RECT로 한픽셀 범위만 잡은뒤 가로 세로로 늘려서 원하는 길이의 선분을 얻을수도 있다. 뭐 대충 그런식...
  • 네번째 D3DXVECTOR2 는 회전중심이라고 하는데 아직 사용해보지는 않아서 모르겠지만 다섯번째 인자로 회전을 할때 어디를 중심으로 할것인가를 나타낸다. 기본값은 0.0f, 0.0f 이다.
  • 다섯번째 FLOAT 는 회전값인데.. 1.0f 를 넣어주니 90도가 회전했다. 음 정확한건 모르겠다.
  • 여섯번째 D3DCOLOR 은 값에 의해 컬러 채널과 알파 채널이 곱셈된다 라고 써있다.. 그냥 0xFFFFFFFF 를 넣어주면 원래 이미지 그래도 찍힌다. 흐음 마스킹값을 넣어주는 건가? 
인자를 설명하면 대충이렇다.(아아 정말 대충이다.) 그런데 이 스프라이트객체를 사용할때는 꼭 2의 X승 크기의 이미지를 사용해야 한다. 안그러면 RECT 구조체로 범위를 지정할때 엉망징창이 된다. 어떤 사람은 메모리도 센다고 하더라...


그리고 당연한 소리같지만 스프라이트 역시 순서에 따러 덥힌다. 즉 스프라이트를 찍고 오브젝트를 렌더링 하면 오브젝트에 가려 스프라이트가 안보일수고 있다는 것이다. 스프라이트도 D3D에서는 프리미티브로 처리할줄 알았는데... 조금 다른가보다.

 

// 스프라이트 객체 생성
 D3DXCreateSprite( g_pd3dDevice, &pSprite );

 // 텍스쳐 생성
 D3DXCreateTextureFromFile( g_pd3dDevice, "..\\res\\google.bmp", &m_Bground );

 

 RECT rext = { 0, 0, 16, 17 };
  pSprite->Begin( D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE );
  pSprite->Draw( m_Bground, &rext, NULL, &D3DXVECTOR3( g_MousePoint->x, g_MousePoint->y, 0 ), 0xffffffff );
  pSprite->End();

 
======================================================================================================

[Direct3D] ID3DXSprite로 BillBoard 사용하기

몇년전 DX가지고 이런말 하는 것도 우습지만, DX가 버전업하면서 
단순한 스크린평면에 텍스쳐를 뿌리는 것뿐이었던 ID3DXSprite가 여러가지 기능을 탑재하게 되었습니다. 

그중 빌보드를 구현할 수 있다는 내용도 포함되어 있죠. 
예전에는 기능이 있다는 것만 알고 넘어갔는데
얼마 전 수업에서 언급되었길래 한번 사용법을 찾아봤습니다... 


당연히 3D상에서 빌보드효과를 위해선 월드좌표상에서 텍스쳐를 뿌려야겠죠...
(g_SP가 ID3DXSprite 객체입니다. D3DXCreateSprite로 생성합니다.)

g_SP->Begin(D3DXSPRITE_BILLBOARD | D3DXSPRITE_OBJECTSPACE);

그리고 출력을 합니다. 

g_SP->Draw(g_pTxFloor, NULL, NULL, NULL, 0xffffffff);


당연히 제대로 출력될 리가 없죠...
BillBoard는 항상 카메라를 향하며 회전하므로, 그에 대한 정보를 넣어줘야 하니깐요. 
카메라 정보를 전달해 주는 것은 SetWorldViewLH메소드가 맡고 있습니다. 

g_SP->SetWorldViewLH(NULL, &mxView);


문제는 SetWorldViewLH의 호출 위치입니다!!!
이 함수는 Begin과 End내에서 호출하면 실패하게 됩니다. 
반드시 Begin 앞에서 호출해줘야 합니다!!!

이것때문에 좀 해맸네요...
빌어먹을... MSDN에도 명시되어 있지 않습니다... 



몇가지 유추한 것들을 적자면

SetWorldView의 WorldMatrix는 BillBoard에선 사용하지 않는 듯 싶습니다. 값변화가 적용되지 않습니다. 
대신 위치를 지정할땐, Draw의 Position Vector로 입력해주면 됩니다. 
또한 빌보드의 회전축은 기본적으로 이미지의 좌하단입니다. (Draw시 NULL 입력할때)

정상적인 빌보드로 사용할려면 이미지의 중심을 센터로 잡아줘야 하는데,
이때의 좌표값은 텍스쳐의 물리적 위치입니다. (일반적으로 1.0으로 맵핑되는 방식이 아닙니다.)
예를 들어 512x512이미지라면 256, 256를 넣어줘야 중심으로 지정됩니다. 

그리고 월드스페이스상의 메쉬의 크기는 별도의 지정하는 게 안보이고
상대적으로 매우 커지는 것으로 봐선, 이미지의 크기만큼 메쉬를 생성하는게 아닐까 싶네요. 
적당히 스케일해줘야겠죠... 자세한건 실험해보거나 문서를 찾아보면 되겠죠... 


써 본 감상으로는.... 
그냥 빌보드 오브젝트 따로 만들어서 쓰고 말겠습니다.... 
만드는 것도 간단하고, 다른 메쉬들과 호환성도 유지할 수 있고 말이죠... 커스텀도 가능하고...

외국쪽에서도 그렇고, 자료 정말 없네요.....
하긴 그다지 필요 없어보이긴 하죠 --;;;
 
 
스프라이트로 글자 출력도 가능하다

반응형

+ Recent posts