SDL_BYTEORDER and the order of the channels

Hi!

In the documentation for SDL_CreateRGBSurface (http://docs.huihoo.com/sdl/1.2/sdlcreatergbsurface.html), there is an example at the bottom:

Code:
/* Create a 32-bit surface with the bytes of each pixel in R,G,B,A order,
as expected by OpenGL for textures */
SDL_Surface *surface;
Uint32 rmask, gmask, bmask, amask;

/* SDL interprets each pixel as a 32-bit number, so our masks must depend
   on the endianness (byte order) of the machine */

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif

surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32,
                               rmask, gmask, bmask, amask);
if(surface == NULL) {
    fprintf(stderr, "CreateRGBSurface failed: %s\n", SDL_GetError());
    exit(1);
}

On my system, the byte order is not SDL_BIG_ENDIAN , so I guess it is little endian. The only thing is that, when I call the function SDL_SetVideoMode, I get the masks

Code:

rmask = 0x00ff0000;
gmask = 0x0000ff00;
bmask = 0x000000ff:
amask = 0x00000000;

Wouldn’t they rather be

Code:

rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000:
amask = 0x00000000;

?

I was trying to perform fast buffer manipulations, hence storing the masks, the shift and the losses of each channel as constants, but my video buffer was clearly giving me trouble! Why does it get these bit masks? :x

Later I discovered that if I create a SDL_Buffer from an image loaded from disk, using SDL_DisplayFormatAlpha, I will get these bit masks:

Code:

rmask = 0x00ff0000;
gmask = 0x0000ff00;
bmask = 0x000000ff:
amask = 0xff000000;

:?

I’ll also get these bit masks if I generate an image from an SDL_Font, a text and a color, using SDL_ttf and the function TTF_RenderText_Blended. I also discovered that if I load an image from the disk, using SDL_img and the function IMG_Load, I will get these bit masks:

Code:

rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000:
amask = 0x00000000;

???

This even differs from the bit masks of the video buffer, which has exactly the same channels enabled! The last empty bitmask for the alpha channel is probably because the images I have loaded doesn’t have an alpha channel. Because I suppose IMG_Load handles alpha channels, right?

This byte order thing is making me kind of confused; Why does images generated in different ways have such different bit masks for their channels? Does it matter at all in what order I choose the channels to be in, when I call SDL_CreateRGBSurface (the ones who have created the example clearly think so)? And if it does, what matter does it do?

Still haven’t got any answer to this post, I shorten it down to two questions:

  1. Is there any way to tell before what the masks for the different channels will look like in a SDL_Buffer created with SDL_SetVideoMode? Then I mean to be able to exactly tell what they will be so you can use them as compile time variables in you program.

  2. What does the function SDL_DisplayFormat do? does it convert the image to a SDL_Buffer with the same format as the video buffer, i.e. the same channel masks? Is SDL_DisplayFormatAlpha the same only that it adds an alpha channel where there is a free space?

  1. No, it will vary depending on the hardware and operating system
    that your program is running on.

  2. Yes, it does exactly what you describe.On Mon, Dec 14, 2009 at 5:43 PM, TriKri wrote:

Still haven’t got any answer to this post, I shorten it down to two
questions:

  1. Is there any way to tell before what the masks for the different channels
    will look like in a SDL_Buffer created with SDL_SetVideoMode? Then I mean to
    be able to exactly tell what they will be so you can use them as compile
    time variables in you program.

  2. What does the function SDL_DisplayFormat do? does it convert the image to
    a SDL_Buffer with the same format as the video buffer, i.e. the same channel
    masks? Is SDL_DisplayFormatAlpha the same only that it adds an alpha channel
    where there is a free space?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

Sam Lantinga wrote:

  1. No, it will vary depending on the hardware and operating system
    that your program is running on.

Okay, that’s what I suspected, so you will have to look in the format variable in each SDL_Buffer and read the channel masks from there.

The next question will be if there is any way to figure out what they will look like if you know the hardware and the operating system that the program is going to be compiled on. Since, I mean, if you change hardware or operating system, you would have to re-compile the program anyway (then with other values of the compile-time variables), right? Of course, there is no guarantee that using Wine or similar will work afterwards (as if there was from the beginning).

Sam Lantinga wrote:

  1. No, it will vary depending on the hardware and operating system
    that your program is running on.

Okay, that’s what I suspected, so you will have to look in the format
variable in each SDL_Buffer and read the channel masks from there.

The next question will be if there is any way to figure out what they will
look like if you know the hardware and the operating system that the program
is going to be compiled on.

Sure, print out the information you need from a run of the program. The best
way to do that is in the form of a .h file suitable for use when you
recompile the code. The first hand coded version of the .h file can just
contain absurd values.

When you run the program you should do a run time check to see if the hard
coded constants are what you actually got. If they are not, you should print
the new .h file, abort and print a nice message telling yourself to
recompile. If the test values match the precompiled values, you can continue
running.

So, the first time you compile and run the code it will terminate and create
a .h file that has the correct values. Then you recompile. After that the
program will just work until the hardware changes at which point it creates
yet another .h file that works for the new hardware.

It works, I’ve seen it work, I’ve even done it. Ever had the home work
assignment to write a program that prints out a copy of itself?

Before going to all that work you should do some tests to find out if using
hard coded constants give you enough benefit to justify the work.

Bob PendletonOn Tue, Dec 15, 2009 at 4:41 AM, TriKri wrote:

Since, I mean, if you change hardware or operating system, you would have
to re-compile the program anyway (then with other values of the compile-time
variables), right? Of course, there is no guarantee that using Wine or
similar will work afterwards (as if there was from the beginning).


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


±----------------------------------------------------------

Hm, it feels like a workaround, even if it is a smart idea; if nothing else work maybe I will consider using it. But shouldn’t there be any rules for deciding what the masks will look like? Or is there maybe some SDL constants telling you what they look like? I mean, SDL knows itself what they look like; how does it know that (I am at a SDL forum so I think someone here should know)?

There’s no harm in sifting through the source… I think you’d want
to look for the code in SDL_SetVideoMode().

Jonny DOn Tue, Dec 15, 2009 at 4:45 PM, TriKri wrote:

Hm, it feels like a workaround, even if it is a smart idea; if nothing else
work maybe I will consider using it. But shouldn’t there be any rules for
deciding what the masks will look like? Or is there maybe some SDL constants
telling you what they look like? I mean, SDL knows itself what they look
like; how does it know that (I am at a SDL forum so I think someone here
should know)?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Hm, it feels like a workaround, even if it is a smart idea; if nothing else
work maybe I will consider using it. But shouldn’t there be any rules for
deciding what the masks will look like? Or is there maybe some SDL constants
telling you what they look like? I mean, SDL knows itself what they look
like; how does it know that (I am at a SDL forum so I think someone here
should know)?

Why should there be such rules? I’ve been working in computer graphics
since before there were frame buffers and I’ve never seen any such
rules or a reason to believe there should be such rules.

The allocation of bits to colors, the order of the bits in a byte or
word, the endianness of the values and their order in a pixel are
basically chosen by the designers of the graphics system in
conjunction with, or in response to, the designers of the core
computer system and its buses. The driving force is pretty much always
getting a price performance ratio than your competition while not
building something so gross the programs with actually quit their jobs
rather than write code for it. I’m being serious here. Hey, I’ve seen
10 bit color values stuck into 32 bit words by putting the high order
8 bits of each color in eight bit fields and the low order two bits of
each color in the first 6 bits of the last byte. It looked like this:

rrrrrrrrggggggggbbbbbbbbrrggbbxx

Does that make sense? It did to the designers.

Ok, for SDL 1.3 if you look inside SDL in include/SDL_pixels.h you
will find all the enumerations used by SDL to encode the 5 different
dimensions of the the space that contains all the defined forms of
pixels that SDL currently understands. BTW, it does not include a
way to encode the weird example I gave above. Sam has cleverly found a
way to pack the entire pack an encoded form from that space of
possibilities into only 30 bits. Which means there are less than
1,073,741,824 possible formats. Less than half that really. But, Sam
needs space to deal with the next generation of 16 bit/color and
floating point color displays. I’m sure I’m leaving some out. And, as
I’ve said, the formats supported by SDL only cover the common formats
used by fairly recent graphics systems.

With that .h file and a little code you can easily generate a list of
all the pixel formats that SDL has to be prepared to work with. You
can then generated custom code for all the cases. Have fun. :slight_smile:

Ok, Ok, I being a bit flippant, but really SDL has to work with what
is there and what does not conform to many, if any, rules.

Bob PendletonOn Tue, Dec 15, 2009 at 3:45 PM, TriKri wrote:


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


±----------------------------------------------------------