mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-06-05 23:10:58 +00:00
Added SDL_WriteSurfacePixel() and SDL_WriteSurfacePixelFloat()
This commit is contained in:
parent
12e50d17a2
commit
9294476788
5 changed files with 169 additions and 0 deletions
|
@ -1211,6 +1211,49 @@ extern SDL_DECLSPEC int SDLCALL SDL_ReadSurfacePixel(SDL_Surface *surface, int x
|
||||||
*/
|
*/
|
||||||
extern SDL_DECLSPEC int SDLCALL SDL_ReadSurfacePixelFloat(SDL_Surface *surface, int x, int y, float *r, float *g, float *b, float *a);
|
extern SDL_DECLSPEC int SDLCALL SDL_ReadSurfacePixelFloat(SDL_Surface *surface, int x, int y, float *r, float *g, float *b, float *a);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a single pixel to a surface.
|
||||||
|
*
|
||||||
|
* This function prioritizes correctness over speed: it is suitable for unit
|
||||||
|
* tests, but is not intended for use in a game engine.
|
||||||
|
*
|
||||||
|
* Like SDL_MapRGBA, this uses the entire 0..255 range when converting color
|
||||||
|
* components from pixel formats with less than 8 bits per RGB component.
|
||||||
|
*
|
||||||
|
* \param surface the surface to write.
|
||||||
|
* \param x the horizontal coordinate, 0 <= x < width.
|
||||||
|
* \param y the vertical coordinate, 0 <= y < height.
|
||||||
|
* \param r the red channel value, 0-255.
|
||||||
|
* \param g the green channel value, 0-255.
|
||||||
|
* \param b the blue channel value, 0-255.
|
||||||
|
* \param a the alpha channel value, 0-255.
|
||||||
|
* \returns 0 on success or a negative error code on failure; call
|
||||||
|
* SDL_GetError() for more information.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.0.0.
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC int SDLCALL SDL_WriteSurfacePixel(SDL_Surface *surface, int x, int y, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a single pixel to a surface.
|
||||||
|
*
|
||||||
|
* This function prioritizes correctness over speed: it is suitable for unit
|
||||||
|
* tests, but is not intended for use in a game engine.
|
||||||
|
*
|
||||||
|
* \param surface the surface to write.
|
||||||
|
* \param x the horizontal coordinate, 0 <= x < width.
|
||||||
|
* \param y the vertical coordinate, 0 <= y < height.
|
||||||
|
* \param r the red channel value, normally in the range 0-1.
|
||||||
|
* \param g the green channel value, normally in the range 0-1.
|
||||||
|
* \param b the blue channel value, normally in the range 0-1.
|
||||||
|
* \param a the alpha channel value, normally in the range 0-1.
|
||||||
|
* \returns 0 on success or a negative error code on failure; call
|
||||||
|
* SDL_GetError() for more information.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.0.0.
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC int SDLCALL SDL_WriteSurfacePixelFloat(SDL_Surface *surface, int x, int y, float r, float g, float b, float a);
|
||||||
|
|
||||||
/* Ends C function definitions when using C++ */
|
/* Ends C function definitions when using C++ */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -875,6 +875,8 @@ SDL3_0.0.0 {
|
||||||
SDL_WriteS64LE;
|
SDL_WriteS64LE;
|
||||||
SDL_WriteS8;
|
SDL_WriteS8;
|
||||||
SDL_WriteStorageFile;
|
SDL_WriteStorageFile;
|
||||||
|
SDL_WriteSurfacePixel;
|
||||||
|
SDL_WriteSurfacePixelFloat;
|
||||||
SDL_WriteU16BE;
|
SDL_WriteU16BE;
|
||||||
SDL_WriteU16LE;
|
SDL_WriteU16LE;
|
||||||
SDL_WriteU32BE;
|
SDL_WriteU32BE;
|
||||||
|
|
|
@ -900,6 +900,8 @@
|
||||||
#define SDL_WriteS64LE SDL_WriteS64LE_REAL
|
#define SDL_WriteS64LE SDL_WriteS64LE_REAL
|
||||||
#define SDL_WriteS8 SDL_WriteS8_REAL
|
#define SDL_WriteS8 SDL_WriteS8_REAL
|
||||||
#define SDL_WriteStorageFile SDL_WriteStorageFile_REAL
|
#define SDL_WriteStorageFile SDL_WriteStorageFile_REAL
|
||||||
|
#define SDL_WriteSurfacePixel SDL_WriteSurfacePixel_REAL
|
||||||
|
#define SDL_WriteSurfacePixelFloat SDL_WriteSurfacePixelFloat_REAL
|
||||||
#define SDL_WriteU16BE SDL_WriteU16BE_REAL
|
#define SDL_WriteU16BE SDL_WriteU16BE_REAL
|
||||||
#define SDL_WriteU16LE SDL_WriteU16LE_REAL
|
#define SDL_WriteU16LE SDL_WriteU16LE_REAL
|
||||||
#define SDL_WriteU32BE SDL_WriteU32BE_REAL
|
#define SDL_WriteU32BE SDL_WriteU32BE_REAL
|
||||||
|
|
|
@ -910,6 +910,8 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS64BE,(SDL_IOStream *a, Sint64 b),(a,b),return
|
||||||
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS64LE,(SDL_IOStream *a, Sint64 b),(a,b),return)
|
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS64LE,(SDL_IOStream *a, Sint64 b),(a,b),return)
|
||||||
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS8,(SDL_IOStream *a, Sint8 b),(a,b),return)
|
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS8,(SDL_IOStream *a, Sint8 b),(a,b),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_WriteStorageFile,(SDL_Storage *a, const char *b, const void *c, Uint64 d),(a,b,c,d),return)
|
SDL_DYNAPI_PROC(int,SDL_WriteStorageFile,(SDL_Storage *a, const char *b, const void *c, Uint64 d),(a,b,c,d),return)
|
||||||
|
SDL_DYNAPI_PROC(int,SDL_WriteSurfacePixel,(SDL_Surface *a, int b, int c, Uint8 d, Uint8 e, Uint8 f, Uint8 g),(a,b,c,d,e,f,g),return)
|
||||||
|
SDL_DYNAPI_PROC(int,SDL_WriteSurfacePixelFloat,(SDL_Surface *a, int b, int c, float d, float e, float f, float g),(a,b,c,d,e,f,g),return)
|
||||||
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU16BE,(SDL_IOStream *a, Uint16 b),(a,b),return)
|
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU16BE,(SDL_IOStream *a, Uint16 b),(a,b),return)
|
||||||
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU16LE,(SDL_IOStream *a, Uint16 b),(a,b),return)
|
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU16LE,(SDL_IOStream *a, Uint16 b),(a,b),return)
|
||||||
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU32BE,(SDL_IOStream *a, Uint32 b),(a,b),return)
|
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU32BE,(SDL_IOStream *a, Uint32 b),(a,b),return)
|
||||||
|
|
|
@ -2459,6 +2459,126 @@ int SDL_ReadSurfacePixelFloat(SDL_Surface *surface, int x, int y, float *r, floa
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SDL_WriteSurfacePixel(SDL_Surface *surface, int x, int y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||||
|
{
|
||||||
|
Uint32 pixel = 0;
|
||||||
|
size_t bytes_per_pixel;
|
||||||
|
Uint8 *p;
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
|
if (!SDL_SurfaceValid(surface) || !surface->format || !surface->pixels) {
|
||||||
|
return SDL_InvalidParamError("surface");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x < 0 || x >= surface->w) {
|
||||||
|
return SDL_InvalidParamError("x");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y < 0 || y >= surface->h) {
|
||||||
|
return SDL_InvalidParamError("y");
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes_per_pixel = SDL_BYTESPERPIXEL(surface->format);
|
||||||
|
|
||||||
|
if (SDL_MUSTLOCK(surface)) {
|
||||||
|
if (SDL_LockSurface(surface) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = (Uint8 *)surface->pixels + y * surface->pitch + x * bytes_per_pixel;
|
||||||
|
|
||||||
|
if (bytes_per_pixel <= sizeof(pixel) && !SDL_ISPIXELFORMAT_FOURCC(surface->format)) {
|
||||||
|
pixel = SDL_MapRGBA(surface->internal->format, surface->internal->palette, r, g, b, a);
|
||||||
|
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||||
|
SDL_memcpy(p, ((Uint8 *)&pixel) + (sizeof(pixel) - bytes_per_pixel), bytes_per_pixel);
|
||||||
|
#else
|
||||||
|
SDL_memcpy(p, &pixel, bytes_per_pixel);
|
||||||
|
#endif
|
||||||
|
result = 0;
|
||||||
|
} else if (SDL_ISPIXELFORMAT_FOURCC(surface->format)) {
|
||||||
|
result = SDL_Unsupported();
|
||||||
|
} else {
|
||||||
|
/* This is really slow, but it gets the job done */
|
||||||
|
Uint8 rgba[4];
|
||||||
|
SDL_Colorspace colorspace = SDL_GetSurfaceColorspace(surface);
|
||||||
|
|
||||||
|
rgba[0] = r;
|
||||||
|
rgba[1] = g;
|
||||||
|
rgba[2] = b;
|
||||||
|
rgba[3] = a;
|
||||||
|
result = SDL_ConvertPixelsAndColorspace(1, 1, SDL_PIXELFORMAT_RGBA32, SDL_COLORSPACE_SRGB, 0, rgba, sizeof(rgba), surface->format, colorspace, surface->internal->props, p, surface->pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_MUSTLOCK(surface)) {
|
||||||
|
SDL_UnlockSurface(surface);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SDL_WriteSurfacePixelFloat(SDL_Surface *surface, int x, int y, float r, float g, float b, float a)
|
||||||
|
{
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
|
if (!SDL_SurfaceValid(surface) || !surface->format || !surface->pixels) {
|
||||||
|
return SDL_InvalidParamError("surface");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x < 0 || x >= surface->w) {
|
||||||
|
return SDL_InvalidParamError("x");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y < 0 || y >= surface->h) {
|
||||||
|
return SDL_InvalidParamError("y");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_BYTESPERPIXEL(surface->format) <= sizeof(Uint32) && !SDL_ISPIXELFORMAT_FOURCC(surface->format)) {
|
||||||
|
Uint8 r8, g8, b8, a8;
|
||||||
|
|
||||||
|
r8 = (Uint8)SDL_round(SDL_clamp(r, 0.0f, 1.0f) * 255.0f);
|
||||||
|
g8 = (Uint8)SDL_round(SDL_clamp(g, 0.0f, 1.0f) * 255.0f);
|
||||||
|
b8 = (Uint8)SDL_round(SDL_clamp(b, 0.0f, 1.0f) * 255.0f);
|
||||||
|
a8 = (Uint8)SDL_round(SDL_clamp(a, 0.0f, 1.0f) * 255.0f);
|
||||||
|
if (SDL_WriteSurfacePixel(surface, x, y, r8, g8, b8, a8) == 0) {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
} else if (SDL_ISPIXELFORMAT_FOURCC(surface->format)) {
|
||||||
|
result = SDL_Unsupported();
|
||||||
|
} else {
|
||||||
|
/* This is really slow, but it gets the job done */
|
||||||
|
float rgba[4];
|
||||||
|
Uint8 *p;
|
||||||
|
|
||||||
|
if (SDL_MUSTLOCK(surface)) {
|
||||||
|
if (SDL_LockSurface(surface) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = (Uint8 *)surface->pixels + y * surface->pitch + x * SDL_BYTESPERPIXEL(surface->format);
|
||||||
|
|
||||||
|
rgba[0] = r;
|
||||||
|
rgba[1] = g;
|
||||||
|
rgba[2] = b;
|
||||||
|
rgba[3] = a;
|
||||||
|
|
||||||
|
if (surface->format == SDL_PIXELFORMAT_RGBA128_FLOAT) {
|
||||||
|
SDL_memcpy(p, rgba, sizeof(rgba));
|
||||||
|
result = 0;
|
||||||
|
} else {
|
||||||
|
SDL_Colorspace dst_colorspace = SDL_GetSurfaceColorspace(surface);
|
||||||
|
SDL_Colorspace src_colorspace = (dst_colorspace == SDL_COLORSPACE_SRGB_LINEAR ? SDL_COLORSPACE_SRGB_LINEAR : SDL_COLORSPACE_SRGB);
|
||||||
|
|
||||||
|
result = SDL_ConvertPixelsAndColorspace(1, 1, SDL_PIXELFORMAT_RGBA128_FLOAT, src_colorspace, 0, rgba, sizeof(rgba), surface->format, dst_colorspace, surface->internal->props, p, surface->pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_MUSTLOCK(surface)) {
|
||||||
|
SDL_UnlockSurface(surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free a surface created by the above function.
|
* Free a surface created by the above function.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue