Używanie elementu RenderTarget jako tekstury po narysowaniu na teksturze
Środowisko weryfikacji
- Windows
-
- Okna 10
- Okna 11
- Visual Studio
-
- Visual Studio 2022
- MonoGame
-
- 3.8.1
Informacje o obiektach docelowych renderowania
Zwykle podczas rysowania zawartość rysunku jest wyświetlana na ekranie, ale można użyć celu renderowania, aby zapisać rysunek do tekstury. Zawartość zapisana w teksturze może być używana jako tekstura taka, jaka jest. Jeśli na przykład zawartość telewizora zostanie zapisana w teksturze, a następnie wkleisz ją na ekranie telewizora, możesz przenieść inny obraz w telewizorze. Oczywiście może być również używany jako nieruchomy obraz i można dynamicznie tworzyć teksturę bez wcześniejszego przygotowywania pliku obrazu dla tekstury.
Przygotowywanie obrazów
Nie potrzebujesz pliku obrazu, aby użyć celu renderowania, ale przygotuję plik obrazu, aby ułatwić zrozumienie go jako przykład.
Będzie używany jako zwykły plik treści, więc zarejestruj go w MGCB. Texture
Pozostaw nazwę jako .
pole
Game1
Napiszmy to w klasie. Istniejący kod nie zostanie zmieniony w szczególności, więc opiszę tylko dodaną kwotę bez jej opisywania.
<summary>描画するテクスチャー画像。</summary>
private Texture2D _texture;
<summary>描画対象となるレンダーターゲット。</summary>
private RenderTarget2D _renderTarget;
_texture
Pola służą do ładowania przygotowanych obrazów i nie są szczególnie istotne dla treści tej wskazówki.
RenderTarget2D
Pola zdefiniowane w klasie stają się celami renderowania.
Ponieważ konieczne GraphicsDevice
jest utworzenie instancji , nie można go utworzyć na tym etapie, więc jest tylko zdefiniowany.
Konstruktor Game1 —
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
// ゲームの解像度の設定
_graphics.PreferredBackBufferWidth = 1280;
_graphics.PreferredBackBufferHeight = 720;
}
Nie ma tu nic specjalnego do zrobienia. Na razie określiłem rozdzielczość gry, aby można ją było porównać z celem renderowania.
LoadContent
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: this.Content を使用してゲーム コンテンツをここに読み込みます
// コンテンツからテクスチャーを読み込みます
_texture = Content.Load<Texture2D>("Texture");
_renderTarget = new RenderTarget2D(GraphicsDevice, 540, 360);
}
Najpierw przeczytaj użycie Texture2D
Content.Load
do rysowania za pomocą .
GraphicsDevice
Jeśli jest RenderTarget2D
, możesz go wygenerować w dowolnym miejscu, ale w przykładzie utworzymy go w LoadContent
metodzie.
Cel renderowania jest prawdziwą teksturą, więc ma rozmiar. Konstruktor GraphicsDevice
określa również rozmiar wraz z .
Rysować
Jeśli używasz celu renderowania, kod tutaj jest główny.
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);
}
Ponieważ rysowanie jest zasadniczo GraphicsDevice
wykonywane na , nawet jeśli proces rysowania jest wykonywany tak, jak jest, zostanie narysowany w głównym oknie.
GraphicsDevice.SetRenderTarget
Określając metodę RenderTarget2D
, można przełączyć miejsce docelowe rysowania na teksturę.
Po przełączeniu proces rysowania odbywa się w taki sam sposób, jak podczas rysowania w oknie głównym.
GraphicsDevice.Clear
Usuwa informacje o rysunku i rysujeSpriteBatch
duszka.
Aby sprawdzić, czy rzeczywiście rysujesz na tle tekstury, celowo określiłem pozycję rysowania, aby tym razem duszek wystawał.
Po zakończeniu rysowania do celu GraphicsDevice.SetRenderTarget
renderowania określ metodę null
.
Umożliwia to powrót celu rysunkowego do okna głównego.
RenderTarget2D
może być używany jako tekstura taka, jaka jest, więc SpriteBatch.Draw
określam _renderTarget
metodę rysowania jej jako duszka.
egzekucja
Po napisaniu kodu spróbuj go uruchomić. Jeśli wygląda jak rysunek, jest OK.
Kolor wypełnienia dla celu renderowania i kolor wypełnienia dla okna głównego są rozdzielone, dzięki czemu można zobaczyć, gdzie tekstura została utworzona jako cel renderowania. Narysowałem duszka tak, aby wystawał w kierunku celu renderowania, ale myślę, że widać, że jest odpowiednio przycięty i nie jest rysowany w kierunku głównego okna.
To cały kod, który osiąga cel renderowania. Nie ma nic szczególnie trudnego.
Myślę, że jedyne, na czym mi zależy, to zarządzanie przełączaniem miejsc docelowych rysowania i RenderTarget2D
zarządzanie .
Spróbuj go przenieść
Wynik poprzedniego wykonania wygląda tak, jakby obraz został po prostu przycięty i narysowany, więc Następnie chciałbym przenieść duszka, aby upewnić się, że jest poprawnie narysowany w celu renderowania.
Update
Ponieważ chcemy za każdym razem aktualizować rotację, przygotujemy kąt obrotu w terenie.
<summary>テクスチャーを回転させる角度。</summary>
private float _rotate;
Update
W metodzie zwiększ _rotate
liczbę plików .
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 ustawia ikonkę do _rotate
obracania.
Musisz tylko wiedzieć, że się obraca, więc inne wartości są odpowiednio ustawione.
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);
}
Po uruchomieniu powinien rysować podczas obracania, jak pokazano na rysunku.