Most efficient way to draw a colored square (no, really!)

Yeah I know, this sounds really lame... I've actually got textures, input, sound, physics and a bunch of other stuff working, but I have to conclude that the method I'm using to draw a starkly colored square is murderously inefficient.

I can add 50 textured squares to my scene and lose maybe 40 frames per second... but adding 20 colored squares to my scene kills about 600 frames per second... from a human standpoint, this makes no sense, since a textured object is much more intricate than a red square, so I'm obviously doing something really bad somewhere.

The lowdown on how I'm drawing these "squares" is that I create a D3D texture from my chosen color using this code:

protected D3D.Texture ColorToTexture( D3D.Device graphics, Color color )
{
if (color.A == 0)
return null;

Bitmap bmp = new Bitmap( 1, 1 );
Graphics osg = Graphics.FromImage( bmp );
osg.Clear( color );

MemoryStream loMS = new MemoryStream();
bmp.Save( loMS, System.Drawing.Imaging.ImageFormat.Bmp );
loMS.Seek( 0, 0 );
return D3D.TextureLoader.FromStream( graphics, loMS );
}

I then use this texture to render the square:

_sprite.Draw( _texture,
new Rectangle( 0, 0, (int)width, (int)height ),
new Vector3( 0.0f, 0.0f, 0.0f ),
new Vector3( (float)_left, (float)_top, 0.0f ),
Color.FromArgb( 255, 255, 255, 255 ) );

Each colored square is an object. I should also mention that each colored square has a black "texture"; I use it with code snippit number two 4 times to draw a black border around the square.

I have no idea if I've given enough information, or if I've already said enough to give experienced DirectX programmers heart palpitations... the good news is that I'm eager to learn, so if you have any input I'd greatly appreciate it!




Answer this question

Most efficient way to draw a colored square (no, really!)

  • sirck sirck

    I'll have a look at these flags; thank you!

  • Vipin.B

    Yes thats another flag you can set that will change the way the sprites get sorted and batched.

  • EricN

    When you create a Sprite you call .begin then you do all your .draw calls as many as you want, then call .end. D3DX batches all the sprites up into as few real draw calls as possible when you get the .end

    If all your sprite.draw calls use the same texture then this can end up as a single draw call to the graphics card. If you use multiple textures then when you create the sprite object you can specify certain flags so to help the sprite object optimize how it will sort and batch things.



  • Keith Henkel

    Well, I gave the static texture idea a try, and saved about 50 frames per second... of course, every little bit helps, but it looks like that wasn't my biggest concern.

    Anything else What's this batching thing you mentioned earlier



  • Jim Fox

    Nah, I'm not stupid enough to be initializing graphics in my render loop. However, I don't know anything about batching or SortByTexture, so I'd presume that I'm not doing it.

    I will give your "single white texture" idea a try, though, it doesn't sound too hard to implement and it ought to be as simple as creating a static texture when my program first loads...



  • Barb O

    Does the SetDepthFrontToBack flag have anything to do with what you were talking about

  • Chris Jiang

    Given your code your 'colored' square is also a textured square, its just a very small texture of a singel color.

    Hopefully you are not calling the ColorToTexture routine within the render loop - that wouldn't help.

    Hopefully you are batching all of your calls into a single sprite batch and you have set the SortByTexture flag when you created it - otherwise all of the texture swaps will cause a slowdown.

    Also there's no need to have multiple colored textures is you make a single white pixel texture, then vary the Color parameter at the end of the sprite.draw call you can change the color of that texture to whatever you want. Then they are all using the same texture and they can all be drawn in one go.



  • Most efficient way to draw a colored square (no, really!)