shithub: npe

ref: 979ae53cfee913c2d303ab0f95aaa65dace1c7b5
dir: /libnpe_sdl3/texture.c/

View raw version
#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;
}