开发者

RenderTargets draw order in XNA

I think I am fundamentally misunderstanding the way render targets work. In my understanding RenderTargets are just Textures that the spritebatch draw calls draw to.

So I tried this code to render GUI windows in order to make sure they can only draw in their client area and its cropped outside that.

 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)开发者_C百科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();
        }

However this code only draws the last form in the list which means it must be clearing the main RT somehow but i dont understand why. I only call clear when the RT is set to the temp canvas.


i think the best method to draw gui controls is with ScissorRectangle, because lets draw only inside that rectangle, that can be the client area of the gui control.

MSDN: GraphicsDevice.ScissorRectangle

You need to enable this funcionality through a RasterizerState.

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

Before you draw, call SpriteBatch.Begin with this state.

A video of my own gui running in a xbox360 :)


How did you create your render target and back buffer? By default you can't write to a render target multiple times after changing to a different render target. This is why:

http://blogs.msdn.com/b/shawnhar/archive/2007/11/21/rendertarget-changes-in-xna-game-studio-2-0.aspx

You can change the default behavior by creating your render targets with RenderTargetUsage.PreserveContents., and the back buffer by overriding GraphicsDeviceManager.PrepareDeviceSettings., changing GraphicsDeviceInformation.PresentationParameters.RenderTargetUsage, as described in the link. Although I believe overriding those settings is done differently in XNA 4.

All that being said, changing away from the default behavior has performance considerations, and is not recommended. You should find a way to do this differently. One possibility would be to create a separate render target for each of your windows, draw all of them, switch to the back buffer and draw the render targets to it.

A better option would be to use the scissor rectangle rasterizer state as proposed by @Blau.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜