Layer Parameters를 사용하여 Sprite 컨텍스트 만들기

페이지 업데이트 :
페이지 생성 날짜 :

요약

레이어의 depth 값을 사용하여 스프라이트의 컨텍스트를 지정합니다.

レイヤーパラメータを使用してスプライトの前後関係を作る

운영 환경

필수 구성 요소

지원되는 XNA 버전
  • 2.0
  • 3.0
  • 3.1
  • 4.0
지원되는 플랫폼
  • Windows(XP SP2 이상, Vista, 7)
  • 엑스박스 360
  • 윈도우 폰 7
Windows 필수 버텍스 셰이더 버전 2.0
Windows 필수 픽셀 셰이더 버전 2.0

운영 환경

플랫폼
  • 윈도우 7
  • 엑스박스 360
  • Windows Phone 7 에뮬레이터

물질

일반적으로 스프라이트를 그릴 때는 나중에 그리는 것이 눈앞에 오도록 그려지지만, 뎁스 값으로 정렬하면 SpriteBatch.Draw 메서드가 호출되는 순서에 관계없이 컨텍스트를 명확하게 할 수 있습니다.

스프라이트 뎁스 값을 기준으로 정렬하려면 "SpriteBatch.Begin" 메서드의 첫 번째 인수로 "SpriteSortMode.BackToFront"를 지정합니다. 뒷면의 스프라이트에서 끌어와 전경의 스프라이트를 덮어쓰는 처리 방법입니다.

// 一つでも半透明、透明要素があるスプライトの場合はこちらの引数を使用
this.spriteBatch.Begin(SpriteSortMode.BackToFront, null);

그러나 반투명하거나 투명 요소가 전혀 없는 스프라이트만 그리려면 다음을 지정하여 더 빠르게 그릴 수 있습니다.

// 深度バッファを使用して前後関係を有効にし描画するように指定
// 完全な不透明スプライトのみ描画する場合はこちらが高速
this.spriteBatch.Begin(SpriteSortMode.FrontToBack,
                       BlendState.Opaque,
                       null,
                       DepthStencilState.Default,
                       null);

네 번째 인수는 "DepthStencilState.Default"로, 스프라이트가 그려질 때 각 픽셀에 "깊이" 정보도 씁니다. 깊이 정보를 기록할 때 해당 위치 이후에 그릴 개체(픽셀 단위)를 작성할 필요가 없다고 판단할 수 있으므로 그리기 비용이 크게 절감됩니다.

위와 같은 이유로 스프라이트를 먼저 전경에 그리면 뒤에 겹치는 스프라이트의 그리기 비용이 줄어들기 때문에 전경에서 그리는 첫 번째 인수로 "SpriteSortMode.FrontToBack"을 지정하여 앞에서 그리도록 정렬합니다.

그러나 이것은 완전히 무시할 수 있는 색상 요소가 뒤에 있는 불투명 스프라이트를 그릴 때만 유용합니다. 반투명 또는 불투명 스프라이트의 경우 반투명 또는 투명 픽셀이라도 각 픽셀에 깊이 값이 기록되기 때문에 정면에서 그리면 뒤에 있는 스프라이트는 표시되지 않습니다. 이것이 캐릭터 드로잉에서 "SpriteSortMode.BackToFront"를 지정하는 이유입니다. (텍스트의 형태 이외의 픽셀은 투명하기 때문에)

덧붙여서, 내 환경에서 30,000 개의 스프라이트를 그리는 테스트 결과, 뎁스 값을 사용하여 정면에서 그리는 것이 뒤에서 그리는 것보다 약 3 배 빠르다고 했습니다. 물론 그리는 시트의 수나 겹치는 정도, 크기 등, 실행 환경에 따라 다르기 때문에 꼭 직접 시험해 보세요.

SpriteBatch.Begin 메서드

스프라이트를 그리기 전에 호출하십시오. 내부적으로는 스프라이트를 그리는 데 필요한 설정을 하고 있습니다.

정렬모드 스프라이트 정렬 모드 SpriteSortMode 열거형에서 스프라이트를 가져오는 순서를 지정합니다. 뒤에서 그리려면 SpriteSortMode.BackToFront를 지정합니다. 정면에서 그리려면 SpriteSortMode.FrontToBack을 지정합니다.
블렌드 스테이트 블렌드 스테이트 그릴 스프라이트의 색상을 배경색과 혼합하는 방법. 기본적으로 BlendState.AlphaBlend 가 지정되지만 이 경우 그릴 스프라이트가 완전히 불투명하므로 배경색을 고려하지 않고 BlendState.Opaque 가 지정됩니다.
샘플러 상태 샘플러 상태 텍스처를 샘플링하는 방법. null이 지정되면 기본 SamplerState.LinearClamp가 지정됩니다.
depthStencilState DepthStencilState (영문) 깊이 스텐실 버퍼를 사용하는 방법을 지정합니다. null을 지정하면 깊이 스텐실 버퍼를 사용하지 않는 DepthStencilState.None이 사용됩니다. 깊이 스텐실 버퍼를 사용하려면 DepthStencilState.Default를 지정합니다.
래스터라이저 상태 래스터라이저 상태 역 컬링과 같은 래스터화 방법을 지정합니다. null을 지정하면 기본 RasterizerState.CullCounterClockwise가 지정됩니다.

스프라이트를 그리려면 SpriteBatch.Draw 메서드에 대한 아홉 번째 인수로 깊이 값을 지정합니다. 여기서 설정할 수 있는 값은 0.0~1.0 사이이며, 0.0이 맨 앞, 1.0이 맨 뒤에 있습니다.

// 最背面に描画(赤)
this.spriteBatch.Draw(this.texture, new Vector2(150.0f, 50.0f), null,
    Color.Red, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f);

// 最前面に描画(緑)
this.spriteBatch.Draw(this.texture, new Vector2(110.0f, 90.0f), null,
    Color.Green, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.0f);

// 2つのスプライトの間に描画(青)
this.spriteBatch.Draw(this.texture, new Vector2(190.0f, 130.0f), null,
    Color.Blue, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);

SpriteBatch.Draw 메서드

스프라이트 드로잉 배치 목록에 스프라이트를 추가합니다.

텍스처 텍스처2D 스프라이트로 표시할 텍스처를 지정합니다.
위치 벡터2 스프라이트가 표시되어야 하는 위치입니다. 화면의 왼쪽 상단을 기준으로 화면 좌표를 지정합니다. 스프라이트의 원점은 왼쪽 상단에 있습니다.
sourceRectangle (영문) Nullable<Rectangle입니다> 텍스처의 전송 영역을 지정합니다. 전체 텍스처를 스프라이트로 표시하려면 null을 지정할 수 있습니다. 이 매개 변수를 지정하면 임의의 영역만 스프라이트로 표시되도록 할 수 있습니다.
스프라이트의 색에 곱할 색을 지정합니다. Color.White를 지정하면 스프라이트의 기본 색상으로 표시됩니다. Color.Black을 지정하면 스프라이트는 색상에 관계없이 전체 검정색으로 표시됩니다. 공식은 "결과 = 스프라이트 색상 * 색상"입니다.
회전 뜨다 스프라이트의 회전 각도입니다. 단위는 라디안으로 지정됩니다. 회전축은 스프라이트의 왼쪽 상단에 있습니다.
기원 벡터2 스프라이트를 회전할 때 회전축의 위치를 지정합니다. 스프라이트의 어느 위치가 회전축이 될지 지정하지만, 실제로는 회전축의 위치가 스프라이트의 왼쪽 상단에 고정되고 스프라이트의 표시 위치는 -origin만큼 이동합니다.
저울 뜨다 스프라이트의 배율을 지정합니다. 1.0을 기준으로 세로 및 가로로 크기를 조정합니다. 확대의 원점은 스프라이트의 왼쪽 상단 모서리에 있습니다.
효과 스프라이트 이펙트 스프라이트의 반전 효과를 지정합니다. 다른 작업을 수행하지 않으면 SpriteEffects.None을 지정합니다.
layerDepth (레이어깊이) 뜨다 스프라이트가 표시되는 깊이를 지정합니다. 주로 전경과 후면에 스프라이트를 표시하는 데 사용됩니다. 0.0~1.0 범위로 지정하며, 0.0은 앞면, 1.0은 뒷면입니다.

위 프로그램에서는 SpriteBatch.Draw 메소드를 "red", "green", "blue" 순으로 호출하지만, 각 depth 값은 "red (1.0)", "green (0.0)", "blue (0.5)"로 설정되어 있기 때문에 뒤쪽은 빨강, 전경은 초록색이 그려져 있는 것을 볼 수 있다.

深度値を使用したスプライトの描画

모든 코드

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
#if WINDOWS_PHONE
using Microsoft.Xna.Framework.Input.Touch;
#endif

namespace LayerDepthSprite
{
    /// <summary>
    /// ゲームメインクラス
    /// </summary>
    public class GameMain : Microsoft.Xna.Framework.Game
    {
        /// <summary>
        /// グラフィックデバイス管理クラス
        /// </summary>
        private GraphicsDeviceManager graphics = null;

        /// <summary>
        /// スプライトのバッチ化クラス
        /// </summary>
        private SpriteBatch spriteBatch = null;

        /// <summary>
        /// テクスチャー
        /// </summary>
        private Texture2D texture = null;


        /// <summary>
        /// GameMain コンストラクタ
        /// </summary>
        public GameMain()
        {
            // グラフィックデバイス管理クラスの作成
            this.graphics = new GraphicsDeviceManager(this);

            // ゲームコンテンツのルートディレクトリを設定
            this.Content.RootDirectory = "Content";

#if WINDOWS_PHONE
            // Windows Phone のデフォルトのフレームレートは 30 FPS
            this.TargetElapsedTime = TimeSpan.FromTicks(333333);

            // バックバッファサイズの設定
            this.graphics.PreferredBackBufferWidth = 480;
            this.graphics.PreferredBackBufferHeight = 800;

            // フルスクリーン表示
            this.graphics.IsFullScreen = true;
#endif
        }

        /// <summary>
        /// ゲームが始まる前の初期化処理を行うメソッド
        /// グラフィック以外のデータの読み込み、コンポーネントの初期化を行う
        /// </summary>
        protected override void Initialize()
        {
            // TODO: ここに初期化ロジックを書いてください

            // コンポーネントの初期化などを行います
            base.Initialize();
        }

        /// <summary>
        /// ゲームが始まるときに一回だけ呼ばれ
        /// すべてのゲームコンテンツを読み込みます
        /// </summary>
        protected override void LoadContent()
        {
            // テクスチャーを描画するためのスプライトバッチクラスを作成します
            this.spriteBatch = new SpriteBatch(this.GraphicsDevice);

            // テクスチャーをコンテンツパイプラインから読み込む
            this.texture = this.Content.Load<Texture2D>("Texture");
        }

        /// <summary>
        /// ゲームが終了するときに一回だけ呼ばれ
        /// すべてのゲームコンテンツをアンロードします
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: ContentManager で管理されていないコンテンツを
            //       ここでアンロードしてください
        }

        /// <summary>
        /// 描画以外のデータ更新等の処理を行うメソッド
        /// 主に入力処理、衝突判定などの物理計算、オーディオの再生など
        /// </summary>
        /// <param name="gameTime">このメソッドが呼ばれたときのゲーム時間</param>
        protected override void Update(GameTime gameTime)
        {
            // Xbox 360 コントローラ、Windows Phone の BACK ボタンを押したときに
            // ゲームを終了させます
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                this.Exit();
            }

            // TODO: ここに更新処理を記述してください

            // 登録された GameComponent を更新する
            base.Update(gameTime);
        }

        /// <summary>
        /// 描画処理を行うメソッド
        /// </summary>
        /// <param name="gameTime">このメソッドが呼ばれたときのゲーム時間</param>
        protected override void Draw(GameTime gameTime)
        {
            // 画面を指定した色でクリアします
            this.GraphicsDevice.Clear(Color.CornflowerBlue);

            // 深度バッファを使用して前後関係を有効にし描画するように指定
            // 完全な不透明スプライトのみ描画する場合はこちらが高速
            this.spriteBatch.Begin(SpriteSortMode.FrontToBack,
                                   BlendState.Opaque,
                                   null,
                                   DepthStencilState.Default,
                                   null);

            // 一つでも半透明、透明要素があるスプライトの場合はこちらの引数を使用
            //this.spriteBatch.Begin(SpriteSortMode.BackToFront, null);

            // 最背面に描画(赤)
            this.spriteBatch.Draw(this.texture, new Vector2(150.0f, 50.0f), null,
                Color.Red, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f);

            // 最前面に描画(緑)
            this.spriteBatch.Draw(this.texture, new Vector2(110.0f, 90.0f), null,
                Color.Green, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.0f);

            // 2つのスプライトの間に描画(青)
            this.spriteBatch.Draw(this.texture, new Vector2(190.0f, 130.0f), null,
                Color.Blue, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);

            // スプライトの一括描画
            this.spriteBatch.End();

            // 登録された DrawableGameComponent を描画する
            base.Draw(gameTime);
        }
    }
}