RenderTarget'ı doku üzerinde çizim yaptıktan sonra doku olarak kullanma

Sayfa güncel :
Sayfa oluşturma tarihi :

Doğrulama ortamı

Windows
  • Pencereler 10
  • Pencereler 11
Görsel Stüdyo
  • Visual Studio 2022
MonoGame
  • 3.8.1

İşleme Hedefleri Hakkında

Normalde, çizim yaptığınızda, çizim içeriği ekranda görüntülenir, ancak çizimi bir dokuya yazmak için bir işleme hedefi kullanabilirsiniz. Dokuya yazılan içerikler olduğu gibi doku olarak kullanılabilir. Örneğin, TV'nin içeriğini bir dokuya yazıp ardından dokuyu TV ekranına yapıştırırsanız, TV'de farklı bir görüntüyü taşıyabilirsiniz. Tabii ki, hareketsiz görüntü olarak da kullanılabilir ve doku için önceden bir görüntü dosyası hazırlamadan dinamik olarak bir doku oluşturabilirsiniz.

Görüntüleri Hazırlama

İşleme hedefini kullanmak için bir görüntü dosyasına ihtiyacınız yok, ancak örnek olarak anlaşılmasını kolaylaştırmak için bir görüntü dosyası hazırlayacağım.

Normal bir içerik dosyası olarak kullanılacaktır, bu nedenle lütfen MGCB'ye kaydedin. Texture Adı olarak bırakın.

alan

Game1 Sınıfa yazalım. Mevcut kod özellikle değiştirilmeyecek, bu yüzden sadece eklenen miktarı açıklamadan açıklayacağım.

/// <summary>描画するテクスチャー画像。</summary>
private Texture2D _texture;

/// <summary>描画対象となるレンダーターゲット。</summary>
private RenderTarget2D _renderTarget;

_texture Alanlar, hazırlanan görüntüleri yüklemek içindir ve bu ipucunun içeriğiyle özellikle alakalı değildir.

RenderTarget2D Sınıfta tanımlanan alanlar işleme hedefleri haline gelir. Örneklemek GraphicsDevice gerekli olduğu için , bu aşamada oluşturulamaz, bu yüzden sadece tanımlanır.

Game1 oluşturucu

public Game1()
{
  _graphics = new GraphicsDeviceManager(this);
  Content.RootDirectory = "Content";
  IsMouseVisible = true;

  // ゲームの解像度の設定
  _graphics.PreferredBackBufferWidth = 1280;
  _graphics.PreferredBackBufferHeight = 720;
}

Burada yapılacak özel bir şey yok. Şimdilik, render hedefiyle karşılaştırılabilmesi için oyunun çözünürlüğünü belirttim.

LoadContent

protected override void LoadContent()
{
  _spriteBatch = new SpriteBatch(GraphicsDevice);

  // TODO: this.Content を使用してゲーム コンテンツをここに読み込みます

  // コンテンツからテクスチャーを読み込みます
  _texture = Content.Load<Texture2D>("Texture");

  _renderTarget = new RenderTarget2D(GraphicsDevice, 540, 360);
}

İlk olarak, ile çizim için kullanımı Texture2D Content.Load okuyun.

GraphicsDevice Varsa RenderTarget2D , herhangi bir yerde oluşturabilirsiniz, ancak örnekte yöntemde LoadContent oluşturacağız. Oluşturma hedefi gerçek bir dokudur, bu nedenle bir boyutu vardır. Oluşturucu GraphicsDevice ayrıca boyutu ile birlikte belirtir.

Çizmek

Bir oluşturma hedefi kullanırsanız, buradaki kod ana koddur.

protected override void Draw(GameTime gameTime)
{
  // TODO: ここに描画コードを追加します

  // 描画先対象をレンダーターゲットに設定
  GraphicsDevice.SetRenderTarget(_renderTarget);

  // テクスチャーの情報をクリアし単色で塗りつぶします
  GraphicsDevice.Clear(Color.LightYellow);

  // スプライトバッチを使用してスプライトを書き込みます
  // レンダーターゲットの外に影響ないことを確認するためにわざと領域をはみ出るように描画しています
  _spriteBatch.Begin();
  for (int i = 0; i < 4; i++)
  {
    _spriteBatch.Draw(_texture, new Vector2((i / 2) * 200 - 50, (i % 2) * 200 - 50), Color.White);
  }
  _spriteBatch.End();

  // レンダーターゲットを解除します。これ以降の描画処理はメインウインドウに対して行われます
  GraphicsDevice.SetRenderTarget(null);

  // メインウィンドウの描画情報をクリアし単色で塗りつぶします
  GraphicsDevice.Clear(Color.CornflowerBlue);

  // メインウィンドウに対してレンダーターゲットをテクスチャーとして描画します
  _spriteBatch.Begin();
  _spriteBatch.Draw(_renderTarget, new Vector2(100, 100), Color.White);
  _spriteBatch.End();

  base.Draw(gameTime);
}

Çizim temel olarak GraphicsDevice , üzerinde gerçekleştirildiği için, çizim işlemi olduğu gibi yapılsa bile, ana pencereye karşı çizilecektir. GraphicsDevice.SetRenderTarget Bir RenderTarget2D yöntem belirterek, çizim hedefini bir dokuya değiştirebilirsiniz.

Anahtarlamadan sonra, çizim işlemi ana pencerede çizim yaparken olduğu gibi gerçekleştirilir. GraphicsDevice.Clear çizim bilgilerini temizler ve hareketli grafiği çizerSpriteBatch . Dokuya karşı gerçekten çizim yapıp yapmadığınızı kontrol etmek için, çizim pozisyonunu kasıtlı olarak belirttim, böylece hareketli grafik bu sefer çıkıntı yapar.

İşleme hedefine çizimi bitirdiğinizde, GraphicsDevice.SetRenderTarget yöntemi belirtin null . Bu, çizim hedefini ana pencereye döndürmenizi sağlar.

RenderTarget2D olduğu gibi bir doku olarak kullanılabilir, bu yüzden SpriteBatch.Draw hareketli grafik olarak çizme yöntemini belirtiyorum _renderTarget .

idam

Kodu yazdıktan sonra çalıştırmayı deneyin. Figüre benziyorsa, sorun değil.

İşleme hedefinin dolgu rengi ve ana pencerenin dolgu rengi ayrılır, böylece dokunun oluşturma hedefi olarak nerede oluşturulduğunu görebilirsiniz. Hareketli grafiği, render hedefine doğru çıkıntı yapacak şekilde çizdim, ancak düzgün bir şekilde kırpıldığını ve ana pencereye doğru çizilmediğini görebildiğinizi düşünüyorum.

Oluşturma hedefine ulaşan tüm kod budur. Özellikle zor bir şey yok. Sanırım umursadığım tek şey, çizim hedeflerinin değiştirilmesini yönetmek ve RenderTarget2D yönetmek.

Taşımayı deneyin

Önceki yürütmenin sonucu, görüntünün basitçe kırpılmış ve çizilmiş gibi görünüyor, bu nedenle Ardından, render hedefinde düzgün bir şekilde çizildiğinden emin olmak için hareketli grafiği taşımak istiyorum.

Update Rotasyonu her seferinde güncellemek istediğimiz için sahadaki dönüş açısını hazırlayacağız.

/// <summary>テクスチャーを回転させる角度。</summary>
private float _rotate;

Update Yöntemde, sayısını artırın _rotate .

protected override void Update(GameTime gameTime)
{
  if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
    Exit();

  // TODO: ここに更新ロジックを追加します

  // テクスチャーの回転角度を更新します
  _rotate += 0.01f;

  base.Update(gameTime);
}

Draw Yöntem, hareketli grafiği döndürülecek şekilde _rotate ayarlar. Sadece döndüğünü bilmeniz gerekir, bu nedenle diğer değerler uygun şekilde ayarlanır.

protected override void Draw(GameTime gameTime)
{
  // 中略

  // スプライトバッチを使用してスプライトを書き込みます
  // レンダーターゲットの外に影響ないことを確認するためにわざと領域をはみ出るように描画しています
  _spriteBatch.Begin();
  for (int i = 0; i < 4; i++)
  {
    _spriteBatch.Draw(_texture, new Vector2((i / 2) * 200 + 32, (i % 2) * 200 + 32),
      null, Color.White, _rotate * i, new Vector2(64, 64), 1, SpriteEffects.None, 0);
  }
  _spriteBatch.End();

  // 中略

  // メインウィンドウに対してレンダーターゲットをテクスチャーとして描画します
  _spriteBatch.Begin();
  _spriteBatch.Draw(_renderTarget, new Vector2(400, 400), null, Color.White,
    _rotate, new Vector2(_renderTarget.Width / 2, _renderTarget.Height / 2), 1, SpriteEffects.None, 0);
  _spriteBatch.End();

  base.Draw(gameTime);
}

Çalıştırdığınızda, şekilde gösterildiği gibi dönerken çizmelidir.