Порядок отображения RenderTargets в XNA - PullRequest
0 голосов
/ 30 августа 2011

Мне кажется, я в корне не понимаю, как работают цели. В моем понимании RenderTargets - это просто текстуры, на которые рисует вызовы spritebatch.

Итак, я попробовал этот код для рендеринга окон графического интерфейса, чтобы убедиться, что они могут рисовать только в своей клиентской области, и она обрезается за пределами этого.

 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 ]

0 голосов
/ 30 августа 2011

Как вы создали цель рендеринга и обратный буфер? По умолчанию вы не можете писать в цель рендеринга несколько раз после перехода на другую цель рендеринга. Вот почему:

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.

0 голосов
/ 30 августа 2011

Я думаю, что лучший способ рисовать элементы управления графическим интерфейсом - это ScissorRectangle, поскольку позволяет рисовать только внутри этого прямоугольника, который может быть клиентской областью элемента управления графического интерфейса.

MSDN: GraphicsDevice.ScissorRectangle

Вам необходимо включить эту функцию через RasterizerState.

 RasterizerState ScissorState = new RasterizerState() 
 { 
     ScissorTestEnabled = true; 
 }

Перед рисованием вызовите SpriteBatch.Begin с этим состоянием.

Видеомоего собственного графического интерфейса, работающего в xbox360:)

...