سؤال

I think I may have encountered a compatibilty problem with SDL versions 1.2 and 2.0: When using SDL_MapRGB and SDL_FillRect to draw to a Surface, SDL 2.0 apparently swaps the RGB red and blue channels, while SDL 1.2 does not. The following C code is a minimal working example which demonstrates the problem:

#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>

int main(void)
{
  const unsigned height = 16;
  const unsigned widthpercolour = 16;
  SDL_Surface *surface;
  SDL_Rect rect;
  rect.x = 0;
  rect.y = 0;
  rect.w = widthpercolour;
  rect.h = height;
  if (SDL_Init(0) != 0) {
    fprintf(stderr, "Could not initialize SDL: %s\n", SDL_GetError());
    return EXIT_FAILURE;
  }
  surface = SDL_CreateRGBSurface(0, 3 * widthpercolour, height, 24, 0x0000ff, 0x00ff00, 0xff0000, 0);
  if (surface == NULL) {
    fprintf(stderr, "Could not create SDL Surface: %s\n", SDL_GetError());
    return EXIT_FAILURE;
  }
  SDL_FillRect(surface, NULL, 0);

  SDL_FillRect(surface, &rect, SDL_MapRGB(surface->format, 255, 0, 0));
  rect.x += widthpercolour;
  SDL_FillRect(surface, &rect, SDL_MapRGB(surface->format, 0, 255, 0));
  rect.x += widthpercolour;
  SDL_FillRect(surface, &rect, SDL_MapRGB(surface->format, 0, 0, 255));

  if (SDL_SaveBMP(surface, "colourtest.bmp") != 0) {
    SDL_FreeSurface(surface);
    SDL_Quit();
    fprintf(stderr, "Could not save SDL Surface: %s\n", SDL_GetError());
    return EXIT_FAILURE;
  }
  SDL_FreeSurface(surface);
  SDL_Quit();
  return EXIT_SUCCESS;
}

When compiled with

gcc $(sdl-config --cflags --libs) colourtest.c -o colourtest

(which uses SDL 1.2 headers and libraries), the code produces (as I expected) the following bitmap file:

rgb rectangles correct order

However, when compiled with

gcc $(sdl2-config --cflags --libs) colourtest.c -o colourtest

(which uses SDL 2.0), the code produces (unexpectedly) the following bitmap file:

bgr, reversed order

I tried changing the (r,g,b) masks, but that changes nothing.

As far as I can tell, the documentation, including the migration guide, mentions none of this and I was unable to find anything else on the matter. This leads me to assume that either this is a bug or I am not using the functions correctly.

هل كانت مفيدة؟

المحلول

Umm....Interesting. No, SDL 2.0 did not swap to bgr, it is still the same old RGB.

Here's what I will say. The only reason that would be happening is the byte order is getting swapped, as SDL maps rgb to whatever your machines byte order is. Maybe for some reason one version resolves this automatically and the other version lets you decide whether you want to use the byte order of your machine or not (in this case default is little endian or choose to use big endian)?

Try using variables to store your rbga values, then use this code to make sure the color values get assigned to the correct bits no matter what the byte order is on your machine:

Uint32 red, greeb, blue, alpha

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
red = 0xff000000;
green = 0x00ff0000;
blue = 0x0000ff00;
alpha = 0x000000ff;

#else
red = 0x000000ff;
green = 0x0000ff00;
blue = 0x00ff0000;
alpha = 0xff000000;

#endif

I hope that helps at all, or at least gives you something to go off of.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top