add texture border to atlas residents, actually make use of mipmapping

This commit is contained in:
veclavtalica
2025-02-23 17:14:05 +03:00
parent a88392b9e9
commit d66eda1894
5 changed files with 79 additions and 12 deletions

View File

@ -95,7 +95,7 @@ static SDL_Surface *gen_missing_texture_surface(void) {
}
SDL_Surface *textures_load_surface(const char *path) {
SDL_Surface *textures_load_surface(const char *path, bool apply_border) {
if (SDL_strncmp(path, "!", 1) == 0)
goto GET_MISSING_TEXTURE;
@ -141,11 +141,59 @@ SDL_Surface *textures_load_surface(const char *path) {
if (surface == NULL)
goto ERR_CANNOT_CREATE_SURFACE;
/* TODO: investigate possibility of growing 1px border on stbi side, reducing the overhead (right now texture is held 2 times in memory) */
/* use in atlases introduces seams on filtering, add 1px padding, growing the resulting */
if (apply_border && (width < 2048 && height < 2048)) {
SDL_Surface* border = SDL_CreateRGBSurface(0,
width + TEXTURE_BORDER_REPEAT_SIZE * 2,
height + TEXTURE_BORDER_REPEAT_SIZE * 2,
channels * 8,
rmask, gmask, bmask, amask);
if (surface == NULL)
goto ERR_CANNOT_CREATE_BORDER;
/* main portion */
SDL_SoftStretch(surface,
&(SDL_Rect){ .x = 0, .y = 0, .w = width, .h = height },
border,
&(SDL_Rect){ .x = TEXTURE_BORDER_REPEAT_SIZE, .y = TEXTURE_BORDER_REPEAT_SIZE, .w = width, .h = height });
/* left border */
SDL_SoftStretch(surface,
&(SDL_Rect){ .w = 1, .h = height },
border,
&(SDL_Rect){ .y = TEXTURE_BORDER_REPEAT_SIZE, .w = TEXTURE_BORDER_REPEAT_SIZE, .h = height });
/* right border */
SDL_SoftStretch(surface,
&(SDL_Rect){ .x = width - 1, .w = 1, .h = height },
border,
&(SDL_Rect){ .y = TEXTURE_BORDER_REPEAT_SIZE, .x = width + TEXTURE_BORDER_REPEAT_SIZE, .w = TEXTURE_BORDER_REPEAT_SIZE, .h = height });
/* up border */
SDL_SoftStretch(surface,
&(SDL_Rect){ .w = width, .h = 1 },
border,
&(SDL_Rect){ .x = TEXTURE_BORDER_REPEAT_SIZE, .w = width, .h = TEXTURE_BORDER_REPEAT_SIZE });
/* bottom border */
SDL_SoftStretch(surface,
&(SDL_Rect){ .y = height - 1, .w = width, .h = 1 },
border,
&(SDL_Rect){ .x = TEXTURE_BORDER_REPEAT_SIZE, .y = height + TEXTURE_BORDER_REPEAT_SIZE, .w = width, .h = TEXTURE_BORDER_REPEAT_SIZE });
stbi_image_free(image_mem);
SDL_FreeSurface(surface);
surface = border;
}
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE);
SDL_SetSurfaceRLE(surface, true);
return surface;
ERR_CANNOT_CREATE_BORDER:
SDL_FreeSurface(surface);
ERR_CANNOT_CREATE_SURFACE:
stbi_image_free(image_mem);
@ -361,7 +409,10 @@ void textures_cache_deinit(TextureCache *cache) {
/* free cache hashes */
for (size_t i = 0; i < shlenu(cache->hash); ++i) {
if (missing_texture_surface == NULL || cache->hash[i].value.data->pixels != missing_texture_surface->pixels)
/* TODO: better to have field that stores the source of memory directly, ugh */
if (cache->hash[i].value.srcrect.w < 2048 && cache->hash[i].value.srcrect.h < 2048)
(void)0; /* do nothing, memory owned by surface */
else if (missing_texture_surface == NULL || cache->hash[i].value.data->pixels != missing_texture_surface->pixels)
stbi_image_free(cache->hash[i].value.data->pixels);
else
SDL_free(cache->hash[i].value.data->pixels);
@ -427,7 +478,7 @@ bool textures_load_workers_thread(void) {
SDL_assert(texture_id != -1 && queue_index != -1);
SDL_Surface *const surface = textures_load_surface(path);
SDL_Surface *const surface = textures_load_surface(path, true);
SDL_free(path);
Texture const response = {
@ -594,7 +645,15 @@ int32_t textures_get_atlas_id(const TextureCache *cache, TextureKey key) {
Rect textures_get_srcrect(const TextureCache *cache, TextureKey key) {
if (m_texture_key_is_valid(key)) {
return cache->hash[key.id].value.srcrect;
Rect const srcrect = cache->hash[key.id].value.srcrect;
if (srcrect.w >= 2048 || srcrect.h >= 2048)
return srcrect;
else
/* offset to not include border*/
return (Rect){ .x = srcrect.x + TEXTURE_BORDER_REPEAT_SIZE,
.y = srcrect.y + TEXTURE_BORDER_REPEAT_SIZE,
.w = srcrect.w - TEXTURE_BORDER_REPEAT_SIZE * 2,
.h = srcrect.h - TEXTURE_BORDER_REPEAT_SIZE * 2 };
} else {
CRY("Texture lookup failed.",
"Tried to get texture that isn't loaded.");