การใช้ RenderTarget เป็นพื้นผิวหลังจากวาดบนพื้นผิว

ปรับปรุงหน้า :
วันที่สร้างเพจ :

สภาพแวดล้อมการตรวจสอบ

หน้าต่าง
  • หน้าต่าง 10
  • หน้าต่าง 11
วิชวลสตูดิโอ
  • Visual Studio 2022
โมโนเกม
  • 3.8.1

เกี่ยวกับ Render Targets

โดยปกติเมื่อคุณวาดเนื้อหาการวาดภาพจะปรากฏบนหน้าจอ แต่คุณสามารถใช้เป้าหมายการแสดงผลเพื่อเขียนภาพวาดไปยังพื้นผิวได้ เนื้อหาที่เขียนในพื้นผิวสามารถใช้เป็นพื้นผิวได้เหมือนเดิม ตัวอย่างเช่น ถ้าหากท่านเขียนคอนเทนท์ของทีวีลงในพื้นผิวแล้ววางพื้นผิวนั้นลงบนหน้าจอทีวี ท่านก็จะย้ายภาพอื่นในทีวีนั้นได้ แน่นอนว่ามันยังสามารถใช้เป็นภาพนิ่งและคุณสามารถสร้างพื้นผิวแบบไดนามิกโดยไม่ต้องเตรียมไฟล์ภาพสําหรับพื้นผิวล่วงหน้า

การเตรียมภาพ

คุณไม่จําเป็นต้องมีไฟล์ภาพเพื่อใช้เป้าหมายการแสดงผล แต่ฉันจะเตรียมไฟล์ภาพเพื่อให้ง่ายต่อการเข้าใจเป็นตัวอย่าง

มันจะถูกใช้เป็นไฟล์เนื้อหาปกติดังนั้นโปรดลงทะเบียนใน MGCB Texture ทิ้งชื่อไว้เป็น .

สนาม

Game1 ลองเขียนไว้ในชั้นเรียน รหัสที่มีอยู่จะไม่เปลี่ยนแปลงโดยเฉพาะดังนั้นฉันจะอธิบายจํานวนเงินที่เพิ่มโดยไม่ต้องอธิบายเท่านั้น

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

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

_texture ฟิลด์นี้มีไว้สําหรับโหลดรูปภาพที่เตรียมไว้และไม่เกี่ยวข้องกับเนื้อหาของเคล็ดลับนี้เป็นพิเศษ

RenderTarget2D ฟิลด์ที่กําหนดไว้ในชั้นเรียนจะกลายเป็นเป้าหมายการแสดงผล เนื่องจากมีความจําเป็นต้อง GraphicsDevice สร้าง instantiate จึงไม่สามารถสร้างได้ในขั้นตอนนี้ดังนั้นจึงมีการกําหนดเท่านั้น

ตัวสร้าง Game1

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

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

ไม่มีอะไรพิเศษที่ต้องทําที่นี่ ในขณะนี้ฉันได้ระบุความละเอียดของเกมเพื่อให้สามารถเปรียบเทียบกับเป้าหมายการแสดงผลได้

โหลดเนื้อหา

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

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

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

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

ก่อนอื่นให้อ่านการใช้งานTexture2DContent.Loadสําหรับการวาดภาพด้วย

GraphicsDeviceRenderTarget2D หากมี คุณสามารถสร้างได้ทุกที่ แต่ในตัวอย่างเราจะสร้างมันในLoadContentวิธีการ เป้าหมายการแสดงผลเป็นพื้นผิวจริงดังนั้นจึงมีขนาด ตัวGraphicsDeviceสร้างยังระบุขนาดพร้อมกับ .

วาด

หากคุณใช้เป้าหมายการแสดงผลรหัสที่นี่เป็นรหัสหลัก

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

GraphicsDeviceแม้ว่ากระบวนการวาดภาพจะดําเนินการตามที่เป็นอยู่ก็ตามมันจะถูกวาดกับหน้าต่างหลัก GraphicsDevice.SetRenderTargetโดยการระบุRenderTarget2Dวิธีการคุณสามารถเปลี่ยนปลายทางการวาดภาพเป็นพื้นผิว

หลังจากเปลี่ยนกระบวนการวาดภาพจะดําเนินการในลักษณะเดียวกับเมื่อวาดในหน้าต่างหลัก GraphicsDevice.Clear ล้างข้อมูลการวาดภาพและวาดSpriteBatch สไปรท์ เพื่อตรวจสอบว่าคุณกําลังวาดกับพื้นผิวจริงๆหรือไม่ฉันจงใจระบุตําแหน่งการวาดภาพเพื่อให้สไปรท์ยื่นออกมาในครั้งนี้

เมื่อคุณวาดภาพไปยังเป้าหมายการแสดงผลเสร็จแล้วให้ GraphicsDevice.SetRenderTarget ระบุ null วิธีการ สิ่งนี้ช่วยให้คุณสามารถส่งคืนเป้าหมายการวาดภาพไปยังหน้าต่างหลัก

RenderTarget2D สามารถใช้เป็นพื้นผิวได้เหมือนเดิมดังนั้นฉันจึง SpriteBatch.Draw ระบุ _renderTarget วิธีการวาดเป็นสไปรท์

การประหารชีวิต

เมื่อคุณเขียนรหัสแล้ว ให้ลองเรียกใช้ ถ้าดูเหมือนรูปก็โอเค

สีเติมสําหรับเป้าหมายการแสดงผลและสีเติมสําหรับหน้าต่างหลักจะถูกแยกออกจากกันเพื่อให้คุณสามารถดูว่าพื้นผิวถูกสร้างขึ้นที่ใดเป็นเป้าหมายการเรนเดอร์ ฉันวาดสไปรท์เพื่อให้มันยื่นออกมากับเป้าหมายการแสดงผล แต่ฉันคิดว่าคุณจะเห็นว่ามันถูกตัดอย่างถูกต้องและไม่วาดไปทางหน้าต่างหลัก

นั่นคือรหัสทั้งหมดที่บรรลุเป้าหมายการเรนเดอร์ ไม่มีอะไรยากเป็นพิเศษ ฉันคิดว่าสิ่งเดียวที่ฉันสนใจคือการจัดการการเปลี่ยนจุดหมายปลายทางการวาดภาพและการจัดการRenderTarget2D

ลองย้ายมัน

ผลลัพธ์ของการดําเนินการก่อนหน้านี้ดูเหมือนว่าภาพจะถูกครอบตัดและวาดดังนั้น ต่อไปฉันต้องการย้ายสไปรท์เพื่อให้แน่ใจว่ามันถูกวาดอย่างถูกต้องในเป้าหมายการแสดงผล

Update เนื่องจากเราต้องการอัปเดตการหมุนทุกครั้งเราจะเตรียมมุมการหมุนในสนาม

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

Update ในวิธีการเพิ่ม _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 วิธีการตั้งค่าสไปรท์ให้ _rotate หมุน คุณเพียงแค่ต้องรู้ว่ามันหมุนดังนั้นค่าอื่น ๆ จึงถูกตั้งค่าอย่างเหมาะสม

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

เมื่อคุณเรียกใช้มันควรจะวาดในขณะที่หมุนดังที่แสดงในรูป