mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-03 08:28:29 +00:00
Added support for textures with palettes
Closes https://github.com/libsdl-org/SDL/pull/6192
This commit is contained in:
@@ -660,6 +660,7 @@ extern SDL_DECLSPEC SDL_Texture * SDLCALL SDL_CreateTextureFromSurface(SDL_Rende
|
|||||||
* pixels, required
|
* pixels, required
|
||||||
* - `SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER`: the height of the texture in
|
* - `SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER`: the height of the texture in
|
||||||
* pixels, required
|
* pixels, required
|
||||||
|
* - `SDL_PROP_TEXTURE_CREATE_PALETTE_POINTER`: an SDL_Palette to use with palettized texture formats. This can be set later with SDL_SetTexturePalette()
|
||||||
* - `SDL_PROP_TEXTURE_CREATE_SDR_WHITE_POINT_FLOAT`: for HDR10 and floating
|
* - `SDL_PROP_TEXTURE_CREATE_SDR_WHITE_POINT_FLOAT`: for HDR10 and floating
|
||||||
* point textures, this defines the value of 100% diffuse white, with higher
|
* point textures, this defines the value of 100% diffuse white, with higher
|
||||||
* values being displayed in the High Dynamic Range headroom. This defaults
|
* values being displayed in the High Dynamic Range headroom. This defaults
|
||||||
@@ -759,6 +760,7 @@ extern SDL_DECLSPEC SDL_Texture * SDLCALL SDL_CreateTextureWithProperties(SDL_Re
|
|||||||
#define SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER "SDL.texture.create.access"
|
#define SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER "SDL.texture.create.access"
|
||||||
#define SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER "SDL.texture.create.width"
|
#define SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER "SDL.texture.create.width"
|
||||||
#define SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER "SDL.texture.create.height"
|
#define SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER "SDL.texture.create.height"
|
||||||
|
#define SDL_PROP_TEXTURE_CREATE_PALETTE_POINTER "SDL.texture.create.palette"
|
||||||
#define SDL_PROP_TEXTURE_CREATE_SDR_WHITE_POINT_FLOAT "SDL.texture.create.SDR_white_point"
|
#define SDL_PROP_TEXTURE_CREATE_SDR_WHITE_POINT_FLOAT "SDL.texture.create.SDR_white_point"
|
||||||
#define SDL_PROP_TEXTURE_CREATE_HDR_HEADROOM_FLOAT "SDL.texture.create.HDR_headroom"
|
#define SDL_PROP_TEXTURE_CREATE_HDR_HEADROOM_FLOAT "SDL.texture.create.HDR_headroom"
|
||||||
#define SDL_PROP_TEXTURE_CREATE_D3D11_TEXTURE_POINTER "SDL.texture.create.d3d11.texture"
|
#define SDL_PROP_TEXTURE_CREATE_D3D11_TEXTURE_POINTER "SDL.texture.create.d3d11.texture"
|
||||||
@@ -929,6 +931,42 @@ extern SDL_DECLSPEC SDL_Renderer * SDLCALL SDL_GetRendererFromTexture(SDL_Textur
|
|||||||
*/
|
*/
|
||||||
extern SDL_DECLSPEC bool SDLCALL SDL_GetTextureSize(SDL_Texture *texture, float *w, float *h);
|
extern SDL_DECLSPEC bool SDLCALL SDL_GetTextureSize(SDL_Texture *texture, float *w, float *h);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the palette used by a texture.
|
||||||
|
*
|
||||||
|
* Setting the palette keeps an internal reference to the palette, which can be safely destroyed afterwards.
|
||||||
|
*
|
||||||
|
* A single palette can be shared with many textures.
|
||||||
|
*
|
||||||
|
* \param texture the texture to update.
|
||||||
|
* \param palette the SDL_Palette structure to use.
|
||||||
|
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* \threadsafety This function should only be called on the main thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.4.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_CreatePalette
|
||||||
|
* \sa SDL_GetTexturePalette
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_SetTexturePalette(SDL_Texture *texture, SDL_Palette *palette);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the palette used by a texture.
|
||||||
|
*
|
||||||
|
* \param texture the texture to query.
|
||||||
|
* \returns a pointer to the palette used by the texture, or NULL if there is
|
||||||
|
* no palette used.
|
||||||
|
*
|
||||||
|
* \threadsafety This function should only be called on the main thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.4.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_SetTexturePalette
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_Palette * SDLCALL SDL_GetTexturePalette(SDL_Texture *texture);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set an additional color value multiplied into render copy operations.
|
* Set an additional color value multiplied into render copy operations.
|
||||||
*
|
*
|
||||||
@@ -1157,7 +1195,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetTextureBlendMode(SDL_Texture *texture, S
|
|||||||
*
|
*
|
||||||
* The default texture scale mode is SDL_SCALEMODE_LINEAR.
|
* The default texture scale mode is SDL_SCALEMODE_LINEAR.
|
||||||
*
|
*
|
||||||
* If the scale mode is not supported, the closest supported mode is chosen.
|
* If the scale mode is not supported, the closest supported mode is chosen. Palettized textures will use SDL_SCALEMODE_PIXELART instead of SDL_SCALEMODE_LINEAR.
|
||||||
*
|
*
|
||||||
* \param texture the texture to update.
|
* \param texture the texture to update.
|
||||||
* \param scaleMode the SDL_ScaleMode to use for texture scaling.
|
* \param scaleMode the SDL_ScaleMode to use for texture scaling.
|
||||||
|
@@ -327,6 +327,8 @@ extern SDL_DECLSPEC SDL_Palette * SDLCALL SDL_CreateSurfacePalette(SDL_Surface *
|
|||||||
/**
|
/**
|
||||||
* Set the palette used by a surface.
|
* Set the palette used by a surface.
|
||||||
*
|
*
|
||||||
|
* Setting the palette keeps an internal reference to the palette, which can be safely destroyed afterwards.
|
||||||
|
*
|
||||||
* A single palette can be shared with many surfaces.
|
* A single palette can be shared with many surfaces.
|
||||||
*
|
*
|
||||||
* \param surface the SDL_Surface structure to update.
|
* \param surface the SDL_Surface structure to update.
|
||||||
|
@@ -1257,6 +1257,8 @@ SDL3_0.0.0 {
|
|||||||
SDL_hid_get_properties;
|
SDL_hid_get_properties;
|
||||||
SDL_GetPixelFormatFromGPUTextureFormat;
|
SDL_GetPixelFormatFromGPUTextureFormat;
|
||||||
SDL_GetGPUTextureFormatFromPixelFormat;
|
SDL_GetGPUTextureFormatFromPixelFormat;
|
||||||
|
SDL_SetTexturePalette;
|
||||||
|
SDL_GetTexturePalette;
|
||||||
# extra symbols go here (don't modify this line)
|
# extra symbols go here (don't modify this line)
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
@@ -1283,3 +1283,5 @@
|
|||||||
#define SDL_GetPixelFormatFromGPUTextureFormat SDL_GetPixelFormatFromGPUTextureFormat_REAL
|
#define SDL_GetPixelFormatFromGPUTextureFormat SDL_GetPixelFormatFromGPUTextureFormat_REAL
|
||||||
#define SDL_GetGPUTextureFormatFromPixelFormat SDL_GetGPUTextureFormatFromPixelFormat_REAL
|
#define SDL_GetGPUTextureFormatFromPixelFormat SDL_GetGPUTextureFormatFromPixelFormat_REAL
|
||||||
#define JNI_OnLoad JNI_OnLoad_REAL
|
#define JNI_OnLoad JNI_OnLoad_REAL
|
||||||
|
#define SDL_SetTexturePalette SDL_SetTexturePalette_REAL
|
||||||
|
#define SDL_GetTexturePalette SDL_GetTexturePalette_REAL
|
||||||
|
@@ -1291,3 +1291,5 @@ SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_hid_get_properties,(SDL_hid_device *a),(a),
|
|||||||
SDL_DYNAPI_PROC(SDL_PixelFormat,SDL_GetPixelFormatFromGPUTextureFormat,(SDL_GPUTextureFormat a),(a),return)
|
SDL_DYNAPI_PROC(SDL_PixelFormat,SDL_GetPixelFormatFromGPUTextureFormat,(SDL_GPUTextureFormat a),(a),return)
|
||||||
SDL_DYNAPI_PROC(SDL_GPUTextureFormat,SDL_GetGPUTextureFormatFromPixelFormat,(SDL_PixelFormat a),(a),return)
|
SDL_DYNAPI_PROC(SDL_GPUTextureFormat,SDL_GetGPUTextureFormatFromPixelFormat,(SDL_PixelFormat a),(a),return)
|
||||||
SDL_DYNAPI_PROC(Sint32,JNI_OnLoad,(JavaVM *a, void *b),(a,b),return)
|
SDL_DYNAPI_PROC(Sint32,JNI_OnLoad,(JavaVM *a, void *b),(a,b),return)
|
||||||
|
SDL_DYNAPI_PROC(bool,SDL_SetTexturePalette,(SDL_Texture *a,SDL_Palette *b),(a,b),return)
|
||||||
|
SDL_DYNAPI_PROC(SDL_Palette*,SDL_GetTexturePalette,(SDL_Texture *a),(a),return)
|
||||||
|
@@ -697,6 +697,46 @@ static bool QueueCmdFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, co
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool UpdateTexturePalette(SDL_Texture *texture)
|
||||||
|
{
|
||||||
|
SDL_Renderer *renderer = texture->renderer;
|
||||||
|
|
||||||
|
if (!SDL_ISPIXELFORMAT_INDEXED(texture->format)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!texture->palette) {
|
||||||
|
return SDL_SetError("Texture doesn't have a palette");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture->palette_version == texture->palette->version) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture->native) {
|
||||||
|
if (!FlushRenderCommandsIfTextureNeeded(texture->native)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface *surface;
|
||||||
|
bool result = SDL_LockTextureToSurface(texture->native, NULL, &surface);
|
||||||
|
if (result) {
|
||||||
|
result = SDL_BlitSurface(texture->palette_surface, NULL, surface, NULL);
|
||||||
|
SDL_UnlockTexture(texture->native);
|
||||||
|
}
|
||||||
|
if (!result) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!renderer->UpdateTexturePalette(renderer, texture)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->palette_version = texture->palette->version;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool QueueCmdCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FRect *srcrect, const SDL_FRect *dstrect)
|
static bool QueueCmdCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FRect *srcrect, const SDL_FRect *dstrect)
|
||||||
{
|
{
|
||||||
SDL_RenderCommand *cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_COPY, texture);
|
SDL_RenderCommand *cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_COPY, texture);
|
||||||
@@ -1408,6 +1448,7 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
|
|||||||
SDL_TextureAccess access = (SDL_TextureAccess)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
|
SDL_TextureAccess access = (SDL_TextureAccess)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
|
||||||
int w = (int)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, 0);
|
int w = (int)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, 0);
|
||||||
int h = (int)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, 0);
|
int h = (int)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, 0);
|
||||||
|
SDL_Palette *palette = (SDL_Palette *)SDL_GetPointerProperty(props, SDL_PROP_TEXTURE_CREATE_PALETTE_POINTER, NULL);
|
||||||
SDL_Colorspace default_colorspace;
|
SDL_Colorspace default_colorspace;
|
||||||
bool texture_is_fourcc_and_target;
|
bool texture_is_fourcc_and_target;
|
||||||
|
|
||||||
@@ -1421,8 +1462,8 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
|
|||||||
SDL_SetError("Invalid texture format");
|
SDL_SetError("Invalid texture format");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
CHECK_PARAM(SDL_ISPIXELFORMAT_INDEXED(format) && !IsSupportedFormat(renderer, format)) {
|
CHECK_PARAM(SDL_ISPIXELFORMAT_INDEXED(format) && access == SDL_TEXTUREACCESS_TARGET) {
|
||||||
SDL_SetError("Palettized textures are not supported");
|
SDL_SetError("Palettized textures can't be render targets");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
CHECK_PARAM(w <= 0 || h <= 0) {
|
CHECK_PARAM(w <= 0 || h <= 0) {
|
||||||
@@ -1453,7 +1494,12 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
|
|||||||
texture->color.b = 1.0f;
|
texture->color.b = 1.0f;
|
||||||
texture->color.a = 1.0f;
|
texture->color.a = 1.0f;
|
||||||
texture->blendMode = SDL_ISPIXELFORMAT_ALPHA(format) ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE;
|
texture->blendMode = SDL_ISPIXELFORMAT_ALPHA(format) ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE;
|
||||||
|
if (renderer->scale_mode == SDL_SCALEMODE_LINEAR &&
|
||||||
|
SDL_ISPIXELFORMAT_INDEXED(format)) {
|
||||||
|
texture->scaleMode = SDL_SCALEMODE_PIXELART;
|
||||||
|
} else {
|
||||||
texture->scaleMode = renderer->scale_mode;
|
texture->scaleMode = renderer->scale_mode;
|
||||||
|
}
|
||||||
texture->view.pixel_w = w;
|
texture->view.pixel_w = w;
|
||||||
texture->view.pixel_h = h;
|
texture->view.pixel_h = h;
|
||||||
texture->view.viewport.w = -1;
|
texture->view.viewport.w = -1;
|
||||||
@@ -1506,7 +1552,12 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SDL_SetNumberProperty(native_props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, closest_format);
|
SDL_SetNumberProperty(native_props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, closest_format);
|
||||||
|
if (SDL_ISPIXELFORMAT_INDEXED(texture->format)) {
|
||||||
|
// We're going to be uploading pixels frequently as the palette changes
|
||||||
|
SDL_SetNumberProperty(native_props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STREAMING);
|
||||||
|
} else {
|
||||||
SDL_SetNumberProperty(native_props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, texture->access);
|
SDL_SetNumberProperty(native_props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, texture->access);
|
||||||
|
}
|
||||||
SDL_SetNumberProperty(native_props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, texture->w);
|
SDL_SetNumberProperty(native_props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, texture->w);
|
||||||
SDL_SetNumberProperty(native_props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, texture->h);
|
SDL_SetNumberProperty(native_props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, texture->h);
|
||||||
|
|
||||||
@@ -1532,6 +1583,8 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
|
|||||||
texture->next = texture->native;
|
texture->next = texture->native;
|
||||||
renderer->textures = texture;
|
renderer->textures = texture;
|
||||||
|
|
||||||
|
SDL_SetTextureScaleMode(texture->native, texture->scaleMode);
|
||||||
|
|
||||||
if (texture->format == SDL_PIXELFORMAT_MJPG) {
|
if (texture->format == SDL_PIXELFORMAT_MJPG) {
|
||||||
// We have a custom decode + upload path for this
|
// We have a custom decode + upload path for this
|
||||||
} else if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
|
} else if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
|
||||||
@@ -1544,6 +1597,12 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
|
|||||||
SDL_DestroyTexture(texture);
|
SDL_DestroyTexture(texture);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
} else if (SDL_ISPIXELFORMAT_INDEXED(texture->format)) {
|
||||||
|
texture->palette_surface = SDL_CreateSurface(w, h, texture->format);
|
||||||
|
if (!texture->palette_surface) {
|
||||||
|
SDL_DestroyTexture(texture);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
} else if (access == SDL_TEXTUREACCESS_STREAMING) {
|
} else if (access == SDL_TEXTUREACCESS_STREAMING) {
|
||||||
// The pitch is 4 byte aligned
|
// The pitch is 4 byte aligned
|
||||||
texture->pitch = (((w * SDL_BYTESPERPIXEL(format)) + 3) & ~3);
|
texture->pitch = (((w * SDL_BYTESPERPIXEL(format)) + 3) & ~3);
|
||||||
@@ -1555,6 +1614,10 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SDL_ISPIXELFORMAT_INDEXED(texture->format) && palette) {
|
||||||
|
SDL_SetTexturePalette(texture, palette);
|
||||||
|
}
|
||||||
|
|
||||||
// Now set the properties for the new texture
|
// Now set the properties for the new texture
|
||||||
props = SDL_GetTextureProperties(texture);
|
props = SDL_GetTextureProperties(texture);
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_COLORSPACE_NUMBER, texture->colorspace);
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_COLORSPACE_NUMBER, texture->colorspace);
|
||||||
@@ -1584,50 +1647,11 @@ SDL_Texture *SDL_CreateTexture(SDL_Renderer *renderer, SDL_PixelFormat format, S
|
|||||||
|
|
||||||
static bool SDL_UpdateTextureFromSurface(SDL_Texture *texture, SDL_Rect *rect, SDL_Surface *surface)
|
static bool SDL_UpdateTextureFromSurface(SDL_Texture *texture, SDL_Rect *rect, SDL_Surface *surface)
|
||||||
{
|
{
|
||||||
SDL_TextureAccess access;
|
|
||||||
bool direct_update;
|
bool direct_update;
|
||||||
SDL_PixelFormat tex_format;
|
|
||||||
SDL_PropertiesID surface_props;
|
|
||||||
SDL_PropertiesID tex_props;
|
|
||||||
SDL_Colorspace surface_colorspace = SDL_COLORSPACE_UNKNOWN;
|
|
||||||
SDL_Colorspace texture_colorspace = SDL_COLORSPACE_UNKNOWN;
|
|
||||||
|
|
||||||
if (texture == NULL || surface == NULL) {
|
if (surface->format == texture->format &&
|
||||||
return false;
|
surface->palette == texture->palette &&
|
||||||
}
|
SDL_GetSurfaceColorspace(surface) == texture->colorspace) {
|
||||||
|
|
||||||
tex_props = SDL_GetTextureProperties(texture);
|
|
||||||
if (!tex_props) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface_props = SDL_GetSurfaceProperties(surface);
|
|
||||||
if (!surface_props) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
tex_format = (SDL_PixelFormat)SDL_GetNumberProperty(tex_props, SDL_PROP_TEXTURE_FORMAT_NUMBER, 0);
|
|
||||||
access = (SDL_TextureAccess)SDL_GetNumberProperty(tex_props, SDL_PROP_TEXTURE_ACCESS_NUMBER, 0);
|
|
||||||
|
|
||||||
if (access != SDL_TEXTUREACCESS_STATIC && access != SDL_TEXTUREACCESS_STREAMING) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface_colorspace = SDL_GetSurfaceColorspace(surface);
|
|
||||||
texture_colorspace = surface_colorspace;
|
|
||||||
|
|
||||||
if (surface_colorspace == SDL_COLORSPACE_SRGB_LINEAR ||
|
|
||||||
SDL_COLORSPACETRANSFER(surface_colorspace) == SDL_TRANSFER_CHARACTERISTICS_PQ) {
|
|
||||||
if (SDL_ISPIXELFORMAT_FLOAT(tex_format)) {
|
|
||||||
texture_colorspace = SDL_COLORSPACE_SRGB_LINEAR;
|
|
||||||
} else if (SDL_ISPIXELFORMAT_10BIT(tex_format)) {
|
|
||||||
texture_colorspace = SDL_COLORSPACE_HDR10;
|
|
||||||
} else {
|
|
||||||
texture_colorspace = SDL_COLORSPACE_SRGB;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tex_format == surface->format && texture_colorspace == surface_colorspace) {
|
|
||||||
if (SDL_ISPIXELFORMAT_ALPHA(surface->format) && SDL_SurfaceHasColorKey(surface)) {
|
if (SDL_ISPIXELFORMAT_ALPHA(surface->format) && SDL_SurfaceHasColorKey(surface)) {
|
||||||
/* Surface and Renderer formats are identical.
|
/* Surface and Renderer formats are identical.
|
||||||
* Intermediate conversion is needed to convert color key to alpha (SDL_ConvertColorkeyToAlpha()). */
|
* Intermediate conversion is needed to convert color key to alpha (SDL_ConvertColorkeyToAlpha()). */
|
||||||
@@ -1643,17 +1667,16 @@ static bool SDL_UpdateTextureFromSurface(SDL_Texture *texture, SDL_Rect *rect, S
|
|||||||
|
|
||||||
if (direct_update) {
|
if (direct_update) {
|
||||||
if (SDL_MUSTLOCK(surface)) {
|
if (SDL_MUSTLOCK(surface)) {
|
||||||
SDL_LockSurface(surface);
|
if (SDL_LockSurface(surface)) {
|
||||||
SDL_UpdateTexture(texture, rect, surface->pixels, surface->pitch);
|
SDL_UpdateTexture(texture, rect, surface->pixels, surface->pitch);
|
||||||
SDL_UnlockSurface(surface);
|
SDL_UnlockSurface(surface);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
SDL_UpdateTexture(texture, rect, surface->pixels, surface->pitch);
|
SDL_UpdateTexture(texture, rect, surface->pixels, surface->pitch);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SDL_Surface *temp = NULL;
|
|
||||||
|
|
||||||
// Set up a destination surface for the texture update
|
// Set up a destination surface for the texture update
|
||||||
temp = SDL_ConvertSurfaceAndColorspace(surface, tex_format, NULL, texture_colorspace, surface_props);
|
SDL_Surface *temp = SDL_ConvertSurfaceAndColorspace(surface, texture->format, texture->palette, texture->colorspace, SDL_GetSurfaceProperties(surface));
|
||||||
if (temp) {
|
if (temp) {
|
||||||
SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
|
SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
|
||||||
SDL_DestroySurface(temp);
|
SDL_DestroySurface(temp);
|
||||||
@@ -1709,7 +1732,7 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s
|
|||||||
needAlpha = false;
|
needAlpha = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If Palette contains alpha values, promotes to alpha format
|
// If palette contains alpha values, promotes to alpha format
|
||||||
palette = SDL_GetSurfacePalette(surface);
|
palette = SDL_GetSurfacePalette(surface);
|
||||||
if (palette) {
|
if (palette) {
|
||||||
bool is_opaque, has_alpha_channel;
|
bool is_opaque, has_alpha_channel;
|
||||||
@@ -1806,6 +1829,9 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s
|
|||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, surface->w);
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, surface->w);
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, surface->h);
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, surface->h);
|
||||||
|
if (format == surface->format && palette) {
|
||||||
|
SDL_SetPointerProperty(props, SDL_PROP_TEXTURE_CREATE_PALETTE_POINTER, palette);
|
||||||
|
}
|
||||||
texture = SDL_CreateTextureWithProperties(renderer, props);
|
texture = SDL_CreateTextureWithProperties(renderer, props);
|
||||||
SDL_DestroyProperties(props);
|
SDL_DestroyProperties(props);
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
@@ -1857,6 +1883,44 @@ bool SDL_GetTextureSize(SDL_Texture *texture, float *w, float *h)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SDL_SetTexturePalette(SDL_Texture *texture, SDL_Palette *palette)
|
||||||
|
{
|
||||||
|
CHECK_TEXTURE_MAGIC(texture, false);
|
||||||
|
|
||||||
|
CHECK_PARAM(!SDL_ISPIXELFORMAT_INDEXED(texture->format)) {
|
||||||
|
return SDL_SetError("Texture isn't palettized format");
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_PARAM(palette && palette->ncolors > (1 << SDL_BITSPERPIXEL(texture->format))) {
|
||||||
|
return SDL_SetError("SDL_SetSurfacePalette() passed a palette that doesn't match the surface format");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (palette != texture->palette) {
|
||||||
|
if (texture->palette) {
|
||||||
|
SDL_DestroyPalette(texture->palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->palette = palette;
|
||||||
|
texture->palette_version = 0;
|
||||||
|
|
||||||
|
if (texture->palette) {
|
||||||
|
++texture->palette->refcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture->palette_surface) {
|
||||||
|
SDL_SetSurfacePalette(texture->palette_surface, palette);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Palette *SDL_GetTexturePalette(SDL_Texture *texture)
|
||||||
|
{
|
||||||
|
CHECK_TEXTURE_MAGIC(texture, NULL);
|
||||||
|
|
||||||
|
return texture->palette;
|
||||||
|
}
|
||||||
|
|
||||||
bool SDL_SetTextureColorMod(SDL_Texture *texture, Uint8 r, Uint8 g, Uint8 b)
|
bool SDL_SetTextureColorMod(SDL_Texture *texture, Uint8 r, Uint8 g, Uint8 b)
|
||||||
{
|
{
|
||||||
const float fR = (float)r / 255.0f;
|
const float fR = (float)r / 255.0f;
|
||||||
@@ -2028,9 +2092,13 @@ bool SDL_SetTextureScaleMode(SDL_Texture *texture, SDL_ScaleMode scaleMode)
|
|||||||
|
|
||||||
switch (scaleMode) {
|
switch (scaleMode) {
|
||||||
case SDL_SCALEMODE_NEAREST:
|
case SDL_SCALEMODE_NEAREST:
|
||||||
case SDL_SCALEMODE_LINEAR:
|
|
||||||
case SDL_SCALEMODE_PIXELART:
|
case SDL_SCALEMODE_PIXELART:
|
||||||
break;
|
break;
|
||||||
|
case SDL_SCALEMODE_LINEAR:
|
||||||
|
if (SDL_ISPIXELFORMAT_INDEXED(texture->format)) {
|
||||||
|
scaleMode = SDL_SCALEMODE_PIXELART;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return SDL_InvalidParamError("scaleMode");
|
return SDL_InvalidParamError("scaleMode");
|
||||||
}
|
}
|
||||||
@@ -2046,7 +2114,7 @@ bool SDL_SetTextureScaleMode(SDL_Texture *texture, SDL_ScaleMode scaleMode)
|
|||||||
bool SDL_GetTextureScaleMode(SDL_Texture *texture, SDL_ScaleMode *scaleMode)
|
bool SDL_GetTextureScaleMode(SDL_Texture *texture, SDL_ScaleMode *scaleMode)
|
||||||
{
|
{
|
||||||
if (scaleMode) {
|
if (scaleMode) {
|
||||||
*scaleMode = SDL_SCALEMODE_LINEAR;
|
*scaleMode = SDL_SCALEMODE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_TEXTURE_MAGIC(texture, false);
|
CHECK_TEXTURE_MAGIC(texture, false);
|
||||||
@@ -2105,15 +2173,27 @@ static bool SDL_UpdateTextureYUV(SDL_Texture *texture, const SDL_Rect *rect,
|
|||||||
}
|
}
|
||||||
#endif // SDL_HAVE_YUV
|
#endif // SDL_HAVE_YUV
|
||||||
|
|
||||||
static bool SDL_UpdateTextureNative(SDL_Texture *texture, const SDL_Rect *rect,
|
static bool SDL_UpdateTexturePaletteSurface(SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
|
||||||
const void *pixels, int pitch)
|
{
|
||||||
|
SDL_Surface *surface = texture->palette_surface;
|
||||||
|
|
||||||
|
const Uint8 *src = (const Uint8 *)pixels;
|
||||||
|
Uint8 *dst = ((Uint8 *)surface->pixels) + rect->y * surface->pitch + (rect->x * SDL_BITSPERPIXEL(texture->format)) / 8;
|
||||||
|
int w = ((rect->w * SDL_BITSPERPIXEL(texture->format)) + 7) / 8;
|
||||||
|
int h = rect->h;
|
||||||
|
while (h--) {
|
||||||
|
SDL_memcpy(dst, src, w);
|
||||||
|
src += pitch;
|
||||||
|
dst += surface->pitch;
|
||||||
|
}
|
||||||
|
texture->palette_version = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SDL_UpdateTextureNative(SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
|
||||||
{
|
{
|
||||||
SDL_Texture *native = texture->native;
|
SDL_Texture *native = texture->native;
|
||||||
|
|
||||||
if (!rect->w || !rect->h) {
|
|
||||||
return true; // nothing to do.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
|
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
|
||||||
// We can lock the texture and copy to it
|
// We can lock the texture and copy to it
|
||||||
void *native_pixels = NULL;
|
void *native_pixels = NULL;
|
||||||
@@ -2174,6 +2254,8 @@ bool SDL_UpdateTexture(SDL_Texture *texture, const SDL_Rect *rect, const void *p
|
|||||||
} else if (texture->yuv) {
|
} else if (texture->yuv) {
|
||||||
return SDL_UpdateTextureYUV(texture, &real_rect, pixels, pitch);
|
return SDL_UpdateTextureYUV(texture, &real_rect, pixels, pitch);
|
||||||
#endif
|
#endif
|
||||||
|
} else if (texture->palette_surface) {
|
||||||
|
return SDL_UpdateTexturePaletteSurface(texture, &real_rect, pixels, pitch);
|
||||||
} else if (texture->native) {
|
} else if (texture->native) {
|
||||||
return SDL_UpdateTextureNative(texture, &real_rect, pixels, pitch);
|
return SDL_UpdateTextureNative(texture, &real_rect, pixels, pitch);
|
||||||
} else {
|
} else {
|
||||||
@@ -2426,8 +2508,16 @@ static bool SDL_LockTextureYUV(SDL_Texture *texture, const SDL_Rect *rect,
|
|||||||
}
|
}
|
||||||
#endif // SDL_HAVE_YUV
|
#endif // SDL_HAVE_YUV
|
||||||
|
|
||||||
static bool SDL_LockTextureNative(SDL_Texture *texture, const SDL_Rect *rect,
|
static bool SDL_LockTexturePaletteSurface(SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
|
||||||
void **pixels, int *pitch)
|
{
|
||||||
|
SDL_Surface *surface = texture->palette_surface;
|
||||||
|
|
||||||
|
*pixels = ((Uint8 *)surface->pixels) + rect->y * surface->pitch + (rect->x * SDL_BITSPERPIXEL(texture->format)) / 8;
|
||||||
|
*pitch = surface->pitch;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SDL_LockTextureNative(SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
|
||||||
{
|
{
|
||||||
texture->locked_rect = *rect;
|
texture->locked_rect = *rect;
|
||||||
*pixels = (void *)((Uint8 *)texture->pixels +
|
*pixels = (void *)((Uint8 *)texture->pixels +
|
||||||
@@ -2463,7 +2553,9 @@ bool SDL_LockTexture(SDL_Texture *texture, const SDL_Rect *rect, void **pixels,
|
|||||||
return SDL_LockTextureYUV(texture, rect, pixels, pitch);
|
return SDL_LockTextureYUV(texture, rect, pixels, pitch);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (texture->native) {
|
if (texture->palette_surface) {
|
||||||
|
return SDL_LockTexturePaletteSurface(texture, rect, pixels, pitch);
|
||||||
|
} else if (texture->native) {
|
||||||
// Calls a real SDL_LockTexture/SDL_UnlockTexture on unlock, flushing then.
|
// Calls a real SDL_LockTexture/SDL_UnlockTexture on unlock, flushing then.
|
||||||
return SDL_LockTextureNative(texture, rect, pixels, pitch);
|
return SDL_LockTextureNative(texture, rect, pixels, pitch);
|
||||||
} else {
|
} else {
|
||||||
@@ -2504,6 +2596,9 @@ bool SDL_LockTextureToSurface(SDL_Texture *texture, const SDL_Rect *rect, SDL_Su
|
|||||||
SDL_UnlockTexture(texture);
|
SDL_UnlockTexture(texture);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (texture->palette) {
|
||||||
|
SDL_SetSurfacePalette(texture->locked_surface, texture->palette);
|
||||||
|
}
|
||||||
|
|
||||||
*surface = texture->locked_surface;
|
*surface = texture->locked_surface;
|
||||||
return true;
|
return true;
|
||||||
@@ -2531,6 +2626,11 @@ static void SDL_UnlockTextureYUV(SDL_Texture *texture)
|
|||||||
}
|
}
|
||||||
#endif // SDL_HAVE_YUV
|
#endif // SDL_HAVE_YUV
|
||||||
|
|
||||||
|
static void SDL_UnlockTexturePaletteSurface(SDL_Texture *texture)
|
||||||
|
{
|
||||||
|
texture->palette_version = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void SDL_UnlockTextureNative(SDL_Texture *texture)
|
static void SDL_UnlockTextureNative(SDL_Texture *texture)
|
||||||
{
|
{
|
||||||
SDL_Texture *native = texture->native;
|
SDL_Texture *native = texture->native;
|
||||||
@@ -2564,16 +2664,20 @@ void SDL_UnlockTexture(SDL_Texture *texture)
|
|||||||
SDL_UnlockTextureYUV(texture);
|
SDL_UnlockTextureYUV(texture);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (texture->native) {
|
if (texture->palette_surface) {
|
||||||
|
SDL_UnlockTexturePaletteSurface(texture);
|
||||||
|
} else if (texture->native) {
|
||||||
SDL_UnlockTextureNative(texture);
|
SDL_UnlockTextureNative(texture);
|
||||||
} else {
|
} else {
|
||||||
SDL_Renderer *renderer = texture->renderer;
|
SDL_Renderer *renderer = texture->renderer;
|
||||||
renderer->UnlockTexture(renderer, texture);
|
renderer->UnlockTexture(renderer, texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (texture->locked_surface) {
|
||||||
SDL_DestroySurface(texture->locked_surface);
|
SDL_DestroySurface(texture->locked_surface);
|
||||||
texture->locked_surface = NULL;
|
texture->locked_surface = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
|
bool SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||||
{
|
{
|
||||||
@@ -3938,6 +4042,10 @@ bool SDL_RenderTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_F
|
|||||||
dstrect = &full_dstrect;
|
dstrect = &full_dstrect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!UpdateTexturePalette(texture)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (texture->native) {
|
if (texture->native) {
|
||||||
texture = texture->native;
|
texture = texture->native;
|
||||||
}
|
}
|
||||||
@@ -3983,6 +4091,10 @@ bool SDL_RenderTextureAffine(SDL_Renderer *renderer, SDL_Texture *texture,
|
|||||||
|
|
||||||
GetRenderViewportSize(renderer, &real_dstrect);
|
GetRenderViewportSize(renderer, &real_dstrect);
|
||||||
|
|
||||||
|
if (!UpdateTexturePalette(texture)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (texture->native) {
|
if (texture->native) {
|
||||||
texture = texture->native;
|
texture = texture->native;
|
||||||
}
|
}
|
||||||
@@ -4111,6 +4223,10 @@ bool SDL_RenderTextureRotated(SDL_Renderer *renderer, SDL_Texture *texture,
|
|||||||
dstrect = &full_dstrect;
|
dstrect = &full_dstrect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!UpdateTexturePalette(texture)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (texture->native) {
|
if (texture->native) {
|
||||||
texture = texture->native;
|
texture = texture->native;
|
||||||
}
|
}
|
||||||
@@ -4367,6 +4483,10 @@ bool SDL_RenderTextureTiled(SDL_Renderer *renderer, SDL_Texture *texture, const
|
|||||||
dstrect = &full_dstrect;
|
dstrect = &full_dstrect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!UpdateTexturePalette(texture)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (texture->native) {
|
if (texture->native) {
|
||||||
texture = texture->native;
|
texture = texture->native;
|
||||||
}
|
}
|
||||||
@@ -5137,9 +5257,15 @@ bool SDL_RenderGeometryRaw(SDL_Renderer *renderer,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (texture && texture->native) {
|
if (texture) {
|
||||||
|
if (!UpdateTexturePalette(texture)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture->native) {
|
||||||
texture = texture->native;
|
texture = texture->native;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
texture_address_mode_u = renderer->texture_address_mode_u;
|
texture_address_mode_u = renderer->texture_address_mode_u;
|
||||||
texture_address_mode_v = renderer->texture_address_mode_v;
|
texture_address_mode_v = renderer->texture_address_mode_v;
|
||||||
@@ -5381,6 +5507,10 @@ static void SDL_DestroyTextureInternal(SDL_Texture *texture, bool is_destroying)
|
|||||||
{
|
{
|
||||||
SDL_Renderer *renderer;
|
SDL_Renderer *renderer;
|
||||||
|
|
||||||
|
if (texture->palette) {
|
||||||
|
SDL_SetTexturePalette(texture, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_DestroyProperties(texture->props);
|
SDL_DestroyProperties(texture->props);
|
||||||
|
|
||||||
renderer = texture->renderer;
|
renderer = texture->renderer;
|
||||||
@@ -5417,8 +5547,14 @@ static void SDL_DestroyTextureInternal(SDL_Texture *texture, bool is_destroying)
|
|||||||
|
|
||||||
renderer->DestroyTexture(renderer, texture);
|
renderer->DestroyTexture(renderer, texture);
|
||||||
|
|
||||||
|
if (texture->palette_surface) {
|
||||||
|
SDL_DestroySurface(texture->palette_surface);
|
||||||
|
texture->palette_surface = NULL;
|
||||||
|
}
|
||||||
|
if (texture->locked_surface) {
|
||||||
SDL_DestroySurface(texture->locked_surface);
|
SDL_DestroySurface(texture->locked_surface);
|
||||||
texture->locked_surface = NULL;
|
texture->locked_surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_free(texture);
|
SDL_free(texture);
|
||||||
}
|
}
|
||||||
|
@@ -81,6 +81,7 @@ struct SDL_Texture
|
|||||||
int refcount; /**< Application reference count, used when freeing texture */
|
int refcount; /**< Application reference count, used when freeing texture */
|
||||||
|
|
||||||
// Private API definition
|
// Private API definition
|
||||||
|
SDL_Renderer *renderer;
|
||||||
SDL_Colorspace colorspace; // The colorspace of the texture
|
SDL_Colorspace colorspace; // The colorspace of the texture
|
||||||
float SDR_white_point; // The SDR white point for this content
|
float SDR_white_point; // The SDR white point for this content
|
||||||
float HDR_headroom; // The HDR headroom needed by this content
|
float HDR_headroom; // The HDR headroom needed by this content
|
||||||
@@ -89,8 +90,9 @@ struct SDL_Texture
|
|||||||
SDL_ScaleMode scaleMode; // The texture scale mode
|
SDL_ScaleMode scaleMode; // The texture scale mode
|
||||||
SDL_FColor color; // Texture modulation values
|
SDL_FColor color; // Texture modulation values
|
||||||
SDL_RenderViewState view; // Target texture view state
|
SDL_RenderViewState view; // Target texture view state
|
||||||
|
SDL_Palette *palette;
|
||||||
SDL_Renderer *renderer;
|
Uint32 palette_version;
|
||||||
|
SDL_Surface *palette_surface;
|
||||||
|
|
||||||
// Support for formats not supported directly by the renderer
|
// Support for formats not supported directly by the renderer
|
||||||
SDL_Texture *native;
|
SDL_Texture *native;
|
||||||
@@ -233,6 +235,7 @@ struct SDL_Renderer
|
|||||||
|
|
||||||
void (*InvalidateCachedState)(SDL_Renderer *renderer);
|
void (*InvalidateCachedState)(SDL_Renderer *renderer);
|
||||||
bool (*RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize);
|
bool (*RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize);
|
||||||
|
bool (*UpdateTexturePalette)(SDL_Renderer *renderer, SDL_Texture *texture);
|
||||||
bool (*UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture,
|
bool (*UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||||
const SDL_Rect *rect, const void *pixels,
|
const SDL_Rect *rect, const void *pixels,
|
||||||
int pitch);
|
int pitch);
|
||||||
|
@@ -126,6 +126,20 @@ static bool SW_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool SW_UpdateTexturePalette(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||||
|
{
|
||||||
|
SDL_Surface *surface = (SDL_Surface *)texture->internal;
|
||||||
|
SDL_Palette *palette = texture->palette;
|
||||||
|
|
||||||
|
if (!surface->palette) {
|
||||||
|
surface->palette = SDL_CreatePalette(1 << SDL_BITSPERPIXEL(surface->format));
|
||||||
|
if (!surface->palette) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SDL_SetPaletteColors(surface->palette, palette->colors, 0, palette->ncolors);
|
||||||
|
}
|
||||||
|
|
||||||
static bool SW_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
static bool SW_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||||
const SDL_Rect *rect, const void *pixels, int pitch)
|
const SDL_Rect *rect, const void *pixels, int pitch)
|
||||||
{
|
{
|
||||||
@@ -1115,6 +1129,9 @@ static void SW_SelectBestFormats(SDL_Renderer *renderer, SDL_PixelFormat format)
|
|||||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_XRGB8888);
|
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_XRGB8888);
|
||||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_ARGB8888);
|
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_ARGB8888);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add 8-bit palettized format
|
||||||
|
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_INDEX8);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SW_CreateRendererForSurface(SDL_Renderer *renderer, SDL_Surface *surface, SDL_PropertiesID create_props)
|
bool SW_CreateRendererForSurface(SDL_Renderer *renderer, SDL_Surface *surface, SDL_PropertiesID create_props)
|
||||||
@@ -1142,6 +1159,7 @@ bool SW_CreateRendererForSurface(SDL_Renderer *renderer, SDL_Surface *surface, S
|
|||||||
renderer->WindowEvent = SW_WindowEvent;
|
renderer->WindowEvent = SW_WindowEvent;
|
||||||
renderer->GetOutputSize = SW_GetOutputSize;
|
renderer->GetOutputSize = SW_GetOutputSize;
|
||||||
renderer->CreateTexture = SW_CreateTexture;
|
renderer->CreateTexture = SW_CreateTexture;
|
||||||
|
renderer->UpdateTexturePalette = SW_UpdateTexturePalette;
|
||||||
renderer->UpdateTexture = SW_UpdateTexture;
|
renderer->UpdateTexture = SW_UpdateTexture;
|
||||||
renderer->LockTexture = SW_LockTexture;
|
renderer->LockTexture = SW_LockTexture;
|
||||||
renderer->UnlockTexture = SW_UnlockTexture;
|
renderer->UnlockTexture = SW_UnlockTexture;
|
||||||
|
@@ -403,6 +403,7 @@ add_sdl_test_executable(testsoftwaretransparent SOURCES testsoftwaretransparent.
|
|||||||
add_sdl_test_executable(testsprite MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testsprite.c)
|
add_sdl_test_executable(testsprite MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testsprite.c)
|
||||||
add_sdl_test_executable(testspriteminimal SOURCES testspriteminimal.c ${icon_bmp_header} DEPENDS generate-icon_bmp_header)
|
add_sdl_test_executable(testspriteminimal SOURCES testspriteminimal.c ${icon_bmp_header} DEPENDS generate-icon_bmp_header)
|
||||||
add_sdl_test_executable(testspritesurface SOURCES testspritesurface.c ${icon_bmp_header} DEPENDS generate-icon_bmp_header)
|
add_sdl_test_executable(testspritesurface SOURCES testspritesurface.c ${icon_bmp_header} DEPENDS generate-icon_bmp_header)
|
||||||
|
add_sdl_test_executable(testpalette SOURCES testpalette.c)
|
||||||
add_sdl_test_executable(teststreaming NEEDS_RESOURCES TESTUTILS SOURCES teststreaming.c)
|
add_sdl_test_executable(teststreaming NEEDS_RESOURCES TESTUTILS SOURCES teststreaming.c)
|
||||||
add_sdl_test_executable(testtimer NONINTERACTIVE NONINTERACTIVE_ARGS --no-interactive NONINTERACTIVE_TIMEOUT 60 SOURCES testtimer.c)
|
add_sdl_test_executable(testtimer NONINTERACTIVE NONINTERACTIVE_ARGS --no-interactive NONINTERACTIVE_TIMEOUT 60 SOURCES testtimer.c)
|
||||||
add_sdl_test_executable(testurl SOURCES testurl.c)
|
add_sdl_test_executable(testurl SOURCES testurl.c)
|
||||||
|
448
test/testpalette.c
Normal file
448
test/testpalette.c
Normal file
@@ -0,0 +1,448 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely.
|
||||||
|
*/
|
||||||
|
/* Simple program: Move N sprites around on the screen as fast as possible */
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#include <SDL3/SDL_main.h>
|
||||||
|
|
||||||
|
#ifdef SDL_PLATFORM_EMSCRIPTEN
|
||||||
|
#include <emscripten/emscripten.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define WINDOW_WIDTH 640
|
||||||
|
#define WINDOW_HEIGHT 480
|
||||||
|
|
||||||
|
|
||||||
|
static const SDL_Color Palette[256] = {
|
||||||
|
{ 255, 0, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 5, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 11, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 17, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 23, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 29, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 35, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 41, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 47, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 53, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 59, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 65, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 71, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 77, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 83, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 89, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 95, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 101, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 107, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 113, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 119, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 125, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 131, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 137, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 143, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 149, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 155, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 161, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 167, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 173, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 179, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 185, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 191, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 197, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 203, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 209, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 215, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 221, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 227, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 233, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 239, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 245, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 251, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 253, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 247, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 241, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 235, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 229, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 223, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 217, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 211, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 205, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 199, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 193, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 187, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 181, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 175, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 169, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 163, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 157, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 151, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 145, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 139, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 133, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 127, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 121, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 115, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 109, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 103, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 97, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 91, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 85, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 79, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 73, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 67, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 61, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 55, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 49, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 43, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 37, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 31, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 25, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 19, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 13, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 7, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 1, 255, 0, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 3, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 9, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 15, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 21, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 27, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 33, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 39, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 45, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 51, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 57, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 63, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 69, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 75, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 81, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 87, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 93, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 99, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 105, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 111, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 117, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 123, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 129, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 135, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 141, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 147, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 153, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 159, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 165, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 171, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 177, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 183, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 189, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 195, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 201, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 207, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 213, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 219, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 225, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 231, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 237, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 243, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 249, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 255, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 249, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 243, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 237, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 231, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 225, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 219, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 213, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 207, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 201, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 195, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 189, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 183, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 177, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 171, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 165, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 159, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 153, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 147, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 141, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 135, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 129, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 123, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 117, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 111, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 105, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 99, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 93, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 87, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 81, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 75, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 69, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 63, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 57, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 51, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 45, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 39, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 33, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 27, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 21, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 15, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 9, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 0, 3, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 1, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 7, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 13, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 19, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 25, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 31, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 37, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 43, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 49, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 55, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 61, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 67, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 73, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 79, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 85, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 91, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 97, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 103, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 109, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 115, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 121, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 127, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 133, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 139, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 145, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 151, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 157, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 163, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 169, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 175, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 181, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 187, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 193, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 199, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 205, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 211, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 217, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 223, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 229, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 235, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 241, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 247, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 253, 0, 255, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 251, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 245, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 239, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 233, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 227, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 221, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 215, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 209, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 203, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 197, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 191, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 185, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 179, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 173, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 167, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 161, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 155, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 149, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 143, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 137, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 131, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 125, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 119, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 113, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 107, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 101, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 95, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 89, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 83, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 77, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 71, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 65, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 59, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 53, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 47, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 41, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 35, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 29, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 23, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 17, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 11, SDL_ALPHA_OPAQUE },
|
||||||
|
{ 255, 0, 5, SDL_ALPHA_OPAQUE }
|
||||||
|
};
|
||||||
|
|
||||||
|
static SDL_Renderer *renderer;
|
||||||
|
static SDL_Palette *palette;
|
||||||
|
static SDL_Texture *texture;
|
||||||
|
static SDL_Texture *black_texture;
|
||||||
|
static SDL_Texture *white_texture;
|
||||||
|
static int palettePos = 0;
|
||||||
|
static int paletteDir = -1;
|
||||||
|
static bool done;
|
||||||
|
|
||||||
|
static bool CreateTextures()
|
||||||
|
{
|
||||||
|
Uint8 data[256];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
palette = SDL_CreatePalette(256);
|
||||||
|
if (!palette) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < SDL_arraysize(data); i++) {
|
||||||
|
data[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_INDEX8, SDL_TEXTUREACCESS_STATIC, 256, 1);
|
||||||
|
if (!texture) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SDL_UpdateTexture(texture, NULL, data, SDL_arraysize(data));
|
||||||
|
SDL_SetTexturePalette(texture, palette);
|
||||||
|
|
||||||
|
black_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_INDEX8, SDL_TEXTUREACCESS_STATIC, 1, 1);
|
||||||
|
if (!black_texture) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SDL_UpdateTexture(black_texture, NULL, data, SDL_arraysize(data));
|
||||||
|
SDL_SetTexturePalette(black_texture, palette);
|
||||||
|
|
||||||
|
white_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_INDEX8, SDL_TEXTUREACCESS_STATIC, 1, 1);
|
||||||
|
if (!white_texture) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SDL_UpdateTexture(white_texture, NULL, data, SDL_arraysize(data));
|
||||||
|
SDL_SetTexturePalette(white_texture, palette);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdatePalette(int pos)
|
||||||
|
{
|
||||||
|
int paletteSize = (int)SDL_arraysize(Palette);
|
||||||
|
|
||||||
|
if (pos == 0) {
|
||||||
|
SDL_SetPaletteColors(palette, Palette, 0, paletteSize);
|
||||||
|
} else {
|
||||||
|
SDL_SetPaletteColors(palette, Palette + pos, 0, paletteSize - pos);
|
||||||
|
SDL_SetPaletteColors(palette, Palette, paletteSize - pos, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loop(void)
|
||||||
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
SDL_FRect src = { 0.0f, 0.0f, 1.0f, 1.0f };
|
||||||
|
SDL_FRect dst1 = { 0.0f, 0.0f, 32.0f, 32.0f };
|
||||||
|
SDL_FRect dst2 = { WINDOW_WIDTH - 32.0f, 0.0f, 32.0f, 32.0f };
|
||||||
|
const SDL_Color black = { 0, 0, 0, SDL_ALPHA_OPAQUE };
|
||||||
|
const SDL_Color white = { 255, 255, 255, SDL_ALPHA_OPAQUE };
|
||||||
|
|
||||||
|
/* Check for events */
|
||||||
|
while (SDL_PollEvent(&event)) {
|
||||||
|
switch (event.type) {
|
||||||
|
case SDL_EVENT_KEY_UP:
|
||||||
|
switch (event.key.key) {
|
||||||
|
case SDLK_LEFT:
|
||||||
|
paletteDir = 1;
|
||||||
|
break;
|
||||||
|
case SDLK_RIGHT:
|
||||||
|
paletteDir = -1;
|
||||||
|
break;
|
||||||
|
case SDLK_ESCAPE:
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_EVENT_QUIT:
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
|
/* Draw the rainbow texture */
|
||||||
|
UpdatePalette(palettePos);
|
||||||
|
palettePos += paletteDir;
|
||||||
|
if (palettePos < 0) {
|
||||||
|
palettePos = SDL_arraysize(Palette) - 1;
|
||||||
|
} else if (palettePos >= SDL_arraysize(Palette)) {
|
||||||
|
palettePos = 0;
|
||||||
|
}
|
||||||
|
SDL_RenderTexture(renderer, texture, NULL, NULL);
|
||||||
|
|
||||||
|
/* Draw one square with black, and one square with white
|
||||||
|
* This tests changing palette colors within a single frame
|
||||||
|
*/
|
||||||
|
SDL_SetPaletteColors(palette, &black, 0, 1);
|
||||||
|
SDL_RenderTexture(renderer, black_texture, &src, &dst1);
|
||||||
|
SDL_SetPaletteColors(palette, &white, 0, 1);
|
||||||
|
SDL_RenderTexture(renderer, white_texture, &src, &dst2);
|
||||||
|
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
SDL_Delay(10);
|
||||||
|
|
||||||
|
#ifdef SDL_PLATFORM_EMSCRIPTEN
|
||||||
|
if (done) {
|
||||||
|
emscripten_cancel_main_loop();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
SDL_Window *window = NULL;
|
||||||
|
int return_code = -1;
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "USAGE: %s", argv[0]);
|
||||||
|
return_code = 1;
|
||||||
|
goto quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SDL_CreateWindowAndRenderer("testpalette", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateWindowAndRenderer failed: %s", SDL_GetError());
|
||||||
|
return_code = 2;
|
||||||
|
goto quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CreateTextures()) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create textures: %s", SDL_GetError());
|
||||||
|
return_code = 3;
|
||||||
|
goto quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main render loop */
|
||||||
|
done = false;
|
||||||
|
|
||||||
|
#ifdef SDL_PLATFORM_EMSCRIPTEN
|
||||||
|
emscripten_set_main_loop(loop, 0, 1);
|
||||||
|
#else
|
||||||
|
while (!done) {
|
||||||
|
loop();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return_code = 0;
|
||||||
|
quit:
|
||||||
|
SDL_DestroyPalette(palette);
|
||||||
|
SDL_DestroyRenderer(renderer);
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
|
return return_code;
|
||||||
|
}
|
@@ -1332,6 +1332,8 @@ const static struct {
|
|||||||
SDL_SYMBOL_ITEM(SDL_hid_get_properties),
|
SDL_SYMBOL_ITEM(SDL_hid_get_properties),
|
||||||
SDL_SYMBOL_ITEM(SDL_GetPixelFormatFromGPUTextureFormat),
|
SDL_SYMBOL_ITEM(SDL_GetPixelFormatFromGPUTextureFormat),
|
||||||
SDL_SYMBOL_ITEM(SDL_GetGPUTextureFormatFromPixelFormat),
|
SDL_SYMBOL_ITEM(SDL_GetGPUTextureFormatFromPixelFormat),
|
||||||
|
SDL_SYMBOL_ITEM(SDL_SetTexturePalette),
|
||||||
|
SDL_SYMBOL_ITEM(SDL_GetTexturePalette),
|
||||||
/* extra symbols go here (don't modify this line) */
|
/* extra symbols go here (don't modify this line) */
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user