Redraw unchanging background on every Draw?
Asked Answered
P

2

4

This might be a very simple question, but I searched and found no other way to do it. It doesn't make sense to redraw the background on every Draw. Is there a way to draw some things and leave them on the screen?

I've tried to comment-out the

GraphicsDevice.Clear(Color.CornflowerBlue);

But that doesn't help. (What is its purpose?)

Peahen answered 3/6, 2013 at 19:57 Comment(2)
Wait - are you saying that your XNA game clears the screen even if you comment out the GraphicsDevice.Clear line? Or are you asking why clear the screen at all if you're going to redraw the whole screen every frame?Pirouette
@ananthonline Yup. It clears the screen even when it's commented out. The only difference is the background color. But even if it would stop clearing the screen - I'd still be looking for something like: ClearForeground();.Peahen
T
3

The dark purple colour you are seeing is used by XNA and DirectX to indicate an uninitialised buffer. XNA will also clear buffers to this colour to emulate the behaviour of the Xbox 360 or Windows Phone, so that if you build a game on Windows, it "just works" on those other platforms (or, rather, so it fails in the same way, so you can debug it).

XNA is double-buffered. You don't draw directly to the screen, but to a "backbuffer". The screen only displays the "front buffer". Every time GraphicsDevice.Present gets called (Game calls it for you in EndDraw), those two buffers get swapped, and what you were drawing gets displayed (and you get a fresh buffer to draw on).

I'm not sure why XNA marks the buffer as uninitialised when it gets swapped. I haven't come across this behaviour before - mostly because it's very unusual to want to swap buffers and preserve their contents.

Usually what you want to do is call Game.SupressDraw, when you know you're not going to modify the contents of the screen (saving both a call to Draw and a swap). See also answers here and here.

Keep in mind that clearing the screen with GraphicsDevice.Clear is extremely fast. And that XNA has no concept of "background" or "foreground" (you're always drawing on top of whatever is already in the buffer).

If you do have some expensive-to-render content that you want to re-use between frames, generally you would draw it into to a render target once, and then draw that to the screen each frame. But, as always, avoid premature optimisation! Graphics cards are designed specifically to redraw scenes every frame - they're pretty damn fast!

Tarrsus answered 4/6, 2013 at 5:51 Comment(5)
Thanks. And especially for "render target". A note, though, (but please correct me if I'm wrong.) - Though graphics cards might be very fast - much of the computation isn't for rendering but rather for calculating. For example - calculating the pixels for a circle using Math.Sin etc. - those aren't done by the graphics card.Peahen
@Peahen The answer to that is very much "it depends". Ideally you'll offload as much of that processing to the GPU as possible (eg: a circle can be calculated as x^2 + y^2 < 1 in a pixel shader). And ideally static models will be sent to the GPU once (as a vertex buffer) and left unchanged in GPU memory.Tarrsus
But take care not to prematurely optimise - which is basically any optimisation without having measurements that you are slow (as compared to some benchmark - like 60fps on target hardware) and why you are slow (what part of your program is the slowest). Otherwise you might find you spent a lot of time optimising away Math.Sin (actually pretty damn fast), only to find that you're actually spending all your time submitting batches or something.Tarrsus
Is there a way to copy the current frame onto the back buffer and start from there, to keep the contents?Siward
To get that effect, use a render target instead of the backbuffer.Tarrsus
G
0

See this, if you want to just prevent it clearing the image you can do:

GraphicsDevice.GetType().GetField("lazyClearFlags", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(GraphicsDevice, ClearOptions.DepthBuffer);
Gatha answered 3/6, 2013 at 23:50 Comment(2)
I wonder if this is to support the emulation of the Xbox's clearing behaviour on Windows (see here). You probably shouldn't need to mess with it.Tarrsus
(Although a little testing reveals that setting PreserveContents doesn't fix it - so it's not an Xbox thing.)Tarrsus

© 2022 - 2024 — McMap. All rights reserved.