Použití RenderTarget jako textury po nakreslení textury

Stránky aktualizovány :
Datum vytvoření stránky :

Ověřovací prostředí

Windows
  • Systém Windows 10
  • Systém Windows 11
Visual Studio
  • Visual Studio 2022
MonoGame
  • 3.8.1

O cílech vykreslení

Obvykle se při kreslení zobrazí obsah výkresu na obrazovce, ale k zápisu výkresu na texturu můžete použít cíl vykreslení. Obsah napsaný v textuře lze použít jako texturu tak, jak je. Pokud například zapíšete obsah televizoru do textury a potom texturu vložíte na televizní obrazovku, můžete v televizoru přesunout jiný obraz. Samozřejmě jej lze také použít jako statický obraz a můžete vytvořit texturu dynamicky bez předchozí přípravy obrazového souboru pro texturu.

Příprava obrázků

K použití cíle vykreslení nepotřebujete obrazový soubor, ale připravím obrazový soubor, aby byl srozumitelnější jako ukázka.

Bude použit jako soubor s normálním obsahem, proto jej prosím zaregistrujte v MGCB. Texture Název ponechte jako .

pole

Game1 Napišme to ve třídě. Stávající kód se nijak zvlášť měnit nebude, takže budu popisovat pouze přidanou částku, aniž bych ji popisoval.

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

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

_texture Pole slouží k načítání připravených obrázků a nejsou pro obsah tohoto tipu nijak zvlášť relevantní.

RenderTarget2D Pole definovaná ve třídě se stanou cíli vykreslení. Vzhledem k tomu, že je nutné GraphicsDevice vytvořit instanci , nelze ji v této fázi vytvořit, takže je pouze definována.

Game1 – konstruktor

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

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

Není zde nic zvláštního. Prozatím jsem upřesnil rozlišení hry tak, aby se dala porovnat s cílem renderu.

LoadContent

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

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

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

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

Nejprve si přečtěte použití Texture2D Content.Load pro kreslení pomocí .

GraphicsDevice Pokud existuje RenderTarget2D , můžete ji vygenerovat kdekoliv, ale v příkladu ji vytvoříme v LoadContent metodě. Cíl vykreslení je skutečná textura, takže má velikost. Konstruktor GraphicsDevice také určuje velikost spolu s .

Remíza

Pokud použijete cíl vykreslení, je zde hlavní kód.

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);
}

Vzhledem k tomu, že kreslení se v podstatě GraphicsDevice provádí na , i když je proces kreslení prováděn tak, jak je, bude vykreslen proti hlavnímu oknu. GraphicsDevice.SetRenderTarget Zadáním RenderTarget2D metody můžete přepnout cíl výkresu na texturu.

Po přepnutí se proces kreslení provádí stejným způsobem jako při kreslení v hlavním okně. GraphicsDevice.Clear Vymaže informace o výkresu a nakreslíSpriteBatch pohyblivý symbol. Abych zkontroloval, zda skutečně kreslíte proti textuře, záměrně jsem určil kreslicí pozici tak, aby skřítek tentokrát vyčníval.

Po dokončení kreslení do cíle GraphicsDevice.SetRenderTarget vykreslení určete metodu null . To vám umožní vrátit cíl výkresu do hlavního okna.

RenderTarget2D lze použít jako texturu tak, jak je, takže SpriteBatch.Draw upřesňuji _renderTarget způsob, jak ji nakreslit jako sprite.

poprava

Jakmile napíšete kód, zkuste ho spustit. Pokud to vypadá jako obrázek, je to v pořádku.

Barva výplně pro cíl vykreslení a barva výplně pro hlavní okno jsou odděleny, takže můžete vidět, kde byla textura vytvořena jako cíl vykreslení. Nakreslil jsem skřítka tak, aby vyčníval proti cíli renderu, ale myslím, že je vidět, že je správně oříznutý a není nakreslen směrem k hlavnímu oknu.

To je veškerý kód, který dosahuje cíle vykreslení. Není nic zvlášť obtížného. Myslím, že jediná věc, na které mi záleží, je řízení přepínání cílů kreslení a RenderTarget2D správa .

Zkuste ho přesunout

Výsledek předchozího provedení vypadá, že obrázek je jednoduše oříznut a nakreslen, takže Dále bych chtěl přesunout sprite, abych se ujistil, že je správně nakreslen v cíli renderu.

Update Protože chceme rotaci pokaždé aktualizovat, připravíme úhel natočení v poli.

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

Update V metodě zvyšte _rotate počet .

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 Metoda nastaví pohyblivý symbol na _rotate rotaci. Stačí vědět, že se otáčí, takže ostatní hodnoty jsou nastaveny správně.

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);
}

Když jej spustíte, měl by kreslit při otáčení, jak je znázorněno na obrázku.