Použití RenderTarget jako textury po nakreslení textury
Ověřovací prostředí
- Windows
-
- Systém Windows 10
- Systém Windows 11
- Visual Studio
-
- Visual Studio 2022
- MonoGame
-
- 3.8.1
O cílech vykreslení
Obvykle se při kreslení zobrazí obsah výkresu na obrazovce, ale k zápisu výkresu na texturu můžete použít cíl vykreslení. Obsah napsaný v textuře lze použít jako texturu tak, jak je. Pokud například zapíšete obsah televizoru do textury a potom texturu vložíte na televizní obrazovku, můžete v televizoru přesunout jiný obraz. Samozřejmě jej lze také použít jako statický obraz a můžete vytvořit texturu dynamicky bez předchozí přípravy obrazového souboru pro texturu.
Příprava obrázků
K použití cíle vykreslení nepotřebujete obrazový soubor, ale připravím obrazový soubor, aby byl srozumitelnější jako ukázka.
Bude použit jako soubor s normálním obsahem, proto jej prosím zaregistrujte v MGCB. Texture
Název ponechte jako .
pole
Game1
Napišme to ve třídě. Stávající kód se nijak zvlášť měnit nebude, takže budu popisovat pouze přidanou částku, aniž bych ji popisoval.
<summary>描画するテクスチャー画像。</summary>
private Texture2D _texture;
<summary>描画対象となるレンダーターゲット。</summary>
private RenderTarget2D _renderTarget;
_texture
Pole slouží k načítání připravených obrázků a nejsou pro obsah tohoto tipu nijak zvlášť relevantní.
RenderTarget2D
Pole definovaná ve třídě se stanou cíli vykreslení.
Vzhledem k tomu, že je nutné GraphicsDevice
vytvořit instanci , nelze ji v této fázi vytvořit, takže je pouze definována.
Game1 – konstruktor
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
// ゲームの解像度の設定
_graphics.PreferredBackBufferWidth = 1280;
_graphics.PreferredBackBufferHeight = 720;
}
Není zde nic zvláštního. Prozatím jsem upřesnil rozlišení hry tak, aby se dala porovnat s cílem renderu.
LoadContent
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: this.Content を使用してゲーム コンテンツをここに読み込みます
// コンテンツからテクスチャーを読み込みます
_texture = Content.Load<Texture2D>("Texture");
_renderTarget = new RenderTarget2D(GraphicsDevice, 540, 360);
}
Nejprve si přečtěte použití Texture2D
Content.Load
pro kreslení pomocí .
GraphicsDevice
Pokud existuje RenderTarget2D
, můžete ji vygenerovat kdekoliv, ale v příkladu ji vytvoříme v LoadContent
metodě.
Cíl vykreslení je skutečná textura, takže má velikost. Konstruktor GraphicsDevice
také určuje velikost spolu s .
Remíza
Pokud použijete cíl vykreslení, je zde hlavní kód.
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);
}
Vzhledem k tomu, že kreslení se v podstatě GraphicsDevice
provádí na , i když je proces kreslení prováděn tak, jak je, bude vykreslen proti hlavnímu oknu.
GraphicsDevice.SetRenderTarget
Zadáním RenderTarget2D
metody můžete přepnout cíl výkresu na texturu.
Po přepnutí se proces kreslení provádí stejným způsobem jako při kreslení v hlavním okně.
GraphicsDevice.Clear
Vymaže informace o výkresu a nakreslíSpriteBatch
pohyblivý symbol.
Abych zkontroloval, zda skutečně kreslíte proti textuře, záměrně jsem určil kreslicí pozici tak, aby skřítek tentokrát vyčníval.
Po dokončení kreslení do cíle GraphicsDevice.SetRenderTarget
vykreslení určete metodu null
.
To vám umožní vrátit cíl výkresu do hlavního okna.
RenderTarget2D
lze použít jako texturu tak, jak je, takže SpriteBatch.Draw
upřesňuji _renderTarget
způsob, jak ji nakreslit jako sprite.
poprava
Jakmile napíšete kód, zkuste ho spustit. Pokud to vypadá jako obrázek, je to v pořádku.
Barva výplně pro cíl vykreslení a barva výplně pro hlavní okno jsou odděleny, takže můžete vidět, kde byla textura vytvořena jako cíl vykreslení. Nakreslil jsem skřítka tak, aby vyčníval proti cíli renderu, ale myslím, že je vidět, že je správně oříznutý a není nakreslen směrem k hlavnímu oknu.
To je veškerý kód, který dosahuje cíle vykreslení. Není nic zvlášť obtížného.
Myslím, že jediná věc, na které mi záleží, je řízení přepínání cílů kreslení a RenderTarget2D
správa .
Zkuste ho přesunout
Výsledek předchozího provedení vypadá, že obrázek je jednoduše oříznut a nakreslen, takže Dále bych chtěl přesunout sprite, abych se ujistil, že je správně nakreslen v cíli renderu.
Update
Protože chceme rotaci pokaždé aktualizovat, připravíme úhel natočení v poli.
<summary>テクスチャーを回転させる角度。</summary>
private float _rotate;
Update
V metodě zvyšte _rotate
počet .
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
Metoda nastaví pohyblivý symbol na _rotate
rotaci.
Stačí vědět, že se otáčí, takže ostatní hodnoty jsou nastaveny správně.
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);
}
Když jej spustíte, měl by kreslit při otáčení, jak je znázorněno na obrázku.