ref: 979ae53cfee913c2d303ab0f95aaa65dace1c7b5
dir: /libnpe_sdl3/texture.c/
#include "_sdl.h"
static SDL_Texture backtex;
bool
SDL_SetTextureScaleMode(SDL_Texture *, SDL_ScaleMode)
{
return true;
}
// https://wiki.libsdl.org/SDL3/SDL_SetRenderTarget
bool
SDL_SetRenderTarget(SDL_Renderer *, SDL_Texture *texture)
{
if(texture == nil)
npe_sdl.target = &backtex;
else
npe_sdl.target = texture;
npe_sdl.back = npe_sdl.target->m;
npe_sdl.fullredraw = 1;
return true;
}
SDL_Texture*
SDL_GetRenderTarget(SDL_Renderer *)
{
return npe_sdl.target;
}
bool
SDL_GetTextureSize(SDL_Texture *t, float *w, float *h)
{
if(t == nil){
werrstr("null texture");
return false;
}
if(w != nil)
*w = Dx(t->m->r) * (t->m->depth / 8);
if(h != nil)
*h = Dy(t->m->r);
return true;
}
SDL_PropertiesID
SDL_GetTextureProperties(SDL_Texture *t)
{
return t;
}
Sint64
SDL_GetNumberProperty(SDL_PropertiesID t, const char *name, Sint64 def)
{
if(strcmp(SDL_PROP_TEXTURE_WIDTH_NUMBER, name) == 0)
return Dx(t->m->r) * (t->m->depth / 8);
else if(strcmp(SDL_PROP_TEXTURE_HEIGHT_NUMBER, name) == 0)
return Dy(t->m->r);
else
return def;
}
SDL_Texture *
SDL_CreateTexture(SDL_Renderer *, Uint32 format, int, int w, int h)
{
SDL_Texture *t;
int dformat;
if((dformat = pixel2chan(format)) == 0){
werrstr("SDL_CreateTexture: format is not supported");
goto err;
}
if((t = malloc(sizeof(*t))) == nil)
goto err;
if((t->m = allocmemimage(Rect(0, 0, w, h), dformat)) == nil){
free(t);
goto err;
}
t->mod = nil;
memfillcolor(t->m, DBlack);
return t;
err:
werrstr("SDL_CreateTexture: %r");
return nil;
}
SDL_Texture *
SDL_CreateTextureFromSurface(SDL_Renderer *r, SDL_Surface *s)
{
SDL_Texture *t;
SDL_Rect re;
if((t = SDL_CreateTexture(r, s->format->format, 0, s->w, s->h)) != nil){
re.x = 0;
re.y = 0;
re.w = s->w;
re.h = s->h;
SDL_UpdateTexture(t, &re, s->pixels, s->pitch);
}
return t;
}
bool
SDL_LockTexture(SDL_Texture *t, const SDL_Rect *re, void **pixels, int *pitch)
{
Rectangle r;
r = re ? Rect(re->x, re->y, re->x+re->w, re->y+re->h) : t->m->r;
*pitch = Dx(r)*(t->m->depth/8);
*pixels = t->m->data->bdata;
return true;
}
bool
SDL_UnlockTexture(SDL_Texture *t)
{
USED(t);
return true;
}
bool
SDL_UpdateTexture(SDL_Texture *t, SDL_Rect *re, void *pixels, int pitch)
{
Rectangle r;
u8int *pix;
int y, my;
r = re ? Rect(re->x, re->y, re->x+re->w, re->y+re->h) : t->m->r;
pix = pixels;
if(pitch == Dx(r)*4){
if(loadmemimage(t->m, r, pix, Dx(r)*Dy(r)*4) < 0){
werrstr("SDL_UpdateTexture: %r");
return false;
}
}else{
my = Dy(r);
for(y = 0; y < my; y++, pix += pitch, r.min.y += 1){
r.max.y = r.min.y + 1;
if(loadmemimage(t->m, r, pix, Dx(r)*4) < 0){
werrstr("SDL_UpdateTexture: %r");
return false;
}
}
}
return true;
}
/* FIXME: do this better */
bool
SDL_SetTextureAlphaMod(SDL_Texture *t, Uint8 a)
{
int w, h;
u8int sa;
u32int c, *s, *e;
Point p;
Memimage *i;
Rectangle ir;
ir = t->m->r;
if(t->mod == nil){
if((t->mod = allocmemimage(ir, ARGB32)) == nil) /* FIXME */
return false;
}
memimagedraw(t->mod, ir, t->m, ZP, nil, ZP, S);
i = t->mod;
w = Dx(ir);
h = Dy(ir);
p = ZP;
for(; p.y<h; p.y++){
s = (u32int *)byteaddr(i, p);
for(e=s+w; s<e; s++){
c = *s;
sa = (c >> 24 & 0xff) * (a / 255.0);
*s = sa << 24 | c & 0xffffff;
}
}
return true;
}
/* FIXME: do this better */
bool
SDL_SetTextureColorMod(SDL_Texture *t, Uint8 r, Uint8 g, Uint8 b)
{
int w, h;
u8int u[4];
u32int c, *s, *e;
Point p;
Memimage *i;
Rectangle ir;
ir = t->m->r;
if(t->mod == nil){
if((t->mod = allocmemimage(ir, ARGB32)) == nil) /* FIXME */
return false;
}
memimagedraw(t->mod, ir, t->m, ZP, nil, ZP, S);
i = t->mod;
w = Dx(ir);
h = Dy(ir);
p = ZP;
for(; p.y<h; p.y++){
s = (u32int *)byteaddr(i, p);
for(e=s+w; s<e; s++){
c = *s;
u[0] = c >> 24;
u[1] = (c >> 16 & 0xff) * (r / 255.0);
u[2] = (c >> 8 & 0xff) * (g / 255.0);
u[3] = (c & 0xff) * (b / 255.0);
*s = u[0] << 24 | u[1] << 16 | u[2] << 8 | u[3];
}
}
return true;
}
bool
SDL_SetTextureBlendMode(SDL_Texture *t, SDL_BlendMode blendMode)
{
if(blendMode != SDL_BLENDMODE_NONE && blendMode != SDL_BLENDMODE_BLEND){
werrstr("SDL_SetTextureBlendMode: unsupported blend mode %d", blendMode);
return false;
}
t->blend = blendMode;
return true;
}
void
SDL_DestroyTexture(SDL_Texture *t)
{
if(t == nil)
return;
freememimage(t->m);
free(t);
}
int
npe_sdl_init_tex(void)
{
npe_sdl.target = &backtex;
return 0;
}