twn_textures.c: make missing texture single and reused
This commit is contained in:
parent
f0ad9b9a8a
commit
3990f78a74
@ -41,7 +41,8 @@ static int load_eof_callback(void *user) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t *missing_texture_data;
|
static SDL_Surface *missing_texture_surface;
|
||||||
|
static uint16_t missing_texture_id;
|
||||||
|
|
||||||
static SDL_Surface *gen_missing_texture_surface(void) {
|
static SDL_Surface *gen_missing_texture_surface(void) {
|
||||||
Uint32 rmask, gmask, bmask;
|
Uint32 rmask, gmask, bmask;
|
||||||
@ -56,22 +57,23 @@ static SDL_Surface *gen_missing_texture_surface(void) {
|
|||||||
bmask = 0x00ff0000;
|
bmask = 0x00ff0000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!missing_texture_data) {
|
if (!missing_texture_surface) {
|
||||||
missing_texture_data = SDL_malloc(64 * 64 * 3);
|
uint8_t *data = SDL_malloc(64 * 64 * 3);
|
||||||
for (int y = 0; y < 64; ++y)
|
for (int y = 0; y < 64; ++y) {
|
||||||
for (int x = 0; x < 64; ++x) {
|
for (int x = 0; x < 64; ++x) {
|
||||||
/* diagonal stripes, chosen so that asked pixel uvs are corresponding to final output */
|
/* diagonal stripes, chosen so that asked pixel uvs are corresponding to final output */
|
||||||
missing_texture_data[(y * 64 + x) * 3 + 0] = (x / 2 + y / 2) % 2 == 0 ? 175 : 0;
|
data[(y * 64 + x) * 3 + 0] = (x / 2 + y / 2) % 2 == 0 ? 175 : 0;
|
||||||
missing_texture_data[(y * 64 + x) * 3 + 1] = (x / 2 + y / 2) % 2 == 0 ? 0 : 0;
|
data[(y * 64 + x) * 3 + 1] = (x / 2 + y / 2) % 2 == 0 ? 0 : 0;
|
||||||
missing_texture_data[(y * 64 + x) * 3 + 2] = (x / 2 + y / 2) % 2 == 0 ? 175 : 0;
|
data[(y * 64 + x) * 3 + 2] = (x / 2 + y / 2) % 2 == 0 ? 175 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* same data is reused after being allocated/generated once */
|
missing_texture_surface = SDL_CreateRGBSurfaceFrom(data, 64, 64,
|
||||||
SDL_Surface *missing_texture_surface = SDL_CreateRGBSurfaceFrom(missing_texture_data, 64, 64,
|
|
||||||
3 * 8,
|
3 * 8,
|
||||||
64 * 3,
|
64 * 3,
|
||||||
rmask, gmask, bmask, 0);
|
rmask, gmask, bmask, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return missing_texture_surface;
|
return missing_texture_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,8 +329,10 @@ void textures_cache_deinit(TextureCache *cache) {
|
|||||||
|
|
||||||
/* free cache hashes */
|
/* free cache hashes */
|
||||||
for (size_t i = 0; i < shlenu(cache->hash); ++i) {
|
for (size_t i = 0; i < shlenu(cache->hash); ++i) {
|
||||||
if (cache->hash[i].value.data->pixels != missing_texture_data)
|
if (missing_texture_surface && cache->hash[i].value.data->pixels != missing_texture_surface->pixels)
|
||||||
stbi_image_free(cache->hash[i].value.data->pixels);
|
stbi_image_free(cache->hash[i].value.data->pixels);
|
||||||
|
else
|
||||||
|
SDL_free(cache->hash[i].value.data->pixels);
|
||||||
SDL_FreeSurface(cache->hash[i].value.data);
|
SDL_FreeSurface(cache->hash[i].value.data);
|
||||||
}
|
}
|
||||||
shfree(cache->hash);
|
shfree(cache->hash);
|
||||||
@ -372,6 +376,9 @@ static TextureKey textures_load(TextureCache *cache, const char *path) {
|
|||||||
return (TextureKey){ (uint16_t)i };
|
return (TextureKey){ (uint16_t)i };
|
||||||
|
|
||||||
SDL_Surface *surface = textures_load_surface(path);
|
SDL_Surface *surface = textures_load_surface(path);
|
||||||
|
if (surface == missing_texture_surface && missing_texture_id != 0)
|
||||||
|
return (TextureKey){ missing_texture_id };
|
||||||
|
|
||||||
Texture new_texture = {
|
Texture new_texture = {
|
||||||
.data = surface,
|
.data = surface,
|
||||||
.mode = infer_texture_mode(surface),
|
.mode = infer_texture_mode(surface),
|
||||||
@ -388,13 +395,22 @@ static TextureKey textures_load(TextureCache *cache, const char *path) {
|
|||||||
new_texture.loner_texture = create_gpu_texture(TEXTURE_FILTER_NEAREAST, true);
|
new_texture.loner_texture = create_gpu_texture(TEXTURE_FILTER_NEAREAST, true);
|
||||||
upload_texture_from_surface(new_texture.loner_texture, surface);
|
upload_texture_from_surface(new_texture.loner_texture, surface);
|
||||||
new_texture.srcrect = (Rect) { .w = (float)surface->w, .h = (float)surface->h };
|
new_texture.srcrect = (Rect) { .w = (float)surface->w, .h = (float)surface->h };
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* will be fully populated as the atlas updates */
|
/* will be fully populated as the atlas updates */
|
||||||
new_texture.atlas_index = cache->atlas_index;
|
new_texture.atlas_index = cache->atlas_index;
|
||||||
cache->is_dirty = true;
|
cache->is_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
shput(cache->hash, path, new_texture);
|
shput(cache->hash, path, new_texture);
|
||||||
return (TextureKey){ (uint16_t)shgeti(cache->hash, path) };
|
|
||||||
|
uint16_t const id = (uint16_t)shgeti(cache->hash, path);
|
||||||
|
|
||||||
|
/* reuse this id for every later missing texture */
|
||||||
|
if (surface == missing_texture_surface)
|
||||||
|
missing_texture_id = id;
|
||||||
|
|
||||||
|
return (TextureKey){ id };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user