|
|
@@ -96,6 +96,7 @@
|
|
|
#include "uvScrollNode.h"
|
|
|
#include "textureStagePool.h"
|
|
|
#include "cmath.h"
|
|
|
+#include "loaderOptions.h"
|
|
|
|
|
|
#include <ctype.h>
|
|
|
#include <algorithm>
|
|
|
@@ -879,6 +880,7 @@ load_texture(TextureDef &def, EggTexture *egg_tex) {
|
|
|
// Check to see if we should reduce the number of channels in the texture.
|
|
|
int wanted_channels = 0;
|
|
|
bool wanted_alpha = false;
|
|
|
+
|
|
|
switch (egg_tex->get_format()) {
|
|
|
case EggTexture::F_red:
|
|
|
case EggTexture::F_green:
|
|
|
@@ -932,6 +934,7 @@ load_texture(TextureDef &def, EggTexture *egg_tex) {
|
|
|
|
|
|
// By convention, the egg loader will preload the simple texture images.
|
|
|
LoaderOptions options;
|
|
|
+
|
|
|
if (egg_preload_simple_textures) {
|
|
|
options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_preload_simple);
|
|
|
}
|
|
|
@@ -963,6 +966,15 @@ load_texture(TextureDef &def, EggTexture *egg_tex) {
|
|
|
options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_allow_compression);
|
|
|
}
|
|
|
|
|
|
+ if (egg_force_srgb_textures) {
|
|
|
+ options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_force_srgb);
|
|
|
+ }
|
|
|
+
|
|
|
+ //The following code sets up all the options for the textures
|
|
|
+ //so that they can be differentiated later in texturePool
|
|
|
+ SamplerState sampler;
|
|
|
+ set_up_loader_options(egg_tex, options, sampler);
|
|
|
+
|
|
|
PT(Texture) tex;
|
|
|
switch (egg_tex->get_texture_type()) {
|
|
|
case EggTexture::TT_unspecified:
|
|
|
@@ -976,22 +988,26 @@ load_texture(TextureDef &def, EggTexture *egg_tex) {
|
|
|
egg_tex->get_alpha_fullpath(),
|
|
|
wanted_channels,
|
|
|
egg_tex->get_alpha_file_channel(),
|
|
|
- egg_tex->get_read_mipmaps(), options);
|
|
|
+ egg_tex->get_read_mipmaps(),
|
|
|
+ options, sampler);
|
|
|
} else {
|
|
|
tex = TexturePool::load_texture(egg_tex->get_fullpath(),
|
|
|
wanted_channels,
|
|
|
- egg_tex->get_read_mipmaps(), options);
|
|
|
+ egg_tex->get_read_mipmaps(),
|
|
|
+ options, sampler);
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case EggTexture::TT_3d_texture:
|
|
|
tex = TexturePool::load_3d_texture(egg_tex->get_fullpath(),
|
|
|
- egg_tex->get_read_mipmaps(), options);
|
|
|
+ egg_tex->get_read_mipmaps(),
|
|
|
+ options, sampler);
|
|
|
break;
|
|
|
|
|
|
case EggTexture::TT_cube_map:
|
|
|
tex = TexturePool::load_cube_map(egg_tex->get_fullpath(),
|
|
|
- egg_tex->get_read_mipmaps(), options);
|
|
|
+ egg_tex->get_read_mipmaps(),
|
|
|
+ options, sampler);
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
@@ -1030,8 +1046,7 @@ load_texture(TextureDef &def, EggTexture *egg_tex) {
|
|
|
egg_tex->set_anisotropic_degree(aux_egg_tex->get_anisotropic_degree());
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- apply_texture_attributes(tex, egg_tex);
|
|
|
+ check_texture_attributes(tex, sampler, egg_tex);
|
|
|
|
|
|
// Make a texture stage for the texture.
|
|
|
PT(TextureStage) stage = make_texture_stage(egg_tex);
|
|
|
@@ -1042,18 +1057,26 @@ load_texture(TextureDef &def, EggTexture *egg_tex) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
- *
|
|
|
+ * Populate the loader options for the incoming texture. These are applied to
|
|
|
+ * the texture and also used to search for the texture. Textures are stored in
|
|
|
+ * texturePool in _textures a map object
|
|
|
*/
|
|
|
void EggLoader::
|
|
|
-apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
|
|
|
- if (egg_tex->get_compression_mode() != EggTexture::CM_default) {
|
|
|
- tex->set_compression(convert_compression_mode(egg_tex->get_compression_mode()));
|
|
|
- }
|
|
|
-
|
|
|
- SamplerState sampler;
|
|
|
+set_up_loader_options(EggTexture *egg_tex, LoaderOptions &options, SamplerState &sampler) {
|
|
|
+ //We store these options and Texture enums, so we need to convert them.
|
|
|
+ options.set_texture_format(convert_format(egg_tex->get_format(), egg_tex->get_env_type()));
|
|
|
+ options.set_texture_compression(convert_compression_mode(egg_tex->get_compression_mode()));
|
|
|
+ options.set_texture_quality(convert_quality_level(egg_tex->get_quality_level()));
|
|
|
+ set_up_sampler(sampler, egg_tex);
|
|
|
+}
|
|
|
|
|
|
+/**
|
|
|
+ * Set up the sampler object that will be stored in the texture pool. Samplers
|
|
|
+ * store the wrap mode, the min and mag filters, and anisotropic degree
|
|
|
+ */
|
|
|
+void EggLoader::
|
|
|
+set_up_sampler(SamplerState &sampler, const EggTexture *egg_tex) {
|
|
|
EggTexture::WrapMode wrap_u = egg_tex->determine_wrap_u();
|
|
|
EggTexture::WrapMode wrap_v = egg_tex->determine_wrap_v();
|
|
|
EggTexture::WrapMode wrap_w = egg_tex->determine_wrap_w();
|
|
|
@@ -1185,202 +1208,216 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
|
|
|
if (egg_tex->has_lod_bias()) {
|
|
|
sampler.set_lod_bias(egg_tex->get_lod_bias());
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- 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) {
|
|
|
+/**
|
|
|
+ * Now that the texture is fully loaded determine whether there are any
|
|
|
+ * inconsistencies in the texture vs the attributes.
|
|
|
+ */
|
|
|
+void EggLoader::
|
|
|
+check_texture_attributes(Texture *tex, SamplerState sampler, const EggTexture *egg_tex) {
|
|
|
+ switch (tex->get_num_components()) {
|
|
|
+ case 1:
|
|
|
switch (egg_tex->get_format()) {
|
|
|
+ case EggTexture::F_unspecified:
|
|
|
case EggTexture::F_red:
|
|
|
- tex->set_format(Texture::F_red);
|
|
|
- break;
|
|
|
case EggTexture::F_green:
|
|
|
- tex->set_format(Texture::F_green);
|
|
|
- break;
|
|
|
case EggTexture::F_blue:
|
|
|
- tex->set_format(Texture::F_blue);
|
|
|
- break;
|
|
|
case EggTexture::F_alpha:
|
|
|
- tex->set_format(Texture::F_alpha);
|
|
|
- break;
|
|
|
case EggTexture::F_luminance:
|
|
|
- tex->set_format(force_srgb ? Texture::F_sluminance : Texture::F_luminance);
|
|
|
break;
|
|
|
-
|
|
|
default:
|
|
|
egg2pg_cat.warning()
|
|
|
- << "Ignoring inappropriate format " << egg_tex->get_format()
|
|
|
+ << "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;
|
|
|
}
|
|
|
+ break;
|
|
|
|
|
|
- } else if (tex->get_num_components() == 2) {
|
|
|
+ case 2:
|
|
|
switch (egg_tex->get_format()) {
|
|
|
+ case EggTexture::F_unspecified:
|
|
|
case EggTexture::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(force_srgb ? Texture::F_sluminance_alpha : Texture::F_luminance_alphamask);
|
|
|
break;
|
|
|
-
|
|
|
default:
|
|
|
- egg2pg_cat.warning()
|
|
|
- << "Ignoring inappropriate format " << egg_tex->get_format()
|
|
|
+ egg2pg_cat.error()
|
|
|
+ << "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;
|
|
|
}
|
|
|
+ break;
|
|
|
|
|
|
- } else if (tex->get_num_components() == 3) {
|
|
|
+ case 3:
|
|
|
+ // We'll quietly accept RGBA8 for a 3-component texture, since flt2egg
|
|
|
+ // generates these for 3-component as well as for 4-component textures.
|
|
|
switch (egg_tex->get_format()) {
|
|
|
+ case EggTexture::F_unspecified:
|
|
|
case EggTexture::F_rgb:
|
|
|
- tex->set_format(force_srgb ? Texture::F_srgb : Texture::F_rgb);
|
|
|
- break;
|
|
|
- case EggTexture::F_rgb12:
|
|
|
- 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 {
|
|
|
- egg2pg_cat.warning()
|
|
|
- << "Ignoring inappropriate format " << egg_tex->get_format()
|
|
|
- << " for 8-bit texture " << egg_tex->get_name() << "\n";
|
|
|
- }
|
|
|
- break;
|
|
|
case EggTexture::F_rgb8:
|
|
|
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(force_srgb ? Texture::F_srgb : Texture::F_rgb8);
|
|
|
- break;
|
|
|
case EggTexture::F_rgb5:
|
|
|
- tex->set_format(force_srgb ? Texture::F_srgb : Texture::F_rgb5);
|
|
|
- break;
|
|
|
case EggTexture::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;
|
|
|
-
|
|
|
- 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);
|
|
|
+ case EggTexture::F_rgb12:
|
|
|
+ if (!egg_force_srgb_textures && tex->get_component_width() < 2) {
|
|
|
+ egg2pg_cat.error()
|
|
|
+ << "Inappropriate format " << egg_tex->get_format()
|
|
|
+ << " for 8-bit texture " << egg_tex->get_name() << "\n";
|
|
|
}
|
|
|
break;
|
|
|
+ default:
|
|
|
+ egg2pg_cat.error()
|
|
|
+ << "Inappropriate format " << egg_tex->get_format()
|
|
|
+ << " for 3-component texture " << egg_tex->get_name() << "\n";
|
|
|
}
|
|
|
+ break;
|
|
|
|
|
|
- } else if (tex->get_num_components() == 4) {
|
|
|
+ case 4:
|
|
|
switch (egg_tex->get_format()) {
|
|
|
+ case EggTexture::F_unspecified:
|
|
|
case EggTexture::F_rgba:
|
|
|
- tex->set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba);
|
|
|
- break;
|
|
|
case EggTexture::F_rgbm:
|
|
|
- tex->set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgbm);
|
|
|
+ case EggTexture::F_rgba8:
|
|
|
+ case EggTexture::F_rgba4:
|
|
|
+ case EggTexture::F_rgba5:
|
|
|
+ case EggTexture::F_srgb_alpha:
|
|
|
break;
|
|
|
case EggTexture::F_rgba12:
|
|
|
- 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(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba12);
|
|
|
- } else {
|
|
|
+ if (!egg_force_srgb_textures || tex->get_component_width() < 2) {
|
|
|
egg2pg_cat.warning()
|
|
|
- << "Ignoring inappropriate format " << egg_tex->get_format()
|
|
|
+ << "Inappropriate format " << egg_tex->get_format()
|
|
|
<< " for 8-bit texture " << egg_tex->get_name() << "\n";
|
|
|
}
|
|
|
break;
|
|
|
- case EggTexture::F_rgba8:
|
|
|
- tex->set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba8);
|
|
|
- break;
|
|
|
- case EggTexture::F_rgba4:
|
|
|
- tex->set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba4);
|
|
|
- break;
|
|
|
- case EggTexture::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;
|
|
|
-
|
|
|
default:
|
|
|
- egg2pg_cat.warning()
|
|
|
- << "Ignoring inappropriate format " << egg_tex->get_format()
|
|
|
+ egg2pg_cat.error()
|
|
|
+ << "Inappropriate format " << egg_tex->get_format()
|
|
|
<< " for 4-component texture " << egg_tex->get_name() << "\n";
|
|
|
+ }
|
|
|
+ break;
|
|
|
|
|
|
- case EggTexture::F_unspecified:
|
|
|
- if (force_srgb) {
|
|
|
- tex->set_format(Texture::F_srgb_alpha);
|
|
|
- }
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Returns the Texture::Format enum corresponding to the EggTexture::Format.
|
|
|
+ * Returns 0 if the compression mode is unspecified.
|
|
|
+ */
|
|
|
+Texture::Format EggLoader::
|
|
|
+convert_format(EggTexture::Format format, EggTexture::EnvType env) {
|
|
|
+ bool force_srgb = false;
|
|
|
+ if (egg_force_srgb_textures) {
|
|
|
+ switch (env) {
|
|
|
+ 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;
|
|
|
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 (format) {
|
|
|
+ case EggTexture::F_unspecified:
|
|
|
+ // Gets handled in TexturePool
|
|
|
+ return (Texture::Format)0;
|
|
|
+
|
|
|
+ case EggTexture::F_red:
|
|
|
+ return Texture::F_red;
|
|
|
+
|
|
|
+ case EggTexture::F_green:
|
|
|
+ return Texture::F_green;
|
|
|
+
|
|
|
+ case EggTexture::F_blue:
|
|
|
+ return Texture::F_blue;
|
|
|
+
|
|
|
+ case EggTexture::F_alpha:
|
|
|
+ return Texture::F_alpha;
|
|
|
+
|
|
|
+ case EggTexture::F_luminance:
|
|
|
+ return (force_srgb ? Texture::F_sluminance : Texture::F_luminance);
|
|
|
+
|
|
|
+ case EggTexture::F_rgba:
|
|
|
+ return (force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba);
|
|
|
+
|
|
|
+ case EggTexture::F_rgbm:
|
|
|
+ return (force_srgb ? Texture::F_srgb_alpha : Texture::F_rgbm);
|
|
|
+
|
|
|
+ case EggTexture::F_rgba12:
|
|
|
+ return (force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba12);
|
|
|
+
|
|
|
+ case EggTexture::F_rgba8:
|
|
|
+ return (force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba8);
|
|
|
+
|
|
|
+ case EggTexture::F_rgba4:
|
|
|
+ return (force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba4);
|
|
|
+
|
|
|
+ case EggTexture::F_rgba5:
|
|
|
+ return (force_srgb ? Texture::F_srgb : Texture::F_rgba5);
|
|
|
+
|
|
|
+ case EggTexture::F_rgb:
|
|
|
+ return (force_srgb ? Texture::F_srgb : Texture::F_rgb);
|
|
|
+
|
|
|
+ case EggTexture::F_rgb12:
|
|
|
+ return (force_srgb ? Texture::F_srgb : Texture::F_rgb12);
|
|
|
+
|
|
|
+ case EggTexture::F_rgb8:
|
|
|
+ return (force_srgb ? Texture::F_srgb : Texture::F_rgb8);
|
|
|
+
|
|
|
+ case EggTexture::F_rgb5:
|
|
|
+ return (force_srgb ? Texture::F_srgb : Texture::F_rgb5);
|
|
|
+
|
|
|
+ case EggTexture::F_rgb332:
|
|
|
+ return (force_srgb ? Texture::F_srgb : Texture::F_rgb332);
|
|
|
+
|
|
|
+ case EggTexture::F_luminance_alpha:
|
|
|
+ return (force_srgb ? Texture::F_sluminance_alpha : Texture::F_luminance_alpha);
|
|
|
+
|
|
|
+ case EggTexture::F_luminance_alphamask:
|
|
|
+ return (force_srgb ? Texture::F_sluminance_alpha : Texture::F_luminance_alphamask);
|
|
|
+
|
|
|
+ case EggTexture::F_srgb:
|
|
|
+ return Texture::F_srgb;
|
|
|
+
|
|
|
+ case EggTexture::F_srgb_alpha:
|
|
|
+ return Texture::F_srgb_alpha;
|
|
|
}
|
|
|
|
|
|
- switch (egg_tex->get_quality_level()) {
|
|
|
+ egg2pg_cat.warning()
|
|
|
+ << "Unexpected format scalar: " << (int)format << "\n";
|
|
|
+ return (Texture::Format)0;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Returns the Texture::QualityLevel enum corresponding to the
|
|
|
+ * EggTexture::QualityLevel. Returns QL_default if the quality level is
|
|
|
+ * unspecified.
|
|
|
+ */
|
|
|
+Texture::QualityLevel EggLoader::
|
|
|
+convert_quality_level(EggTexture::QualityLevel quality) {
|
|
|
+ switch (quality) {
|
|
|
case EggTexture::QL_unspecified:
|
|
|
case EggTexture::QL_default:
|
|
|
- tex->set_quality_level(Texture::QL_default);
|
|
|
- break;
|
|
|
+ return Texture::QL_default;
|
|
|
|
|
|
case EggTexture::QL_fastest:
|
|
|
- tex->set_quality_level(Texture::QL_fastest);
|
|
|
- break;
|
|
|
-
|
|
|
- case EggTexture::QL_normal:
|
|
|
- tex->set_quality_level(Texture::QL_normal);
|
|
|
- break;
|
|
|
+ return Texture::QL_fastest;
|
|
|
|
|
|
case EggTexture::QL_best:
|
|
|
- tex->set_quality_level(Texture::QL_best);
|
|
|
- break;
|
|
|
+ return Texture::QL_best;
|
|
|
+
|
|
|
+ case EggTexture::QL_normal:
|
|
|
+ return Texture::QL_normal;
|
|
|
}
|
|
|
+ return Texture::QL_default;
|
|
|
}
|
|
|
|
|
|
/**
|