RenderTarget gebruiken als een structuur na het tekenen op een structuur

Pagina bijgewerkt :
Aanmaakdatum van pagina :

Verificatieomgeving

Ramen
  • Windows 10
  • Voor Windows 11
Visual Studio
  • Visual Studio 2022
Monospel
  • 3.8.1

Informatie over renderdoelen

Normaal gesproken wordt de tekeninginhoud tijdens het tekenen op het scherm weergegeven, maar u kunt een renderdoel gebruiken om de tekening naar een structuur te schrijven. De inhoud die in de textuur is geschreven, kan worden gebruikt als een textuur zoals deze is. Als u bijvoorbeeld de inhoud van de tv naar een structuur schrijft en de structuur vervolgens op het tv-scherm plakt, kunt u een ander beeld in de tv verplaatsen. Natuurlijk kan het ook worden gebruikt als een stilstaand beeld en kunt u dynamisch een textuur maken zonder van tevoren een afbeeldingsbestand voor de textuur voor te bereiden.

Afbeeldingen voorbereiden

U hebt geen afbeeldingsbestand nodig om het renderdoel te gebruiken, maar ik zal een afbeeldingsbestand voorbereiden om het gemakkelijker te begrijpen als een voorbeeld.

Het zal worden gebruikt als een normaal inhoudsbestand, dus registreer het in MGCB. Texture Laat de naam staan als .

veld

Game1 Laten we het in de klas schrijven. De bestaande code zal niet in het bijzonder worden gewijzigd, dus ik zal alleen het toegevoegde bedrag beschrijven zonder het te beschrijven.

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

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

_texture De velden zijn voor het laden van de voorbereide afbeeldingen en zijn niet bijzonder relevant voor de inhoud van deze tip.

RenderTarget2D Velden die in de klasse zijn gedefinieerd, worden renderdoelen. Omdat het nodig is om te GraphicsDevice instantiëren , kan het in dit stadium niet worden gemaakt, dus het is alleen gedefinieerd.

Game1 constructeur

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

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

Er is hier niets bijzonders te doen. Vooralsnog heb ik de resolutie van het spel gespecificeerd zodat het vergeleken kan worden met het renderdoel.

LoadContent

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

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

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

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

Lees eerst het gebruik Texture2D Content.Load voor tekenen met .

GraphicsDevice Als dat zo is RenderTarget2D , kunt u het overal genereren, maar in het voorbeeld maken we het in LoadContent de methode. Het renderdoel is een echte textuur, dus het heeft een grootte. De GraphicsDevice constructor specificeert ook de grootte samen met .

Tekenen

Als u een renderdoel gebruikt, is de code hier de belangrijkste.

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

Omdat tekenen in principe GraphicsDevice wordt uitgevoerd op , zelfs als het tekenproces wordt uitgevoerd zoals het is, wordt het tegen het hoofdvenster getekend. GraphicsDevice.SetRenderTarget Door een methode op te geven, kunt u de tekenbestemming wijzigen in een RenderTarget2D structuur.

Na het schakelen wordt het tekenproces op dezelfde manier uitgevoerd als bij het tekenen in het hoofdvenster. GraphicsDevice.Clear wist de tekeninginformatie en tekentSpriteBatch de sprite. Om te controleren of je echt tegen de textuur aan tekent, heb ik bewust de tekenpositie zo opgegeven dat de sprite deze keer uitsteekt.

Wanneer u klaar bent met tekenen naar het renderdoel, GraphicsDevice.SetRenderTarget geeft u de null methode op. Hiermee kunt u het tekendoel terugzetten naar het hoofdvenster.

RenderTarget2D kan worden gebruikt als een textuur zoals het is, dus SpriteBatch.Draw ik specificeer de _renderTarget methode om het als een sprite te tekenen.

uitvoering

Nadat u de code hebt geschreven, probeert u deze uit te voeren. Als het op de figuur lijkt, is het OK.

De vulkleur voor het renderdoel en de vulkleur voor het hoofdvenster worden gescheiden, zodat u kunt zien waar de structuur is gemaakt als renderdoel. Ik heb de sprite zo getekend dat hij tegen het renderdoel uitsteekt, maar ik denk dat je kunt zien dat hij goed is geknipt en niet naar het hoofdvenster is getekend.

Dat is alle code die het renderdoel bereikt. Er is niets bijzonder moeilijks. Ik denk dat het enige waar ik om geef, het beheren van het wisselen van tekenbestemmingen en RenderTarget2D het beheren van .

Probeer het te verplaatsen

Het resultaat van de vorige uitvoering ziet eruit alsof de afbeelding eenvoudig is bijgesneden en getekend, dus Vervolgens wil ik de sprite verplaatsen om ervoor te zorgen dat deze correct in het renderdoel wordt getekend.

Update Omdat we de rotatie elke keer willen bijwerken, zullen we de rotatiehoek in het veld voorbereiden.

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

Update Verhoog in de methode het _rotate aantal .

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 De methode stelt de sprite in om te _rotate roteren. U hoeft alleen maar te weten dat het roteert, dus de andere waarden zijn op de juiste manier ingesteld.

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

Wanneer u het uitvoert, moet het tekenen tijdens het draaien zoals weergegeven in de afbeelding.