Notes on SpeedThere are a few things you should do to make sure this all goes as quickly as possible. First of all, locking a surface is not the fastest thing in the world, so you should try to keep the number of times you lock a surface per frame to a minimum. For many things, including a simple pixel-plotting demo, one lock per frame is all you'll need. Second, let's say you're working in 640x480x16. The pitch will almost always be 1,280 bytes. You still need to take into consideration that it might not always be that way, but you may want to add some optimized code to take advantage of the fact that the pitch will almost always be 1,280. More specifically, you can use a pixel-plotting function that uses bit shifts instead of multiplication to locate the correct pixel. The function we were using earlier used this line of code: buffer[y*nPitch + x] = color; We can speed that up if we know nPitch is going to be 640 (since nPitch is in USHORTs, not bytes). 640 isn't a power of two, but 512 is 2^9, and 128 is 2^7. And guess what? 512 + 128 = 640. :) Convenient, hey? The line above will execute just a tad faster if we use this instead: buffer[(y<<9) + (y<<7) + x] = color; Most resolutions you'll use have widths that are either powers of two, or a sum of two powers of two. No such luck if you're in 800x600 (512 + 256 + 32 = 800), but it's a good trick to keep in mind. Bit shifts are some of the fastest operations you could ask for. Finally, if you are going to be using two functions -- one using multiplication, and the other using bit-shifts -- keep the comparison outside of the plotting loop. That is, don't do this: for (x=0; x<1000; x++) { if (nPitch == 640) PlotPixelFast16(); else PlotPixel16(); } Putting the decision statement inside the loop is just detracting from the advantage you gain with the fast function. Do it this way instead: if (nPitch == 640) { for (x=0; x<1000; x++) PlotPixelFast16( parameters ); } else { for (x=0; x<1000; x++) PlotPixel16( parameters ); } Make sense? Whenever you've got a big for loop, keep as much as you can on the outside of it. There's no sense in making a calculation a thousand times that's going to come up the same way every time. :) Also, if you're going to be plotting pixels in such a way that the locations are in a pattern, like a horizontal or vertical line (or even a diagonal one), there's no need to re-calculate the location every time. Look at this example, for drawing a line of randomly colored pixels: for (x=0; x<640; x++) PlotPixel16(x, 50, color, buffer, pitch); The function is re-calculating the correct line every time, when all you need to do is advance the pointer by one each time. This is a faster way of doing it: // get the address of the line USHORT* temp = &buffer[50*pitch]; // plot the pixels for (x=0; x<640; x++) { *temp = color; temp++; } None of these things are going to make a huge difference in your program's speed unless you're plotting thousands and thousands of pixels each frame -- which you might be doing -- but even if not, it's always good policy to make any little optimization you can find, no matter how insignificant it seems. Considering how long the previous articles in this series have been, stopping this one here would seem like kind of a rip-off, wouldn't it? Now that we know how to plot pixels, let's take a look at some of the things you can use it for. |
|