Using RenderTarget as a texture after drawing on a texture
Verification environment
- Windows
-
- Windows 10
- Windows 11
- Visual Studio
-
- Visual Studio 2022
- MonoGame
-
- 3.8.1
About Render Targets
Normally, when you draw, the drawing content is displayed on the screen, but you can use a render target to write the drawing to a texture. The contents written in the texture can be used as a texture as it is. For example, if you write the contents of the TV to a texture and then paste the texture to the TV screen, you can move a different image in the TV. Of course, it can also be used as a still image, and you can create a texture dynamically without preparing an image file for the texture in advance.
Preparing Images
You don't need an image file to use the render target, but I'll prepare an image file to make it easier to understand as a sample.
It will be used as a normal content file, so please register it in MGCB. Texture
Leave the name as .
field
Game1
Let's write it in the class. The existing code will not be changed in particular, so I will only describe the added amount without describing it.
<summary>描画するテクスチャー画像。</summary>
private Texture2D _texture;
<summary>描画対象となるレンダーターゲット。</summary>
private RenderTarget2D _renderTarget;
_texture
The fields are for loading the prepared images and are not particularly relevant to the content of this tip.
RenderTarget2D
Fields defined in the class become render targets.
Since it is necessary to GraphicsDevice
instantiate , it cannot be created at this stage, so it is only defined.
Game1 constructor
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
// ゲームの解像度の設定
_graphics.PreferredBackBufferWidth = 1280;
_graphics.PreferredBackBufferHeight = 720;
}
There is nothing special to do here. For the time being, I have specified the resolution of the game so that it can be compared with the render target.
LoadContent
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: this.Content を使用してゲーム コンテンツをここに読み込みます
// コンテンツからテクスチャーを読み込みます
_texture = Content.Load<Texture2D>("Texture");
_renderTarget = new RenderTarget2D(GraphicsDevice, 540, 360);
}
First, read the use Texture2D
Content.Load
for drawing with .
GraphicsDevice
If there is RenderTarget2D
, you can generate it anywhere, but in the example we will create it in LoadContent
the method.
The render target is a real texture, so it has a size. The GraphicsDevice
constructor also specifies the size along with .
Draw
If you use a render target, the code here is the main one.
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);
}
Since drawing is basically GraphicsDevice
performed on , even if the drawing process is performed as it is, it will be drawn against the main window.
GraphicsDevice.SetRenderTarget
By specifying a RenderTarget2D
method, you can switch the drawing destination to a texture.
After switching, the drawing process is performed in the same way as when drawing in the main window.
GraphicsDevice.Clear
clears the drawing information and drawsSpriteBatch
the sprite.
In order to check whether you are really drawing against the texture, I deliberately specified the drawing position so that the sprite protrudes this time.
When you have finished drawing to the render target, GraphicsDevice.SetRenderTarget
specify the null
method.
This allows you to return the drawing target to the main window.
RenderTarget2D
can be used as a texture as it is, so SpriteBatch.Draw
I specify the _renderTarget
method to draw it as a sprite.
execution
Once you've written the code, try running it. If it looks like the figure, it is OK.
The fill color for the render target and the fill color for the main window are separated, so you can see where the texture was created as the render target. I drew the sprite so that it protrudes against the render target, but I think you can see that it is properly clipped and not drawn towards the main window.
That's all the code that achieves the render target. There is nothing particularly difficult.
I think the only thing I care about is managing the switching of drawing destinations and RenderTarget2D
managing .
Try moving it
The result of the previous execution looks like the image is simply cropped and drawn, so Next, I would like to move the sprite to make sure that it is properly drawn in the render target.
Update
Since we want to update the rotation every time, we will prepare the rotation angle in the field.
<summary>テクスチャーを回転させる角度。</summary>
private float _rotate;
Update
In the method, increase the _rotate
number of .
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
The method sets the sprite to _rotate
rotate.
You only need to know that it is rotating, so the other values are set appropriately.
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);
}
When you run it, it should draw while rotating as shown in the figure.