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\$
  • \$\begingroup\$ Please post the entire loop's contents. Make sure you are not clearing/copying/presenting every time you update a pixel. \$\endgroup\$ – Jon Apr 18 '15 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\$ – Robert Goulet Apr 18 '15 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 Apr 18 '15 at 19:33
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\$
  • \$\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\$ – Robert Goulet Apr 18 '15 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 Apr 18 '15 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 Apr 18 '15 at 19:48

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.