SpriteBatch

Draw Class에 보면 최 상단에 SpriteBatch.Begin 메서드가 있고 SpriteBatch.End 메서드가 있다. 두 메서드 사이에 SpriteBatch를 이용해 그려지는 (DrawString, Draw 등의 메서드) 등은 SpriteBatch의 설정을 모두 이어받는다.

환경 설정은 SpriteBatch.Begin 메서드는 다수의 메서드로 오버로딩 되어있는데 각각 알아보자.

 

SpriteBatch.Begin()
SpriteBatch.Begin(SpriteSortMode, BlendState)
SpriteBatch.Begin(SpriteSortMode, BlendState, SamplerState, DepthStencilState, RasterizerState)
SpriteBatch.Begin(SpriteSortMode, BlendState, SamplerState, DepthStencilState, RasterizerState,Effect)
SpriteBatch.Begin(SpriteSortMode, BlendState, SamplerState, DepthStencilState, RasterizerState,Effect, Matrix)

어차피 생성자를 재 호출 하고 추가된 기능만 수정되지 싶으니 인자의 역할을 하나하나 살펴보자.

SpriteSortMode – 이미지 출력 순서를 결정

Deferred / Immediate / Texture / BackToFront / FrontToBack

의 속성들을 갖고 있는데 각각에 대해 간단히 알아보겟다.

Deferred – SpriteBatch.End() 가 호출되기 전까지 스프라이트를 화면에 출력하지 않으며, 호출될 때 호출된 순서대로 출력. 가장 기본적인 처리 방식이다

Immediate – Draw 메서드 호출시 즉각적으로 화면에 출력한다.가장 빠르지만 한 번에 SpriteBatch 메서드 밖에 활성화 시킬 수 없는 문제가 있다.

Texture – 텍스쳐 우선순위 별로 정렬하여 마지막에 모아서 그린다.

* 텍스쳐 우선순위 : Draw 메서드는 여러 개의 오버로딩 함수가 있다(MSDN을 참조해보면 7개 정도 있는 것 같다)  여기서Draw Order란 항목이 있다고 하는데 이것에 따라 출력됨을 원칙으로 한다.

BackToFront – Deferred모드와 동일하지만 호출 순서의 반대로 출력이 된다. (즉 마지막에 호출된 Draw가 가장 앞에 출력이 된다)

FrontToBack – Layer Depth 인자를 이용하여 그에 따라 출력을 한다. 생각하기에 Deferred 와 함께 개인적으로 많이 쓸 방식이 아닌가 싶다.

BlendState – 이미지 출력시 색상 혼합이 일어나는 방식을 결정하기 위해 사용.

AlphaBlend/Additive/NonePremultiplied/Opaque

의 속성들을 갖고 있다.

Alphablend -  알다시피 알파블렌딩이다. 알파 값을 조절해 겹치게 하는 것.

Additive – 색상 혼합

NonePremultiplied – 아무런 처리를 하지 않고 그냥 출력

Opaque – 불투명 처리를 통해 알파 값을 무시하고 이미지를 그대로 출력

SamplerState – Clamp 와 Wrap 모드로 나뉘며 그에 따라 필터링 방식이 세분화된다.

Clamp 모드는 텍스쳐의 경계에 위치한 가장자리 픽셀을 사용해 범위에 벗어난 부분을 표현한다.

Warp 모드는 범위를 벗어난 부분에 대해 텍스쳐를 반복해서 출력한다.(타일 형식으로 부어버림)

필터링은 Point, Linear, Anisotropic 세 가지 방식을 지원한다. Point 방식은 해당 지점에 가까운 텍스쳐를 그대로 사용하여 처리 시간이 짧고, Linear 방식은 해당 지점과 가까운 텍스처의 주변 색상을 선형 보간을 통해 출력 색상을 결정한다. Anisotropic 방식은 비등방성 필터링을 이야기한다.

DepthStencilState – 장치의 깊이 버퍼의 사용 방식을 결정한다. DepthBufferEnable / DepthBufferWriteEnable의 설정값이 자동으로 변경이 된다.

DepthBufferEnable – Pixel Buffer에 객체를 그릴 때 깊이 버퍼의 값을 비교해 객체의 출력 여부를 결정한다.

DepthBufferWriteEnable – 객체를 픽셀 버퍼에 그릴 때 객체의 깊이 값을 깊이 버퍼에 저장할 것인지 결정

DepthStencilState의 설정 가능 목록은 다음과 같다.

Default / DepthRead / None 이 있다.

RasterizerState – 벡터 정보를 레스터 정보로 어떻게 변환할 것인지 처리한다.

여기서 3D쪽에 많이 나오는 CW,CCW가 나온다.

CullClockWise – 시계방향으로 앞면을 판별, 뒷면 미출력

CullCounterClockWise – 반시계방향으로 앞면을 판별, 뒷면 미출력

CullNoneNone – 앞면, 뒷면 모두 출력

Effect – Begin과 End 사이에 그려지는 3D 객체들에 대해 쉐이더 효과를 지정한다.  WP7에서는 성능 저하를 막기 위해 간단한 5가지 이펙트를 쓸 수 있다. 그 목록은 다음과 같다.

BasicEffect / AlphaTestEffect / DualTextureEffect / EnvironmentMapEffect / SkinnedEffect

BasicEffect – 기본 제공 이펙트

AlphaTestEffect – 투명 효과에 특화되어있는 이펙트

DualTextureEffect - 2개 이상의 텍스쳐를 사용할 수 있는 이펙트

EnvironmentMapEffect – 객체 주변의 환경을 반영할 수 있는 이펙트

SkinnedEffect – 스키닝 애니메이션을 모델에 적용 가능한 Effect

Matrix – 구조체를 이용해 회전이나 반전 등을 사용할 수 있다.

여기까지가 Begin의 인자들의 설명이다. 사실 이런거 알아서 뭐하나~ 싶은데 ………. 개인적으로 이런 거 잘 몰라서 고생한 기억도 있고, 알아두면 나중에 다 뼈가 되고 살이 된다고 생각한다.

SpriteBatch.End()

Begin, End 사이에서 사용된 출력 대상을 화면에 반영하고 출력 환경을 복원한다. Begin과 End 메서드 사이에 다른 SpirteBatch 클래스의 Begin 과 End를 사용할 수 없다(runtime error발생). 또한 짝을 잘 맞춰서 사용해야 한다.

 

SpriteBatch.Draw()

이 메서드는 2D 이미지를 화면에 출력할 수 있다. 오버로딩된 함수의 목록은 다음과 같다.

SpriteBatch.Draw(Texture2D, Rectangle, Color)
SpriteBatch.Draw(Texture2D, Rectangle, Nullable<Rectangle>, Color)
SpriteBatch.Draw(Texture2D, Rectangle, Nullable<Rectangle>, Color, float, Vector2, SpriteEffects, float)
SpriteBatch.Draw(Texture2D,  Vector2, Color)
SpriteBatch.Draw(Texture2D, Vector2, Nullable<Rectangle>, Color)
SpriteBatch.Draw(Texture2D, Vector2, Nullable<Rectangle>, Color, float, Vector2, float, SpriteEffects, float)
SpriteBatch.Draw(Texture2D, Vector2, Nullable<Rectangle>, Color, float, Vector2, Vector2, SpriteEffects, float)

각각의 매개변수의 역할은 다음과 같다.

Texture2D texture: 이미지

Vector2 position: 화면 출력 위치 좌표 지정

Rectangle destinationRectangle: 화면 출력 rect 지정. 자동으로 이미지를 확대, 축소해 영역에 맞춘다.

Nullable<Rectangle> sourceRectangle: 이미지 자산 중 출력하고 싶은 부분을 지정

Color color: 이미지 자산과 색상 혼합. Color.White를 사용지 원 이미지 그대로 표현 가능

float rotation: 이미지 회전 상태 지정. radian 형식의 값 사용

Vector2 origin: 이미지 출력 기준 위치 지정. 회전 상태, 출력 위치 등에 영향을 준다.

float scale: 이미지 확대 축소 비율 지정. 가로, 세로 방향 동일

Vector2 scale: 이미지 확대 축소 비율 지정. 가로, 세로 방향 다르게 사용 가능.

SpriteEffects effects: 이미지 좌우, 상하 반전 효과 지정

float layerDepth: 출력 순서 지정

Draw 메서드를 사용해서 화면에 출력시 어떻게 내부에서 처리되는 과정을 이해한다면 매개변수 설정에 따라 어떤 결과가 나올 것인지 예상할 수 있다. 

현재 공식적으로 내부 처리 과정에 대해 설명한 자료가 없으므로 이는 출력 결과를 바탕으로 예상한 내용이라는 것에 주의해야 한다.

우선 이미지에서 많이 쓰이는 두가지 좌표계에 알아 둘 필요가 있을 것 같다. 간단히 그림으로 설명하면 다음과 같다.

위 그림은 정점 좌표계에 대해 이야기한다. 정점 좌표계에선 축을 지칭할 때 가로를 x축, 세로를 y축으로 한다.

그리고 해당 이미지의 좌측 끝 좌표를 Left, 우측 끝 좌표를 Right라고 한다. 최상단을 Top, 최하단을 Bottom이라고 칭한다. 그래서 이를 기준으로 4 꼭지점에 대한 좌표를 정의하면 위의 그림에도 보이듯이 다음과 같이 이야기한다.

좌측 상단: (Left, Top)

우측 상단: (Right, Top)

좌측 하단: (Left, Bottom)

우측 하단: (Right, Bottom)

위의 그림은 UV좌표계를 이야기한다. UV좌표는 텍스쳐의 좌표를 설정해 출력할 이미지에 대한 조작을 가한다.

텍스쳐 좌표 설정시 영향을 주는 요소는 잘라내기 영역과 좌우, 상하 반전 효과이다. 텍스쳐 좌표는 텍스쳐가 변경되어도 그 크기에 상관없이 텍스쳐 좌표를 계속 사용할 수 있도록 실수로 표현한다.

Left = 0, Right = 1, Top = 0, Bottom = 1 과 같은 개념으로 생각하면 되겠다. Right를 Texture.Width와 같게 표현한다고 볼 수 있으며, Bottom을 Texture.Height와 같게  표현한다고 볼 수 있다.

잘라내기 영역이 이 텍스쳐 좌표를 결정하는데 중요한 영향을 미치는데 별도로 설정하지 않는 경우에는 일반적으로 모두 다 표기되게 처리를 하나 만약 잘라내기 영역을 설정할 경우, 각각 left,right,top,bottom에 잘라낼 비율을 설정할 수 있다.(쉽게 sourceRectangle.Left / texture.Width 와 같은 형식으로 비율을 맞춰 출력을 하게 된다.)

Left와 Right, Top과 Bottom의 위치가 바뀔 경우 좌우, 상하 반전 효과를 적용할 수 있게 된다.

destinationRectangle 매개변수를 전달받은 메서드들은 축소 비율을 무시하고 destinationRectangle에서 받은 값으로 처리를 하게 된다.이것은

scale 인자는 2종류가 있는데, 하나는 float이고 하나는 Vector2 형식이다. float형식은 가로, 세로를 동일한 비율로 바꿔주게 되고, Vector2는 각각 설정이 가능하다.

이에 대해 자세히 알아보고 싶으면 MSDN을 참조하기 바란다. Matrix부분에 대한 것은 본인이 3D에 대한 지식이 미약하여 헛된 정보를 전하지 않을까 하여 생략하도록 하겠다.^^;

다음에는 문자 출력에 대해 한 번 자세히 알아보도록 하겠다.^^

Posted by TY
,