Simplified and improved the process of creating a texture from a surface.
This commit is contained in:
parent
31b3ad2414
commit
fe2b0d9703
5 changed files with 40 additions and 248 deletions
|
@ -172,19 +172,16 @@ extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTexture(SDL_Renderer * renderer,
|
||||||
/**
|
/**
|
||||||
* \brief Create a texture from an existing surface.
|
* \brief Create a texture from an existing surface.
|
||||||
*
|
*
|
||||||
* \param format The format of the texture, or 0 to pick an appropriate format.
|
|
||||||
* \param surface The surface containing pixel data used to fill the texture.
|
* \param surface The surface containing pixel data used to fill the texture.
|
||||||
*
|
*
|
||||||
* \return The created texture is returned, or 0 if no rendering context was
|
* \return The created texture is returned, or 0 on error.
|
||||||
* active, the format was unsupported, or the surface width or height
|
|
||||||
* were out of range.
|
|
||||||
*
|
*
|
||||||
* \note The surface is not modified or freed by this function.
|
* \note The surface is not modified or freed by this function.
|
||||||
*
|
*
|
||||||
* \sa SDL_QueryTexture()
|
* \sa SDL_QueryTexture()
|
||||||
* \sa SDL_DestroyTexture()
|
* \sa SDL_DestroyTexture()
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTextureFromSurface(SDL_Renderer * renderer, Uint32 format, SDL_Surface * surface);
|
extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Query the attributes of a texture
|
* \brief Query the attributes of a texture
|
||||||
|
|
|
@ -250,13 +250,15 @@ SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Texture *
|
SDL_Texture *
|
||||||
SDL_CreateTextureFromSurface(SDL_Renderer * renderer, Uint32 format, SDL_Surface * surface)
|
SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface)
|
||||||
{
|
{
|
||||||
SDL_Texture *texture;
|
const SDL_PixelFormat *fmt;
|
||||||
Uint32 requested_format = format;
|
SDL_bool needAlpha;
|
||||||
SDL_PixelFormat *fmt;
|
Uint32 i;
|
||||||
|
Uint32 format;
|
||||||
int bpp;
|
int bpp;
|
||||||
Uint32 Rmask, Gmask, Bmask, Amask;
|
Uint32 Rmask, Gmask, Bmask, Amask;
|
||||||
|
SDL_Texture *texture;
|
||||||
|
|
||||||
CHECK_RENDERER_MAGIC(renderer, NULL);
|
CHECK_RENDERER_MAGIC(renderer, NULL);
|
||||||
|
|
||||||
|
@ -264,255 +266,56 @@ SDL_CreateTextureFromSurface(SDL_Renderer * renderer, Uint32 format, SDL_Surface
|
||||||
SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
|
SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See what the best texture format is */
|
||||||
fmt = surface->format;
|
fmt = surface->format;
|
||||||
|
if (fmt->Amask || SDL_GetColorKey(surface, NULL) == 0) {
|
||||||
if (format) {
|
needAlpha = SDL_TRUE;
|
||||||
if (!SDL_PixelFormatEnumToMasks
|
|
||||||
(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
|
|
||||||
SDL_SetError("Unknown pixel format");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
SDL_bool hasColorkey;
|
needAlpha = SDL_FALSE;
|
||||||
SDL_BlendMode blendMode;
|
}
|
||||||
SDL_bool hasBlending;
|
format = renderer->info.texture_formats[0];
|
||||||
|
for (i = 0; i < renderer->info.num_texture_formats; ++i) {
|
||||||
|
if (SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == needAlpha) {
|
||||||
|
format = renderer->info.texture_formats[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hasColorkey = (SDL_GetColorKey(surface, NULL) == 0);
|
if (!SDL_PixelFormatEnumToMasks(format, &bpp,
|
||||||
|
&Rmask, &Gmask, &Bmask, &Amask)) {
|
||||||
SDL_GetSurfaceBlendMode(surface, &blendMode);
|
|
||||||
hasBlending = (blendMode == SDL_BLENDMODE_BLEND);
|
|
||||||
|
|
||||||
if (surface->format->Amask || (!hasColorkey && !hasBlending)) {
|
|
||||||
Uint32 it;
|
|
||||||
int pfmt;
|
|
||||||
|
|
||||||
/* Pixel formats, sorted by best first */
|
|
||||||
static const Uint32 sdl_pformats[] = {
|
|
||||||
SDL_PIXELFORMAT_ARGB8888,
|
|
||||||
SDL_PIXELFORMAT_RGBA8888,
|
|
||||||
SDL_PIXELFORMAT_ABGR8888,
|
|
||||||
SDL_PIXELFORMAT_BGRA8888,
|
|
||||||
SDL_PIXELFORMAT_RGB888,
|
|
||||||
SDL_PIXELFORMAT_BGR888,
|
|
||||||
SDL_PIXELFORMAT_RGB24,
|
|
||||||
SDL_PIXELFORMAT_BGR24,
|
|
||||||
SDL_PIXELFORMAT_RGB565,
|
|
||||||
SDL_PIXELFORMAT_BGR565,
|
|
||||||
SDL_PIXELFORMAT_ARGB1555,
|
|
||||||
SDL_PIXELFORMAT_RGBA5551,
|
|
||||||
SDL_PIXELFORMAT_ABGR1555,
|
|
||||||
SDL_PIXELFORMAT_BGRA5551,
|
|
||||||
SDL_PIXELFORMAT_RGB555,
|
|
||||||
SDL_PIXELFORMAT_BGR555,
|
|
||||||
SDL_PIXELFORMAT_ARGB4444,
|
|
||||||
SDL_PIXELFORMAT_RGBA4444,
|
|
||||||
SDL_PIXELFORMAT_ABGR4444,
|
|
||||||
SDL_PIXELFORMAT_BGRA4444,
|
|
||||||
SDL_PIXELFORMAT_RGB444,
|
|
||||||
SDL_PIXELFORMAT_ARGB2101010,
|
|
||||||
SDL_PIXELFORMAT_RGB332,
|
|
||||||
SDL_PIXELFORMAT_UNKNOWN
|
|
||||||
};
|
|
||||||
|
|
||||||
bpp = fmt->BitsPerPixel;
|
|
||||||
Rmask = fmt->Rmask;
|
|
||||||
Gmask = fmt->Gmask;
|
|
||||||
Bmask = fmt->Bmask;
|
|
||||||
Amask = fmt->Amask;
|
|
||||||
|
|
||||||
format =
|
|
||||||
SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
|
|
||||||
if (!format) {
|
|
||||||
SDL_SetError("Unknown pixel format");
|
SDL_SetError("Unknown pixel format");
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search requested format in the supported texture */
|
|
||||||
/* formats by current renderer */
|
|
||||||
for (it = 0; it < renderer->info.num_texture_formats; it++) {
|
|
||||||
if (renderer->info.texture_formats[it] == format) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If requested format can't be found, search any best */
|
|
||||||
/* format which renderer provides */
|
|
||||||
if (it == renderer->info.num_texture_formats) {
|
|
||||||
pfmt = 0;
|
|
||||||
for (;;) {
|
|
||||||
if (sdl_pformats[pfmt] == SDL_PIXELFORMAT_UNKNOWN) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (it = 0; it < renderer->info.num_texture_formats;
|
|
||||||
it++) {
|
|
||||||
if (renderer->info.texture_formats[it] ==
|
|
||||||
sdl_pformats[pfmt]) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (it != renderer->info.num_texture_formats) {
|
|
||||||
/* The best format has been found */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pfmt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If any format can't be found, then return an error */
|
|
||||||
if (it == renderer->info.num_texture_formats) {
|
|
||||||
SDL_SetError
|
|
||||||
("Any of the supported pixel formats can't be found");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert found pixel format back to color masks */
|
|
||||||
if (SDL_PixelFormatEnumToMasks
|
|
||||||
(renderer->info.texture_formats[it], &bpp, &Rmask, &Gmask,
|
|
||||||
&Bmask, &Amask) != SDL_TRUE) {
|
|
||||||
SDL_SetError("Unknown pixel format");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Need a format with alpha */
|
|
||||||
Uint32 it;
|
|
||||||
int apfmt;
|
|
||||||
|
|
||||||
/* Pixel formats with alpha, sorted by best first */
|
|
||||||
static const Uint32 sdl_alpha_pformats[] = {
|
|
||||||
SDL_PIXELFORMAT_ARGB8888,
|
|
||||||
SDL_PIXELFORMAT_RGBA8888,
|
|
||||||
SDL_PIXELFORMAT_ABGR8888,
|
|
||||||
SDL_PIXELFORMAT_BGRA8888,
|
|
||||||
SDL_PIXELFORMAT_ARGB1555,
|
|
||||||
SDL_PIXELFORMAT_RGBA5551,
|
|
||||||
SDL_PIXELFORMAT_ABGR1555,
|
|
||||||
SDL_PIXELFORMAT_BGRA5551,
|
|
||||||
SDL_PIXELFORMAT_ARGB4444,
|
|
||||||
SDL_PIXELFORMAT_RGBA4444,
|
|
||||||
SDL_PIXELFORMAT_ABGR4444,
|
|
||||||
SDL_PIXELFORMAT_BGRA4444,
|
|
||||||
SDL_PIXELFORMAT_ARGB2101010,
|
|
||||||
SDL_PIXELFORMAT_UNKNOWN
|
|
||||||
};
|
|
||||||
|
|
||||||
if (surface->format->Amask) {
|
|
||||||
/* If surface already has alpha, then try an original */
|
|
||||||
/* surface format first */
|
|
||||||
bpp = fmt->BitsPerPixel;
|
|
||||||
Rmask = fmt->Rmask;
|
|
||||||
Gmask = fmt->Gmask;
|
|
||||||
Bmask = fmt->Bmask;
|
|
||||||
Amask = fmt->Amask;
|
|
||||||
} else {
|
|
||||||
bpp = 32;
|
|
||||||
Rmask = 0x00FF0000;
|
|
||||||
Gmask = 0x0000FF00;
|
|
||||||
Bmask = 0x000000FF;
|
|
||||||
Amask = 0xFF000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
format =
|
|
||||||
SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
|
|
||||||
if (!format) {
|
|
||||||
SDL_SetError("Unknown pixel format");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Search this format in the supported texture formats */
|
|
||||||
/* by current renderer */
|
|
||||||
for (it = 0; it < renderer->info.num_texture_formats; it++) {
|
|
||||||
if (renderer->info.texture_formats[it] == format) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If this format can't be found, search any best */
|
|
||||||
/* compatible format with alpha which renderer provides */
|
|
||||||
if (it == renderer->info.num_texture_formats) {
|
|
||||||
apfmt = 0;
|
|
||||||
for (;;) {
|
|
||||||
if (sdl_alpha_pformats[apfmt] == SDL_PIXELFORMAT_UNKNOWN) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (it = 0; it < renderer->info.num_texture_formats;
|
|
||||||
it++) {
|
|
||||||
if (renderer->info.texture_formats[it] ==
|
|
||||||
sdl_alpha_pformats[apfmt]) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (it != renderer->info.num_texture_formats) {
|
|
||||||
/* Compatible format has been found */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
apfmt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If compatible format can't be found, then return an error */
|
|
||||||
if (it == renderer->info.num_texture_formats) {
|
|
||||||
SDL_SetError("Compatible pixel format can't be found");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert found pixel format back to color masks */
|
|
||||||
if (SDL_PixelFormatEnumToMasks
|
|
||||||
(renderer->info.texture_formats[it], &bpp, &Rmask, &Gmask,
|
|
||||||
&Bmask, &Amask) != SDL_TRUE) {
|
|
||||||
SDL_SetError("Unknown pixel format");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
format = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
|
|
||||||
if (!format) {
|
|
||||||
SDL_SetError("Unknown pixel format");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
texture =
|
|
||||||
SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
|
|
||||||
surface->w, surface->h);
|
|
||||||
if (!texture && !requested_format) {
|
|
||||||
SDL_DisplayMode desktop_mode;
|
|
||||||
SDL_GetDesktopDisplayMode(&desktop_mode);
|
|
||||||
format = desktop_mode.format;
|
|
||||||
texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
|
texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
|
||||||
surface->w, surface->h);
|
surface->w, surface->h);
|
||||||
}
|
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpp == fmt->BitsPerPixel && Rmask == fmt->Rmask && Gmask == fmt->Gmask
|
if (bpp == fmt->BitsPerPixel && Rmask == fmt->Rmask && Gmask == fmt->Gmask
|
||||||
&& Bmask == fmt->Bmask && Amask == fmt->Amask) {
|
&& Bmask == fmt->Bmask && Amask == fmt->Amask) {
|
||||||
if (SDL_MUSTLOCK(surface)) {
|
if (SDL_MUSTLOCK(surface)) {
|
||||||
SDL_LockSurface(surface);
|
SDL_LockSurface(surface);
|
||||||
SDL_UpdateTexture(texture, NULL, surface->pixels,
|
SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
|
||||||
surface->pitch);
|
|
||||||
SDL_UnlockSurface(surface);
|
SDL_UnlockSurface(surface);
|
||||||
} else {
|
} else {
|
||||||
SDL_UpdateTexture(texture, NULL, surface->pixels,
|
SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
|
||||||
surface->pitch);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SDL_PixelFormat dst_fmt;
|
SDL_PixelFormat dst_fmt;
|
||||||
SDL_Surface *dst = NULL;
|
SDL_Surface *temp = NULL;
|
||||||
|
|
||||||
/* Set up a destination surface for the texture update */
|
/* Set up a destination surface for the texture update */
|
||||||
SDL_InitFormat(&dst_fmt, bpp, Rmask, Gmask, Bmask, Amask);
|
SDL_InitFormat(&dst_fmt, bpp, Rmask, Gmask, Bmask, Amask);
|
||||||
dst = SDL_ConvertSurface(surface, &dst_fmt, 0);
|
temp = SDL_ConvertSurface(surface, &dst_fmt, 0);
|
||||||
if (dst) {
|
if (temp) {
|
||||||
SDL_UpdateTexture(texture, NULL, dst->pixels, dst->pitch);
|
SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
|
||||||
SDL_FreeSurface(dst);
|
SDL_FreeSurface(temp);
|
||||||
}
|
} else {
|
||||||
if (!dst) {
|
|
||||||
SDL_DestroyTexture(texture);
|
SDL_DestroyTexture(texture);
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ int main(int argc,char** argv)
|
||||||
for(i=0;i<num_pictures;i++)
|
for(i=0;i<num_pictures;i++)
|
||||||
pictures[i].texture = NULL;
|
pictures[i].texture = NULL;
|
||||||
for(i=0;i<num_pictures;i++) {
|
for(i=0;i<num_pictures;i++) {
|
||||||
pictures[i].texture = SDL_CreateTextureFromSurface(renderer,0,pictures[i].surface);
|
pictures[i].texture = SDL_CreateTextureFromSurface(renderer,pictures[i].surface);
|
||||||
if(pictures[i].texture == NULL) {
|
if(pictures[i].texture == NULL) {
|
||||||
j = 0;
|
j = 0;
|
||||||
for(j=0;j<num_pictures;i++)
|
for(j=0;j<num_pictures;i++)
|
||||||
|
|
|
@ -77,11 +77,7 @@ LoadSprite(char *file)
|
||||||
/* Create textures from the image */
|
/* Create textures from the image */
|
||||||
for (i = 0; i < state->num_windows; ++i) {
|
for (i = 0; i < state->num_windows; ++i) {
|
||||||
SDL_Renderer *renderer = state->renderers[i];
|
SDL_Renderer *renderer = state->renderers[i];
|
||||||
sprites[i] = SDL_CreateTextureFromSurface(renderer, 0, temp);
|
sprites[i] = SDL_CreateTextureFromSurface(renderer, temp);
|
||||||
if (!sprites[i]) {
|
|
||||||
SDL_SetColorKey(temp, 0, 0);
|
|
||||||
sprites[i] = SDL_CreateTextureFromSurface(renderer, 0, temp);
|
|
||||||
}
|
|
||||||
if (!sprites[i]) {
|
if (!sprites[i]) {
|
||||||
fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
|
fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
|
||||||
SDL_FreeSurface(temp);
|
SDL_FreeSurface(temp);
|
||||||
|
|
|
@ -60,11 +60,7 @@ LoadSprite(char *file, SDL_Renderer *renderer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create textures from the image */
|
/* Create textures from the image */
|
||||||
sprite = SDL_CreateTextureFromSurface(renderer, 0, temp);
|
sprite = SDL_CreateTextureFromSurface(renderer, temp);
|
||||||
if (!sprite) {
|
|
||||||
SDL_SetColorKey(temp, 0, 0);
|
|
||||||
sprite = SDL_CreateTextureFromSurface(renderer, 0, temp);
|
|
||||||
}
|
|
||||||
if (!sprite) {
|
if (!sprite) {
|
||||||
fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
|
fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
|
||||||
SDL_FreeSurface(temp);
|
SDL_FreeSurface(temp);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue