在纹理上绘制后使用渲染目标作为纹理

更新页 :
页面创建日期 :

验证环境

窗户
  • 视窗 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);
}

当您运行它时,它应该在旋转时绘制,如图所示。