Использование RenderTarget в качестве текстуры после рисования на текстуре

Страница обновлена :
Дата создания страницы :

Среда верификации

Виндоус
  • Windows 10
  • Windows 11
Visual Studio
  • Visual Studio 2022
Моноигра
  • 3.8.1

О целевых объектах рендеринга

Обычно при рисовании содержимое чертежа отображается на экране, но для записи рисунка в текстуру можно использовать целевой объект рендеринга. Содержимое, записанное в текстуре, можно использовать как текстуру, как она есть. Например, если записать содержимое телевизора в текстуру, а затем вставить текстуру на экран телевизора, можно переместить другое изображение в телевизоре. Конечно, его также можно использовать в качестве неподвижного изображения, и вы можете создавать текстуру динамически, не подготавливая заранее файл изображения для текстуры.

Подготовка изображений

Вам не нужен файл изображения, чтобы использовать цель рендеринга, но я подготовлю файл изображения, чтобы его было легче понять в качестве примера.

Он будет использоваться как обычный файл содержимого, поэтому, пожалуйста, зарегистрируйте его в MGCB. Texture Оставьте имя как .

поле

Game1 Давайте напишем это в классе. Существующий код не будет изменен в частности, поэтому я опишу только добавленную сумму, не описывая ее.

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

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

_texture Поля предназначены для загрузки подготовленных изображений и не имеют особого отношения к содержанию этого совета.

RenderTarget2D Поля, определенные в классе, становятся целевыми объектами рендеринга. Поскольку необходимо GraphicsDevice создать экземпляр , он не может быть создан на данном этапе, поэтому он только определен.

Конструктор 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);
}

Во-первых, ознакомьтесь с использованием Texture2D Content.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);
}

Когда вы запускаете его, он должен рисовать при вращении, как показано на рисунке.