voxel-tracer.github.io

Development blog where I share my knowledge and projects


Project maintained by voxel-tracer Hosted on GitHub Pages — Theme by mattgraham

Sdl Image

Display image using SDL

Using SDL it is not that complicated to display a picture in a window.

From our previous post, we learned how to load a png from disk using the following:

int nx, ny, n;
const int desired_channels = 3;
unsigned char *data = stbi_load("my_picture.png", &nx, &ny, &n, desired_channels);
if (data == NULL)
  return 1;

Now for the sake of this example, lets write the image into another pixel array:

unsigned int *pixels = new unsigned int[nx*ny];

// copy pixels from RGB to ARGB
for (int y = 0, idx = 0; y < ny; y++) {
  for (int x = 0; x < nx; x++, idx++) {
    unsigned char red = data[idx * desired_channels];
    unsigned char green = data[idx * desired_channels + 1];
    unsigned char blue = data[idx * desired_channels + 2];
    pixels[idx] = (red << 16) + (green << 8) + blue;
  }
}

Now for the fun part, let’s initialize SDL along a couple of variables needed by it:

SDL_Window *win = NULL;
SDL_Renderer *renderer = NULL;
SDL_Texture *img = NULL;

// Initialize SDL.
if (SDL_Init(SDL_INIT_VIDEO) < 0)
  return 1;

Now we create a window, renderer, and a texture and copy the pixels to it:

win = SDL_CreateWindow("Image Loading", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, nx, ny, 0);
renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
img = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, nx, ny);
SDL_UpdateTexture(img, NULL, pixels, nx * sizeof(unsigned int));
SDL_RenderCopy(renderer, img, NULL, NULL);
SDL_RenderPresent(renderer);

Now we can just wait for the user to close the window:

// wait until the window is closed
SDL_Event event;
bool quit = false;
while (!quit && SDL_WaitEvent(&event)) {
  switch (event.type) {
    case SDL_QUIT:
      quit = true;
      break;
  }
}

And finally we are ready to free all created resources:

// free all resources
SDL_DestroyTexture(img);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(win);

stbi_image_free(data);
delete[] pixels;

SDL_Quit();
Written on March 4, 2018