Я думаю, что я в корне неправильно понимаю, как работают цели рендеринга. Насколько я понимаю, RenderTargets - это просто текстуры, к которым обращается вызов spritebatch draw.
Поэтому я попробовал этот код для рендеринга окон графического интерфейса, чтобы убедиться, что они могут рисовать только в своей клиентской области и обрезать ее за ее пределами.
for (int i = Controls.Count - 1; i >= 0; i--)
{
RenderTarget2D oldTarget;
if (graphics.GetRenderTargets().Count() == 0) oldTarget = null;
else oldTarget = (RenderTarget2D)graphics.GetRenderTargets()[0].RenderTarget; // Get the old target being used.
graphics.SetRenderTarget(canvas); //set the target to a temporary RT
graphics.Clear(Color.Black); // Clear it
Control c = Controls[i]; // Get the current control (a form in this case)
c.Draw(spriteBatch, gameTime); // Draw it to the temp RT
graphics.SetRenderTarget(oldTarget); // Set the RT back to the main RT
Vector2 dest = c.DrawCoOrds(); // Gets the draw coordinates of the control
spriteBatch.Begin();
spriteBatch.Draw(canvas, new Rectangle((int)dest.X, (int)dest.Y, c.Bounds.Width, c.Bounds.Height), new Rectangle((int)dest.X, (int)dest.Y, c.Bounds.Width, c.Bounds.Height), Color.White);
// take the rect from the temp RT and draw it to the main RT.
spriteBatch.End();
}
Однако этот код рисует только последнюю форму в списке, что означает, что он должен каким-то образом очищать основной RT, но я не понимаю, почему. Я вызываю clear только тогда, когда RT установлен на временный холст.
2 ответа
Я думаю, что лучший способ рисовать элементы управления gui - это ScissorRectangle, потому что позволяет рисовать только внутри этого прямоугольника, который может быть клиентской областью элемента управления gui.
MSDN: GraphicsDevice.ScissorRectangle
Вам необходимо включить эту функциональность через RasterizerState.
RasterizerState ScissorState = new RasterizerState()
{
ScissorTestEnabled = true;
}
Прежде чем рисовать, вызовите SpriteBatch. Начните с этого состояния.
Видео с моим собственным графическим интерфейсом, работающим на xbox360 :)
Как вы создали цель рендеринга и задний буфер? По умолчанию вы не можете писать в цель рендеринга несколько раз после перехода на другую цель рендеринга. Вот почему:
http://blogs.msdn.com/b/shawnhar/archive/2007/11/21/rendertarget-changes-in-xna-game-studio-2-0.aspx
Вы можете изменить поведение по умолчанию, создав целевые объекты рендеринга с помощью RenderTargetUsage.PreserveContents.
, а задний буфер, переопределив GraphicsDeviceManager.PrepareDeviceSettings.
, изменив GraphicsDeviceInformation.PresentationParameters.RenderTargetUsage
, как описано в ссылке. Хотя я считаю, что переопределение этих настроек в XNA 4 выполняется по-другому.
При этом изменение поведения по умолчанию связано с соображениями производительности и не рекомендуется. Вы должны найти способ сделать это по-другому. Одна из возможностей - создать отдельную цель рендеринга для каждого из ваших окон, нарисовать их все, переключиться на задний буфер и нарисовать цели рендеринга к нему.
Лучшим вариантом было бы использовать состояние растеризатора прямоугольных ножниц, предложенное @Blau.
Похожие вопросы
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.