3
\$\begingroup\$

I want to add pixel splatters and particle effects to a game. For this my options were to have a bunch of pre-made animations in the form of textures, OR create a particle engine.

For the particle engine approach, my options as far as I know are to create pixels and render them either using:

  1. SDL_RenderDrawPoint(s) (Using SDL_SetRenderDrawColor)
  2. SDL_RenderCopy (Using Textures with SDL_SetTextureColorMod)

I'm not sure what's a better approach. #2 is probably easier as I have a whole system built around fast texture rendering (not necessarily faster than 1., but seemingly easier to implement with my current system.) #1 seems ideal because it's in the SDL2 library for a reason I'd think, but really I'm unsure which approach I should go with.

\$\endgroup\$
1
  • \$\begingroup\$ Are you just using SDL2's drawing systems or are you leveraging OpenGL? The "fastest and most efficient" way would probably involve using OpenGL. \$\endgroup\$
    – Honeybunch
    Dec 31, 2016 at 19:45

2 Answers 2

2
\$\begingroup\$

So I ran both Functions 100,000 times (ran it a few times just to make sure), and timed it using time.h . I rendered a simple 1x1 pixel at 0,0 and a texture of a 1x1 pixel at 0,0. Below is basically a single trial I found.

SDL_RenderDrawPoint: Time taken 9 milliseconds

SDL_RenderCopy: Time taken 266 milliseconds

Not surprisingly the RenderDrawPoint is much faster than RenderCopy. My trial wasn't super perfect as I might have been able to use a more optimized Texture, and had to use some variables with values for SDL_RenderCopy, but I doubt it added much time to make RenderCopy come even close to RenderDrawPoint.

Edit (Here's essentially the code I used, renderer is the window renderer, texture is a 1x1 bitmap surface in a texture loaded using RLE optimization):

#include <time.h>
#include <SDL2/SDL.h>

SDL_Rect clip;
clip.x = 0;
clip.y = 0;
clip.w = 1;
clip.h = 1;

int msec, i;
clock_t start, diff;

i = 100000;
start = clock()
while(i-- > 0)
{
    SDL_RenderDrawPoint(renderer, 0, 0);
}
diff = clock() - start;

msec = diff * 1000 / CLOCKS_PER_SEC;
fprintf(stdout, "Time taken %d seconds %d milliseconds", msec/1000, msec%1000);

i = 100000;
start = clock()
while(i-- > 0)
{
    SDL_RenderCopy(renderer, texture, &clip, &clip);
}
diff = clock() - start;

msec = diff * 1000 / CLOCKS_PER_SEC;
fprintf(stdout, "Time taken %d seconds %d milliseconds", msec/1000, msec%1000);
\$\endgroup\$
2
  • \$\begingroup\$ Could you post the code you used? \$\endgroup\$
    – user35344
    Jan 1, 2017 at 2:01
  • \$\begingroup\$ Added the code I essentially used (deleted it). Note that I could have replaced clip with NULL and maybe it would have been faster. Also I could have loaded a texture using the createTexture() function rather than from a bitmap surface, "may" have done something. \$\endgroup\$
    – Ray C
    Jan 1, 2017 at 2:34
1
\$\begingroup\$

Neither of those: use SDL_LockSurface to directly access directly the surface data. Then changing pixels is changing values in an array, which is fastest.

\$\endgroup\$

You must log in to answer this question.

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