5
\$\begingroup\$

I've been messing around with C++ the last few days and I'm trying to figure out how to draw the screen pixel by pixel each frame.

It sounded simple enough at first, but then I realized for loops during the games main loop is nothing but a slow mess. How do I safely and with speed show visual effects?

\$\endgroup\$
  • \$\begingroup\$ I don't understand your point about the sin function, and the relate issue concerning "it's not my method, since I use the standard method" is not answerable without your implementation details, so I removed them. Feel free to add them back if you can clarify them appropriately. \$\endgroup\$ – Josh Mar 17 '15 at 16:29
5
\$\begingroup\$

Per-pixel rendering operations are not particularly efficient on modern hardware. In the past, on classic game consoles and older PCs, they could be made usefully efficient because you had direct access to video RAM. On modern machines this is no longer the case.

Consequently, if you want to do per-pixel manipulation efficiently, you are better off constructing your own in-memory buffer of the pixel data (something as simple as a char * pointing at a buffer of 4 * width * height bytes, assuming you want four-component RGBA pixels) and directly manipulating that.

At the conclusion of every frame, you then use a modern, efficient method to render this buffer to the screen. Typically, these days, that would involve updating a GPU texture with your pixel buffer and rendering a fullscreen quad with that texture mapped accordingly.

Further, when actually manipulating the pixels, it's better not to actually set each pixel individually, if possible. Most of the time you'll be rendering objects that consist of more than one pixel, and in those cases you should use specialized routines to blit the data. Focus on accessing the memory of the destination buffer (and source buffer, if you are copying a sprite) in a cache-coherent fashion. Copy entire rows of data when possible (for opaque sprites, for example, you can memcpy the rows of the sprite).

Another technique commonly used when doing this kind of thing is to use "dirty rectangles," that is, tracking which regions have changed and only re-rendering those (the previous frame bounds of a sprite, the current frame bounds of a sprite, for example -- or their union if they overlap, as they commonly will). This will generally also involve keeping a separate buffer containing all the static background imagery in a scene, so you can then (for each dirty rectangle), blit the appropriate portion of the background into the rectangle, then do the appropriate foreground drawing.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.