在紋理上繪製後使用渲染目標作為紋理

更新頁 :
頁面創建日期 :

驗證環境

窗戶
  • 視窗 10
  • 視窗 11
視覺工作室
  • 視覺工作室 2022
單博
  • 3.8.1

關於渲染目標

通常,繪製時,繪圖內容會顯示在螢幕上,但您可以使用呈現器目標將繪圖寫入紋理。 紋理中寫入的內容可以按原樣用作紋理。 例如,如果將電視的內容寫入紋理,然後將紋理粘貼到電視螢幕上,則可以在電視中移動其他圖像。 當然,它也可以用作靜止圖像,您可以動態創建紋理,而無需事先為紋理準備圖像檔。

準備映像

使用呈現器目標不需要圖像檔,但我將準備一個圖像檔,以便作為範例更易於理解。

它將用作普通內容檔,因此請在MGCB中註冊。 Texture 將名稱保留為 。

Game1 讓我們在課堂上寫它。 現有的代碼不會特別改變,所以我只會描述添加的數量而不描述它。

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

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

_texture 這些欄位用於載入準備好的圖像,與本提示的內容並不特別相關。

RenderTarget2D 類中定義的欄位將成為呈現目標。 由於需要 GraphicsDevice 實例化,因此在此階段無法創建它,因此僅對其進行定義。

遊戲 1 構造函數

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使用 .

GraphicsDevice 如果有 RenderTarget2D ,您可以在任何地方生成它,但在示例中,我們將在方法中創建 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);
}

當您運行它時,它應該在旋轉時繪製,如圖所示。