0

I have the following function which draws a grid of pixels on the window, I'm using sdl.

The problem is that is very slow! It makes my program to run at 10fps, so I think Im must be doing something wrong.

This is the code I'm using

void rayTracing(SDL &sdl) {
  int nx = 1440;
  int ny = 810;

  for (int x = 0; x < nx; x++) {
    for (int y = 0; y < ny; y++) {
      float r = float(x) / float(nx);
      float g = float(y) / float(ny);
      float b = 0.2;
      int ir = int(255.99 * r);
      int ig = int(255.99 * g);
      int ib = int(255.99 * b);

      SDL_SetRenderDrawColor(sdl.renderer.get(), ir, ig, ib, 255);
      SDL_RenderDrawPoint(sdl.renderer.get(), x, ny - y);
    }
  }

  SDL_SetRenderDrawColor(sdl.renderer.get(), 0, 0, 0, 0);
}

Maybe the problem is the way I use SDL_RenderDrawPoint?

genpfault
  • 51,148
  • 11
  • 85
  • 139
ellipticaldoor
  • 1,122
  • 11
  • 24
  • Which version of SDL are you using? If you can, upgrade to one of the recent ones that supports SDL_Renderer batching (2.0.10+?) & force-enable it via the `SDL_HINT_RENDER_BATCHING` hint. Otherwise, group your points by color & use `SDL_RenderDrawPoints()`. Or, since everything is just in a grid, load your pixels into a SDL_Texture & draw that. – genpfault Jun 15 '20 at 04:10
  • I'll try SDL_HINT_RENDER_BATCHING, and SDL_RenderDrawPoints doesn't works on this case for me. How should I do it with SDL_Texture in a performant way? – ellipticaldoor Jun 15 '20 at 17:20
  • 1
    [Like so](https://stackoverflow.com/a/33312056/44729). – genpfault Jun 15 '20 at 18:23
  • It would be much faster if implemented with OpenGL & shaders. – HolyBlackCat Jun 15 '20 at 19:44
  • @HolyBlackCat do you know a tutorial for that? – ellipticaldoor Jun 17 '20 at 15:35
  • 1
    https://learnopengl.com/ is a good tutorial. – HolyBlackCat Jun 17 '20 at 16:10

1 Answers1

4

Your best bet may be to create a separate render texture that you can access directly through a pointer. You make your changes and when you are done, you call an SDL texture update once and it will transfer your in-memory texture to the display.

This is how you create the SDL texture

theTexture = SDL_CreateTexture( theRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, nx, ny );

You would then also create an in-memory buffer to draw to

uint32_t *textureBuffer = new uint32_t[ nx * ny ];

At this point, drawing a pixel really just comes down to writing the respective RGB8888 color value to the textureBuffer array, kind of like this

textureBuffer[(yPos*nx) + xPos] = 0xFF000000 | (ir<<16) | (ib<<8) | ig;

After drawing to it, you can then update the entire texture in one swoop like this

SDL_UpdateTexture( theTexture , NULL, textureBuffer, nx * sizeof (uint32_t));
Justiniscoding
  • 441
  • 5
  • 19
Striding Dragon
  • 225
  • 1
  • 9
  • Yes, it does, as long as each of the platforms supports the pixel format you are using. If you don't need full ARGB8888, you can also use RGB888, or RGB565, etc. ARGB8888 is my preference for most platforms because it makes every pixel a 32-bit entry, allowing you to optimize your drawing loops and indexing accordingly. With a 24-bit format, you always run into alignment issues, etc, because no native 24-bit data type exists in C/C++. – Striding Dragon Jun 17 '20 at 22:37
  • thank you, it works well. one thing is that my image now is upside down how I can change this to flip it? textureBuffer[(yPos*nx) + xPos) = 0xFF000000 | (ir<<16) | (ib<<8) | ig; – ellipticaldoor Jun 17 '20 at 22:46
  • Hmmh, that is strange. It should not be upside down—unless you loaded a BMP file into the buffer, which is inherently stored upside down. – Striding Dragon Jun 17 '20 at 23:26
  • 1
    yeah, its because of how I was rendering the raytracer, now I just reverse the y and its fine – ellipticaldoor Jun 18 '20 at 00:08
  • I followed this solution, I am also making a ray tracer. With a larger width and height, the program closes and I get a `segmentation fault: 11`. Why is this happening? – Justiniscoding May 23 '22 at 00:00
  • Segmentation faults are typically an indicator that you are writing outside your allocated buffer. Make sure your pointers and lengths are correct. – Striding Dragon May 23 '22 at 17:21
  • Thanks, I fixed it by removing the malloc call I was using to create the array and instead created it using `uint32_t textureBuffer[size]` – Justiniscoding Jul 15 '22 at 23:09