0
\$\begingroup\$

I'm using SDL and need to plot pixels one by one on the screen. When I do this, it's extremely slow. I followed the tutorial here:

http://www.programmersranch.com/2014/02/sdl2-pixel-drawing.html

Which basically said to call:

SDL_RenderClear();

SDL_RenderCopy();

SDL_RenderPresent();

SDL_UpdateTexture();

Right after I update my pixel array.

I ran a loop (which calls the above functions) to demonstrate the issue:

for (unsigned int i = 0; i < 128; i++)     
    for (unsigned int j = 0; j < 128; j++)          
        plot_pixel(j, i, 0xff); // x, y, ARGB val

But it runs painfully slow. Is there a better way to plot pixels with extreme speed? The whole idea of my program is to plot pixels as fast as possible, and it takes several seconds to run through that loop and plot 128*128 pixels.

Here is the code for plot_pixel:

void plot_pixel(int x, int y, int argb)
{
    pixels[y*width+x] = argb;
    SDL_UpdateTexture(texture, NULL, pixels, width * 4);
    SDL_RenderClear(renderer);
    SDL_RenderCopy(renderer, texture, NULL, NULL);
    SDL_RenderPresent(renderer);
}

The code works exactly like I want it to (it plots a pixel) but its painfully slow.

\$\endgroup\$
3
  • \$\begingroup\$ Please post the entire loop's contents. Make sure you are not clearing/copying/presenting every time you update a pixel. \$\endgroup\$
    – Jon
    Commented Apr 18, 2015 at 19:12
  • \$\begingroup\$ @Jon I've updated my post reflecting the code inside of plot_pixel. The loop is exactly what I have. You mention not clearing/copying/presenting, for each pixel, but I can't figure out a better way of doing it. Any hints? \$\endgroup\$ Commented Apr 18, 2015 at 19:24
  • \$\begingroup\$ Indeed; you're very close. The sample was written that way since it only affects one pixel per-"frame" (loop iteration). \$\endgroup\$
    – Jon
    Commented Apr 18, 2015 at 19:33

1 Answer 1

1
\$\begingroup\$

You need to move all the SDL functions out of the compound for loop.

for
{ 
 for
 {
   pixels[y*width+x] = argb;
   //Updating them all at once should be fine
   //Nothing else can happen while this is running
 }
}
//Update entire array at once, then...
SDL_UpdateTexture(texture, NULL, pixels, width * 4); //Copy entire array only once
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
\$\endgroup\$
3
  • \$\begingroup\$ My fault, I'm being a little cryptic with my question. My issue is that I need to plot a pixel at a time and then render it immediately, instead of deferring the rendering. I'm writing an emulator and I can't afford to defer the render at the end of the frame (or scanline). \$\endgroup\$ Commented Apr 18, 2015 at 19:35
  • 1
    \$\begingroup\$ @RobertGoulet, I'm not sure what you mean. The program will remain within the compound for{} and be busy until it's finished, so there is no other code for this change to affect. The performance problem comes from copying the entire array many, many times per-frame, even though you've only changed one value within it. \$\endgroup\$
    – Jon
    Commented Apr 18, 2015 at 19:42
  • 2
    \$\begingroup\$ @RobertGoulet, the second parameter of UpdateTexture allows you to specify a rectangle to update. If you were to limit the rectangle to only the pixel you just modified, you could increase performance. It's possible that I'm still misunderstanding but, please try my original solution and verify that it is unsatisfactory. \$\endgroup\$
    – Jon
    Commented Apr 18, 2015 at 19:48

You must log in to answer this question.

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