3
\$\begingroup\$

If I wanted to fill my game screen with individually coloured pixels, how would I do this?

For example, if I wanted to write a 'game of life'-type game where each pixel was a cell, how would I achieve this using XNA?

I've tried just calling SetData() on a Texture2D object using a screen-sized array of Color values, but it complains with:

You may not call SetData on a resource while
it is actively set on the GraphicsDevice.
Unset it from the device before calling SetData.

How do I do as it asks? Or better still... is there an alternative, better, efficient way to fill a screen with arbitrary pixels?

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Perhaps you are doing the SetData between SpriteBatch.Begin and SpriteBatch.End calls? \$\endgroup\$
    – r2d2rigo
    Dec 23, 2010 at 14:08
  • \$\begingroup\$ @r2d2rigo: Answers should be answers, not comments, so I can really upvote that. \$\endgroup\$
    – user744
    Dec 23, 2010 at 15:24
  • \$\begingroup\$ Afraid not. The linked answer below leads to this - GraphicsDevice.Textures[0] = null; - which makes the texture inacvtive on the device, but why index 0 is a mystery. \$\endgroup\$
    – izb
    Dec 23, 2010 at 15:28
  • \$\begingroup\$ @Joe: It was just a question, see izb's response telling that he wasn't doing it. It wasn't an answer per se, just asking for some info about how did he code it. \$\endgroup\$
    – r2d2rigo
    Dec 23, 2010 at 17:53

2 Answers 2

5
\$\begingroup\$

It sounds like the texture is still selected into the GraphicsDevice (or at the very least in use still as the GPU is allowed to lag behind the CPU to achieve the best performance). I've not really used XNA so I can't really speak to the exact nature of that error.

However, if you do this with a single texture and managed to fix the above problem you would most likely incur a costly peformance bottleneck which requires the CPU to sit around waiting for the GPU to finish using that texture before it can lock it again (the CPU would be blocked from continuing until it could lock the texture knowing it was safe to do so). A better solution would be to create two textures and double-buffer their usage, so you write to Texture 1, then render with it, the next frame write to Texture 2 instead, render with it, switch back to Texture 1 again, etc. That way you can ensure the GPU won't be using the texture still and should also solve the problem you have now.

\$\endgroup\$
1
  • \$\begingroup\$ That's great, can you link to any examples of double-buffered textures used in this way? \$\endgroup\$
    – izb
    Jan 5, 2011 at 14:27
0
\$\begingroup\$

For drawing lines and such I've just used a 1x1 white texture and scaled/rotated it. Not sure if that will be any faster, but it is an option

pixel = new Texture2D(graphicsDevice, 1, 1);
pixel.SetData<Color>(new Color[1] { Color.White });
\$\endgroup\$
2
  • \$\begingroup\$ Four vertices - or even one 2D vertex - is way more data than you would be sending by re-uploading a texture. \$\endgroup\$
    – user744
    Dec 23, 2010 at 22:49
  • \$\begingroup\$ If you do this, don't forget to release it. I made a TextureManager to hold static references for generated images and images pulled from external APIs that the content manager doesn't handle. \$\endgroup\$
    – person27
    May 8, 2019 at 4:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .