diff --git a/panda/src/egg2pg/config_egg2pg.cxx b/panda/src/egg2pg/config_egg2pg.cxx index e32aa19914..0b42a6f450 100644 --- a/panda/src/egg2pg/config_egg2pg.cxx +++ b/panda/src/egg2pg/config_egg2pg.cxx @@ -194,6 +194,13 @@ ConfigVariableBool egg_implicit_alpha_binary "will automatically be downgraded to alpha type \"binary\" instead of " "whatever appears in the egg file.")); +ConfigVariableBool egg_force_srgb_textures +("egg-force-srgb-textures", false, + PRC_DESC("If this is true, Panda3D will automatically assign the F_srgb or " + "F_srgb_alpha format to all textures loaded from egg files, unless " + "their envtype is set to a non-color map. Keep in mind that the " + "model-cache must be cleared after changing this setting.")); + ConfigureFn(config_egg2pg) { init_libegg2pg(); } diff --git a/panda/src/egg2pg/config_egg2pg.h b/panda/src/egg2pg/config_egg2pg.h index e9e0e202d6..f833772676 100644 --- a/panda/src/egg2pg/config_egg2pg.h +++ b/panda/src/egg2pg/config_egg2pg.h @@ -54,6 +54,7 @@ extern EXPCL_PANDA_EGG2PG ConfigVariableBool egg_preload_simple_textures; extern EXPCL_PANDA_EGG2PG ConfigVariableDouble egg_vertex_membership_quantize; extern EXPCL_PANDA_EGG2PG ConfigVariableInt egg_vertex_max_num_joints; extern EXPCL_PANDA_EGG2PG ConfigVariableBool egg_implicit_alpha_binary; +extern EXPCL_PANDA_EGG2PG ConfigVariableBool egg_force_srgb_textures; extern EXPCL_PANDA_EGG2PG void init_libegg2pg(); diff --git a/panda/src/egg2pg/eggLoader.cxx b/panda/src/egg2pg/eggLoader.cxx index 170cc6f7ae..d456dd5b16 100644 --- a/panda/src/egg2pg/eggLoader.cxx +++ b/panda/src/egg2pg/eggLoader.cxx @@ -1188,6 +1188,30 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { tex->set_default_sampler(sampler); + bool force_srgb = false; + if (egg_force_srgb_textures) { + switch (egg_tex->get_env_type()) { + case EggTexture::ET_unspecified: + case EggTexture::ET_modulate: + case EggTexture::ET_decal: + case EggTexture::ET_blend: + case EggTexture::ET_replace: + case EggTexture::ET_add: + case EggTexture::ET_blend_color_scale: + case EggTexture::ET_modulate_glow: + case EggTexture::ET_modulate_gloss: + force_srgb = true; + if (egg2pg_cat.is_debug()) { + egg2pg_cat.debug() + << "Enabling sRGB format on texture " << egg_tex->get_name() << "\n"; + } + break; + + default: + break; + } + } + if (tex->get_num_components() == 1) { switch (egg_tex->get_format()) { case EggTexture::F_red: @@ -1203,44 +1227,52 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { tex->set_format(Texture::F_alpha); break; case EggTexture::F_luminance: - tex->set_format(Texture::F_luminance); - break; - - case EggTexture::F_unspecified: + tex->set_format(force_srgb ? Texture::F_sluminance : Texture::F_luminance); break; default: egg2pg_cat.warning() << "Ignoring inappropriate format " << egg_tex->get_format() << " for 1-component texture " << egg_tex->get_name() << "\n"; + + case EggTexture::F_unspecified: + if (force_srgb) { + tex->set_format(Texture::F_sluminance); + } + break; } } else if (tex->get_num_components() == 2) { switch (egg_tex->get_format()) { case EggTexture::F_luminance_alpha: - tex->set_format(Texture::F_luminance_alpha); + tex->set_format(force_srgb ? Texture::F_sluminance_alpha : Texture::F_luminance_alpha); break; case EggTexture::F_luminance_alphamask: - tex->set_format(Texture::F_luminance_alphamask); - break; - - case EggTexture::F_unspecified: + tex->set_format(force_srgb ? Texture::F_sluminance_alpha : Texture::F_luminance_alphamask); break; default: egg2pg_cat.warning() << "Ignoring inappropriate format " << egg_tex->get_format() << " for 2-component texture " << egg_tex->get_name() << "\n"; + + case EggTexture::F_unspecified: + if (force_srgb) { + tex->set_format(Texture::F_sluminance_alpha); + } + break; } } else if (tex->get_num_components() == 3) { switch (egg_tex->get_format()) { case EggTexture::F_rgb: - tex->set_format(Texture::F_rgb); + tex->set_format(force_srgb ? Texture::F_srgb : Texture::F_rgb); break; case EggTexture::F_rgb12: - if (tex->get_component_width() >= 2) { + if (force_srgb) { + tex->set_format(Texture::F_srgb); + } else if (tex->get_component_width() >= 2) { // Only do this if the component width supports it. tex->set_format(Texture::F_rgb12); } else { @@ -1253,40 +1285,45 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { case EggTexture::F_rgba8: // We'll quietly accept RGBA8 for a 3-component texture, since flt2egg // generates these for 3-component as well as for 4-component textures. - tex->set_format(Texture::F_rgb8); + tex->set_format(force_srgb ? Texture::F_srgb : Texture::F_rgb8); break; case EggTexture::F_rgb5: - tex->set_format(Texture::F_rgb5); + tex->set_format(force_srgb ? Texture::F_srgb : Texture::F_rgb5); break; case EggTexture::F_rgb332: - tex->set_format(Texture::F_rgb332); + tex->set_format(force_srgb ? Texture::F_srgb : Texture::F_rgb332); break; case EggTexture::F_srgb: case EggTexture::F_srgb_alpha: tex->set_format(Texture::F_srgb); break; - case EggTexture::F_unspecified: - break; - default: egg2pg_cat.warning() << "Ignoring inappropriate format " << egg_tex->get_format() << " for 3-component texture " << egg_tex->get_name() << "\n"; + + case EggTexture::F_unspecified: + if (force_srgb) { + tex->set_format(Texture::F_srgb); + } + break; } } else if (tex->get_num_components() == 4) { switch (egg_tex->get_format()) { case EggTexture::F_rgba: - tex->set_format(Texture::F_rgba); + tex->set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba); break; case EggTexture::F_rgbm: - tex->set_format(Texture::F_rgbm); + tex->set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgbm); break; case EggTexture::F_rgba12: - if (tex->get_component_width() >= 2) { + if (force_srgb) { + tex->set_format(Texture::F_srgb_alpha); + } else if (tex->get_component_width() >= 2) { // Only do this if the component width supports it. - tex->set_format(Texture::F_rgba12); + tex->set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba12); } else { egg2pg_cat.warning() << "Ignoring inappropriate format " << egg_tex->get_format() @@ -1294,28 +1331,38 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { } break; case EggTexture::F_rgba8: - tex->set_format(Texture::F_rgba8); + tex->set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba8); break; case EggTexture::F_rgba4: - tex->set_format(Texture::F_rgba4); + tex->set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba4); break; case EggTexture::F_rgba5: - tex->set_format(Texture::F_rgba5); + tex->set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba5); break; case EggTexture::F_srgb_alpha: tex->set_format(Texture::F_srgb_alpha); break; - case EggTexture::F_unspecified: - break; - default: egg2pg_cat.warning() << "Ignoring inappropriate format " << egg_tex->get_format() << " for 4-component texture " << egg_tex->get_name() << "\n"; + + case EggTexture::F_unspecified: + if (force_srgb) { + tex->set_format(Texture::F_srgb_alpha); + } + break; } } + if (force_srgb && tex->get_format() != Texture::F_alpha && + !Texture::is_srgb(tex->get_format())) { + egg2pg_cat.warning() + << "Unable to enable sRGB format on texture " << egg_tex->get_name() + << " with specified format " << egg_tex->get_format() << "\n"; + } + switch (egg_tex->get_quality_level()) { case EggTexture::QL_unspecified: case EggTexture::QL_default: