Compare commits

..

4 Commits

Author SHA1 Message Date
veclavtalica
82d4f21a4b twn_textures.c: minor optimization 2025-01-15 00:11:47 +03:00
veclavtalica
3990f78a74 twn_textures.c: make missing texture single and reused 2025-01-15 00:10:30 +03:00
veclavtalica
f0ad9b9a8a twn_textures.c: fix repeated bind to work over varying channel count 2025-01-14 23:47:59 +03:00
veclavtalica
ea0af5159f only enable fog for 3d 2025-01-14 23:28:48 +03:00
2 changed files with 32 additions and 16 deletions

View File

@ -458,7 +458,7 @@ void finally_draw_command(DeferredCommandDraw command) {
glDepthRange(command.depth_range_low, command.depth_range_high); glDepthRange(command.depth_range_low, command.depth_range_high);
/* TODO: cache it for constant parameters, which is a common case */ /* TODO: cache it for constant parameters, which is a common case */
if (fabsf(0.0f - ctx.game_copy.fog_density) >= 0.00001f) { if (command.pipeline == PIPELINE_SPACE && fabsf(0.0f - ctx.game_copy.fog_density) >= 0.00001f) {
glEnable(GL_FOG); glEnable(GL_FOG);
/* clamp to valid range */ /* clamp to valid range */

View File

@ -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)shlenu(cache->hash) - 1;
/* reuse this id for every later missing texture */
if (surface == missing_texture_surface)
missing_texture_id = id;
return (TextureKey){ id };
} }
@ -573,7 +589,7 @@ void textures_bind_repeating(const TextureCache *cache, TextureKey key) {
upload_gpu_texture(repeating_texture, upload_gpu_texture(repeating_texture,
texture.data->pixels, texture.data->pixels,
4, texture.data->format->BytesPerPixel,
texture.data->w, texture.data->w,
texture.data->h); texture.data->h);