Meshing OpenGL and SDL
ThemsAllTook Wrote:Take an int, 0x12345678, for example. On a big-endian architecture, this number is represented in physical memory as 0x12, 0x34, 0x56, 0x78. On a little-endian architecture, on the other hand, it's represented as 0x78, 0x56, 0x34, 0x12.
Meh?
I thought that big endian meant that the bigger numbers went first with little numbers went last, and vice versa?
"bigger" meaning "most significant" (eg. the hundreds place comes before the tens place, even if the digit in the hundreds place is a 2 and the digit in the tens place is a 7)
A bit late. I found my code I was talking about but I made some assumptions and it wasn't that generic such that it would work with any surface. Modified the code but didn't test it; but it should give the idea that a/ it's not hard, b/ it's not that error prone c/ it's not that future-proof problematic; but I do grant that it's not that efficient. Some inlining could be done to speed it up a bit, the use of pointer arithmetic as well would help, but all in all, if this function isn't being used in a time critical location, then I don't see the point of putting so much effort into making it ugly and unreadable.
Granted the RGBA order in the image returned may need looking at for endianness which I wasn't concerned about at the time.
Code:
/********************************************************************
** FUNC: ConvertSDLSurfaceToRGBA
**
** This will convert an SDL surface to an RGBA buffer.
********************************************************************/
unsigned char *ConvertSDLSurfaceToRGBA(SDL_Surface *surface)
{
int a,
b,
rindexi;
Uint8 cr,
cg,
cb,
ca;
unsigned char *image;
/* Trivial check */
if (!surface) {
return NULL;
}
/* Create the RGBA buffer */
image = (unsigned char *) calloc(
1,
sizeof(unsigned char) * 4 * surface->w * surface->h);
if (!image) {
return NULL;
}
/* For all Rows... */
for (b = 0; b < surface->h; b++) {
rindexi = b * surface->w * 4;
/* For all Cols... */
for (a = 0; a < surface->w; a++) {
/* Copy the rgb values over. */
SDL_GetRGBA(
GetPixel(surface, a, b),
surface->format,
&cr,
&cg,
&cb,
&ca);
image[rindexi + a * 4 + 0] = cr;
image[rindexi + a * 4 + 1] = cg;
image[rindexi + a * 4 + 2] = cb;
image[rindexi + a * 4 + 3] = ca;
}
}
return image;
}
/********************************************************************
func: GetPixel
Get a pixel's value. (From libsdl.org wiki)
********************************************************************/
Uint32 GetPixel(SDL_Surface *surface, int x, int y)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to retrieve */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
return *p;
case 2:
return *(Uint16 *)p;
case 3:
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
return p[0] << 16 |
p[1] << 8 |
p[2];
#else
return p[0] |
p[1] << 8 |
p[2] << 16;
#endif
case 4:
return *(Uint32 *)p;
default:
return 0; /* shouldn't happen, but avoids warnings */
}
}
This is effectively what skorche's solution does, except that his uses the optimized SDL routines, rather than reinventing the wheel
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| Meshing MDD and Obj | OptimisticMonkey | 0 | 2,943 |
May 3, 2011 06:25 PM Last Post: OptimisticMonkey |
|

