better fixes for auto-compressed textures

This commit is contained in:
David Rose 2009-01-16 18:01:35 +00:00
parent 2f47cbbb17
commit 32581604cf
12 changed files with 271 additions and 156 deletions

View File

@ -196,14 +196,6 @@ ConfigVariableString red_blue_stereo_colors
"be a two-word string, where each word is one of 'red', 'blue', " "be a two-word string, where each word is one of 'red', 'blue', "
"'green', or 'alpha'.")); "'green', or 'alpha'."));
ConfigVariableBool auto_generate_mipmaps
("auto-generate-mipmaps", false,
PRC_DESC("Set this true to use the hardware to generate mipmaps "
"automatically in all cases, if supported. Set it false "
"to generate mipmaps in software when possible. This is "
"false by default because some drivers (Intel) seem to do a "
"poor job of generating mipmaps when needed."));
ConfigVariableBool color_scale_via_lighting ConfigVariableBool color_scale_via_lighting
("color-scale-via-lighting", true, ("color-scale-via-lighting", true,
PRC_DESC("When this is true, Panda will try to implement ColorAttribs and " PRC_DESC("When this is true, Panda will try to implement ColorAttribs and "

View File

@ -57,7 +57,6 @@ extern EXPCL_PANDA_DISPLAY ConfigVariableBool copy_texture_inverted;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool window_inverted; extern EXPCL_PANDA_DISPLAY ConfigVariableBool window_inverted;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool red_blue_stereo; extern EXPCL_PANDA_DISPLAY ConfigVariableBool red_blue_stereo;
extern EXPCL_PANDA_DISPLAY ConfigVariableString red_blue_stereo_colors; extern EXPCL_PANDA_DISPLAY ConfigVariableString red_blue_stereo_colors;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool auto_generate_mipmaps;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool color_scale_via_lighting; extern EXPCL_PANDA_DISPLAY ConfigVariableBool color_scale_via_lighting;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool alpha_scale_via_texture; extern EXPCL_PANDA_DISPLAY ConfigVariableBool alpha_scale_via_texture;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool allow_incomplete_render; extern EXPCL_PANDA_DISPLAY ConfigVariableBool allow_incomplete_render;

View File

@ -934,6 +934,21 @@ load_texture(TextureDef &def, EggTexture *egg_tex) {
options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_preload_simple); options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_preload_simple);
} }
if (!egg_ignore_filters && !egg_ignore_mipmaps) {
switch (egg_tex->get_minfilter()) {
case EggTexture::FT_nearest:
case EggTexture::FT_linear:
case EggTexture::FT_unspecified:
break;
case EggTexture::FT_nearest_mipmap_nearest:
case EggTexture::FT_linear_mipmap_nearest:
case EggTexture::FT_nearest_mipmap_linear:
case EggTexture::FT_linear_mipmap_linear:
options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_generate_mipmaps);
}
}
PT(Texture) tex; PT(Texture) tex;
switch (egg_tex->get_texture_type()) { switch (egg_tex->get_texture_type()) {
case EggTexture::TT_unspecified: case EggTexture::TT_unspecified:

View File

@ -660,11 +660,6 @@ reset() {
_supports_generate_mipmap = _supports_generate_mipmap =
has_extension("GL_SGIS_generate_mipmap") || is_at_least_version(1, 4); has_extension("GL_SGIS_generate_mipmap") || is_at_least_version(1, 4);
// Temporary hack. There is an issue with auto-generating mipmaps
// for pre-compressed images, on certain drivers. Until I check in
// a fix, let's turn off this feature in general.
_supports_generate_mipmap = false;
_supports_multitexture = false; _supports_multitexture = false;
_supports_mesa_6 = false; _supports_mesa_6 = false;
@ -7278,9 +7273,12 @@ upload_texture_image(CLP(TextureContext) *gtc,
if (num_ram_mipmap_levels == 1) { if (num_ram_mipmap_levels == 1) {
// No RAM mipmap levels available. Should we generate some? // No RAM mipmap levels available. Should we generate some?
if (!_supports_generate_mipmap || if (!_supports_generate_mipmap || !driver_generate_mipmaps ||
(!auto_generate_mipmaps && image_compression == Texture::CM_off)) { image_compression != Texture::CM_off) {
// Yes, the GL won't generate them, so we need to. // Yes, the GL can't or won't generate them, so we need to.
// Note that some drivers (nVidia) will *corrupt memory* if
// you ask them to generate mipmaps for a pre-compressed
// texture.
tex->generate_ram_mipmap_images(); tex->generate_ram_mipmap_images();
num_ram_mipmap_levels = tex->get_num_ram_mipmap_images(); num_ram_mipmap_levels = tex->get_num_ram_mipmap_images();
} }

View File

@ -125,6 +125,15 @@ ConfigVariableBool driver_compress_textures
"and will always be handed to the graphics driver, regardless " "and will always be handed to the graphics driver, regardless "
"of this setting.")); "of this setting."));
ConfigVariableBool driver_generate_mipmaps
("driver-generate-mipmaps", false,
PRC_DESC("Set this true to use the hardware to generate mipmaps "
"automatically in all cases, if supported. Set it false "
"to generate mipmaps in software when possible. This is "
"false by default because some drivers (Intel) seem to do a "
"poor job of generating mipmaps when needed; also, generating "
"mipmaps in software may allow smoother texture loads."));
ConfigVariableBool vertex_buffers ConfigVariableBool vertex_buffers
("vertex-buffers", true, ("vertex-buffers", true,
PRC_DESC("Set this true to allow the use of vertex buffers (or buffer " PRC_DESC("Set this true to allow the use of vertex buffers (or buffer "

View File

@ -56,6 +56,7 @@ extern EXPCL_PANDA_GOBJ ConfigVariableList exclude_texture_scale;
extern EXPCL_PANDA_GOBJ ConfigVariableBool keep_texture_ram; extern EXPCL_PANDA_GOBJ ConfigVariableBool keep_texture_ram;
extern EXPCL_PANDA_GOBJ ConfigVariableBool compressed_textures; extern EXPCL_PANDA_GOBJ ConfigVariableBool compressed_textures;
extern EXPCL_PANDA_GOBJ ConfigVariableBool driver_compress_textures; extern EXPCL_PANDA_GOBJ ConfigVariableBool driver_compress_textures;
extern EXPCL_PANDA_GOBJ ConfigVariableBool driver_generate_mipmaps;
extern EXPCL_PANDA_GOBJ ConfigVariableBool vertex_buffers; extern EXPCL_PANDA_GOBJ ConfigVariableBool vertex_buffers;
extern EXPCL_PANDA_GOBJ ConfigVariableBool vertex_arrays; extern EXPCL_PANDA_GOBJ ConfigVariableBool vertex_arrays;
extern EXPCL_PANDA_GOBJ ConfigVariableBool display_lists; extern EXPCL_PANDA_GOBJ ConfigVariableBool display_lists;

View File

@ -254,7 +254,8 @@ load(const PNMImage &pnmimage, const LoaderOptions &options) {
++_properties_modified; ++_properties_modified;
++_image_modified; ++_image_modified;
if (do_load_one(pnmimage, get_name(), 0, 0, options)) { if (do_load_one(pnmimage, get_name(), 0, 0, options)) {
consider_auto_compress_ram_image(); bool generate_mipmaps = ((options.get_texture_flags() & LoaderOptions::TF_generate_mipmaps) != 0);
consider_auto_process_ram_image(generate_mipmaps || uses_mipmaps(), true);
return true; return true;
} }
return false; return false;
@ -272,7 +273,6 @@ load(const PNMImage &pnmimage, int z, int n, const LoaderOptions &options) {
++_properties_modified; ++_properties_modified;
++_image_modified; ++_image_modified;
if (do_load_one(pnmimage, get_name(), z, n, options)) { if (do_load_one(pnmimage, get_name(), z, n, options)) {
consider_auto_compress_ram_image();
return true; return true;
} }
return false; return false;
@ -1296,6 +1296,19 @@ has_ram_mipmap_image(int n) const {
return do_has_ram_mipmap_image(n); return do_has_ram_mipmap_image(n);
} }
////////////////////////////////////////////////////////////////////
// Function: Texture::has_all_ram_mipmap_images
// Access: Published
// Description: Returns true if all expected mipmap levels have been
// defined and exist in the system RAM, or false if even
// one mipmap level is missing.
////////////////////////////////////////////////////////////////////
INLINE bool Texture::
has_all_ram_mipmap_images() const {
MutexHolder holder(_lock);
return do_has_all_ram_mipmap_images();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Texture::get_ram_mipmap_image_size // Function: Texture::get_ram_mipmap_image_size
// Access: Published // Access: Published
@ -1403,6 +1416,26 @@ clear_ram_mipmap_images() {
do_clear_ram_mipmap_images(); do_clear_ram_mipmap_images();
} }
////////////////////////////////////////////////////////////////////
// Function: Texture::generate_ram_mipmap_images
// Access: Published
// Description: Automatically fills in the n mipmap levels of the
// Texture, based on the texture's source image. This
// requires the texture's uncompressed ram image to be
// available in system memory. If it is not already, it
// will be fetched if possible.
//
// This call is not normally necessary, since the mipmap
// levels will be generated automatically if needed.
// But there may be certain cases in which you would
// like to call this explicitly.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
generate_ram_mipmap_images() {
MutexHolder holder(_lock);
do_generate_ram_mipmap_images();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Texture::get_simple_x_size // Function: Texture::get_simple_x_size
// Access: Published // Access: Published

View File

@ -859,42 +859,6 @@ get_num_loadable_ram_mipmap_images() const {
return n; return n;
} }
////////////////////////////////////////////////////////////////////
// Function: Texture::has_all_ram_mipmap_images
// Access: Published
// Description: Returns true if all expected mipmap levels have been
// defined and exist in the system RAM, or false if even
// one mipmap level is missing.
////////////////////////////////////////////////////////////////////
bool Texture::
has_all_ram_mipmap_images() const {
MutexHolder holder(_lock);
if (_ram_images.empty() || _ram_images[0]._image.empty()) {
// If we don't even have a base image, the answer is no.
return false;
}
if (!is_mipmap(_minfilter)) {
// If we have a base image and don't require mipmapping, the
// answer is yes.
return true;
}
// Check that we have enough mipmap levels to meet the size
// requirements.
int size = max(_x_size, max(_y_size, _z_size));
int n = 0;
int x = 1;
while (x < size) {
x = (x << 1);
++n;
if (n >= (int)_ram_images.size() || _ram_images[n]._image.empty()) {
return false;
}
}
return true;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Texture::get_ram_mipmap_image // Function: Texture::get_ram_mipmap_image
// Access: Published // Access: Published
@ -959,67 +923,6 @@ clear_ram_mipmap_image(int n) {
_ram_images[n]._page_size = 0; _ram_images[n]._page_size = 0;
} }
////////////////////////////////////////////////////////////////////
// Function: Texture::generate_ram_mipmap_images
// Access: Published
// Description: Automatically fills in the n mipmap levels of the
// Texture, based on the texture's source image. This
// requires the texture's uncompressed ram image to be
// available in system memory. If it is not already, it
// will be fetched if possible.
//
// This call is not normally necessary, since the mipmap
// levels will be generated automatically if needed.
// But there may be certain cases in which you would
// like to call this explicitly.
////////////////////////////////////////////////////////////////////
void Texture::
generate_ram_mipmap_images() {
MutexHolder holder(_lock);
do_get_uncompressed_ram_image();
nassertv(do_has_ram_image());
nassertv(_ram_image_compression == CM_off);
nassertv(_component_type != T_float);
do_clear_ram_mipmap_images();
if (gobj_cat.is_debug()) {
gobj_cat.debug()
<< "Generating mipmap levels for " << *this << "\n";
}
if (_texture_type == Texture::TT_3d_texture && _z_size != 1) {
// Eek, a 3-D texture.
int x_size = _x_size;
int y_size = _y_size;
int z_size = _z_size;
int n = 0;
while (x_size > 1 || y_size > 1 || z_size > 1) {
_ram_images.push_back(RamImage());
filter_3d_mipmap_level(_ram_images[n + 1], _ram_images[n],
x_size, y_size, z_size);
x_size = max(x_size >> 1, 1);
y_size = max(y_size >> 1, 1);
z_size = max(z_size >> 1, 1);
++n;
}
} else {
// A 1-D, 2-D, or cube map texture.
int x_size = _x_size;
int y_size = _y_size;
int n = 0;
while (x_size > 1 || y_size > 1) {
_ram_images.push_back(RamImage());
filter_2d_mipmap_pages(_ram_images[n + 1], _ram_images[n],
x_size, y_size);
x_size = max(x_size >> 1, 1);
y_size = max(y_size >> 1, 1);
++n;
}
}
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Texture::modify_simple_ram_image // Function: Texture::modify_simple_ram_image
// Access: Published // Access: Published
@ -2097,8 +2000,9 @@ do_read(const Filename &fullpath, const Filename &alpha_fullpath,
} else { } else {
if ((options.get_texture_flags() & LoaderOptions::TF_preload) != 0) { if ((options.get_texture_flags() & LoaderOptions::TF_preload) != 0) {
// If we intend to keep the ram image around, consider // If we intend to keep the ram image around, consider
// compressing it. // compressing it etc.
consider_auto_compress_ram_image(); bool generate_mipmaps = ((options.get_texture_flags() & LoaderOptions::TF_generate_mipmaps) != 0);
consider_auto_process_ram_image(generate_mipmaps || uses_mipmaps(), true);
} }
} }
@ -3029,8 +2933,11 @@ do_reload_ram_image(bool allow_compression) {
_ram_images = tex->_ram_images; _ram_images = tex->_ram_images;
_loaded_from_image = true; _loaded_from_image = true;
if (allow_compression && consider_auto_compress_ram_image()) { bool was_compressed = (_ram_image_compression != CM_off);
if (cache->get_cache_compressed_textures()) { if (consider_auto_process_ram_image(uses_mipmaps(), allow_compression)) {
bool is_compressed = (_ram_image_compression != CM_off);
if (!was_compressed && is_compressed &&
cache->get_cache_compressed_textures()) {
// We've re-compressed the image after loading it from the // We've re-compressed the image after loading it from the
// cache. To keep the cache current, rewrite it to the // cache. To keep the cache current, rewrite it to the
// cache now, in its newly compressed form. // cache now, in its newly compressed form.
@ -3153,38 +3060,44 @@ do_make_ram_mipmap_image(int n) {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Texture::consider_auto_compress_ram_image // Function: Texture::consider_auto_process_ram_image
// Access: Protected // Access: Protected
// Description: Should be called after a texture has been loaded into // Description: Should be called after a texture has been loaded into
// RAM, this considers compressing the RAM image, if // RAM, this considers generating mipmaps and/or
// cpu-compress-textures has been set and the default // compressing the RAM image.
// GSG has been set and supports it. //
// Returns true if the image was modified by this // Returns true if the image was modified by this
// operation, false if it wasn't. // operation, false if it wasn't.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool Texture:: bool Texture::
consider_auto_compress_ram_image() { consider_auto_process_ram_image(bool generate_mipmaps, bool allow_compression) {
if (!driver_compress_textures) { bool modified = false;
if (generate_mipmaps && !driver_generate_mipmaps &&
_ram_images.size() == 1) {
do_generate_ram_mipmap_images();
modified = true;
}
if (allow_compression && !driver_compress_textures) {
CompressionMode compression = _compression; CompressionMode compression = _compression;
if (compression == CM_default) { if (compression == CM_default && compressed_textures) {
if (!compressed_textures) {
return false;
}
compression = CM_on; compression = CM_on;
} }
if (compression != CM_off && _ram_image_compression == CM_off) { if (compression != CM_off && _ram_image_compression == CM_off) {
GraphicsStateGuardianBase *gsg = GraphicsStateGuardianBase::get_default_gsg(); GraphicsStateGuardianBase *gsg = GraphicsStateGuardianBase::get_default_gsg();
if (do_compress_ram_image(compression, QL_default, gsg)) { if (do_compress_ram_image(compression, QL_default, gsg)) {
gobj_cat.info() if (gobj_cat.is_debug()) {
<< "Compressed " << get_name() << " with " gobj_cat.debug()
<< _ram_image_compression << "\n"; << "Compressed " << get_name() << " with "
return true; << _ram_image_compression << "\n";
}
modified = true;
} }
} }
} }
return false; return modified;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -3324,6 +3237,39 @@ do_uncompress_ram_image() {
return false; return false;
} }
////////////////////////////////////////////////////////////////////
// Function: Texture::do_has_all_ram_mipmap_images
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
bool Texture::
do_has_all_ram_mipmap_images() const {
if (_ram_images.empty() || _ram_images[0]._image.empty()) {
// If we don't even have a base image, the answer is no.
return false;
}
if (!is_mipmap(_minfilter)) {
// If we have a base image and don't require mipmapping, the
// answer is yes.
return true;
}
// Check that we have enough mipmap levels to meet the size
// requirements.
int size = max(_x_size, max(_y_size, _z_size));
int n = 0;
int x = 1;
while (x < size) {
x = (x << 1);
++n;
if (n >= (int)_ram_images.size() || _ram_images[n]._image.empty()) {
return false;
}
}
return true;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Texture::do_reconsider_z_size // Function: Texture::do_reconsider_z_size
// Access: Protected // Access: Protected
@ -3866,8 +3812,10 @@ do_get_uncompressed_ram_image() {
// We have an image in-ram, but it's compressed. Try to // We have an image in-ram, but it's compressed. Try to
// uncompress it first. // uncompress it first.
if (do_uncompress_ram_image()) { if (do_uncompress_ram_image()) {
gobj_cat.info() if (gobj_cat.is_debug()) {
<< "Uncompressed " << get_name() << "\n"; gobj_cat.debug()
<< "Uncompressed " << get_name() << "\n";
}
return _ram_images[0]._image; return _ram_images[0]._image;
} }
} }
@ -4172,6 +4120,103 @@ do_clear_ram_mipmap_images() {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: Texture::do_generate_ram_mipmap_images
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void Texture::
do_generate_ram_mipmap_images() {
nassertv(do_has_ram_image());
nassertv(_component_type != T_float);
if (do_get_expected_num_mipmap_levels() == 1) {
// Don't bother.
return;
}
RamImage orig_compressed_image;
CompressionMode orig_compression_mode = CM_off;
if (_ram_image_compression != CM_off) {
// The RAM image is compressed. This means we need to uncompress
// it in order to generate mipmap images. Save the original
// first, to avoid lossy recompression.
orig_compressed_image = _ram_images[0];
orig_compression_mode = _ram_image_compression;
// Now try to get the uncompressed source image.
do_get_uncompressed_ram_image();
nassertv(_ram_image_compression == CM_off);
}
do_clear_ram_mipmap_images();
if (gobj_cat.is_debug()) {
gobj_cat.debug()
<< "Generating mipmap levels for " << *this << "\n";
}
if (_texture_type == Texture::TT_3d_texture && _z_size != 1) {
// Eek, a 3-D texture.
int x_size = _x_size;
int y_size = _y_size;
int z_size = _z_size;
int n = 0;
while (x_size > 1 || y_size > 1 || z_size > 1) {
_ram_images.push_back(RamImage());
filter_3d_mipmap_level(_ram_images[n + 1], _ram_images[n],
x_size, y_size, z_size);
x_size = max(x_size >> 1, 1);
y_size = max(y_size >> 1, 1);
z_size = max(z_size >> 1, 1);
++n;
}
} else {
// A 1-D, 2-D, or cube map texture.
int x_size = _x_size;
int y_size = _y_size;
int n = 0;
while (x_size > 1 || y_size > 1) {
_ram_images.push_back(RamImage());
filter_2d_mipmap_pages(_ram_images[n + 1], _ram_images[n],
x_size, y_size);
x_size = max(x_size >> 1, 1);
y_size = max(y_size >> 1, 1);
++n;
}
}
if (orig_compression_mode != CM_off) {
// Now attempt to recompress the mipmap images according to the
// original compression mode. We don't need to bother compressing
// the first image (it was already compressed, after all), so
// temporarily remove it from the top of the mipmap stack, and
// compress all of the rest of them instead.
nassertv(_ram_images.size() > 1);
int l0_x_size = _x_size;
int l0_y_size = _y_size;
int l0_z_size = _z_size;
_x_size = do_get_expected_mipmap_x_size(1);
_y_size = do_get_expected_mipmap_y_size(1);
_z_size = do_get_expected_mipmap_z_size(1);
RamImage uncompressed_image = _ram_images[0];
_ram_images.erase(_ram_images.begin());
bool success = do_compress_ram_image(orig_compression_mode, QL_default, NULL);
// Now restore the toplevel image.
if (success) {
_ram_images.insert(_ram_images.begin(), orig_compressed_image);
} else {
_ram_images.insert(_ram_images.begin(), uncompressed_image);
}
_x_size = l0_x_size;
_y_size = l0_y_size;
_z_size = l0_z_size;
}
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Texture::do_set_pad_size // Function: Texture::do_set_pad_size
// Access: Protected // Access: Protected
@ -5328,6 +5373,13 @@ do_squish(Texture::CompressionMode compression, int squish_flags) {
if (_ram_images.empty()) { if (_ram_images.empty()) {
return false; return false;
} }
if (!do_has_all_ram_mipmap_images()) {
// If we're about to compress the RAM image, we should ensure that
// we have all of the mipmap levels first.
do_generate_ram_mipmap_images();
}
RamImages compressed_ram_images; RamImages compressed_ram_images;
compressed_ram_images.reserve(_ram_images.size()); compressed_ram_images.reserve(_ram_images.size());
for (size_t n = 0; n < _ram_images.size(); ++n) { for (size_t n = 0; n < _ram_images.size(); ++n) {
@ -5562,28 +5614,31 @@ make_from_bam(const FactoryParams &params) {
} }
} }
LoaderOptions options = manager->get_loader_options();
if (false) { // temporary hack standin
options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_generate_mipmaps);
}
switch (texture_type) { switch (texture_type) {
case TT_1d_texture: case TT_1d_texture:
case TT_2d_texture: case TT_2d_texture:
if (alpha_filename.empty()) { if (alpha_filename.empty()) {
me = TexturePool::load_texture(filename, primary_file_num_channels, me = TexturePool::load_texture(filename, primary_file_num_channels,
false, manager->get_loader_options()); false, options);
} else { } else {
me = TexturePool::load_texture(filename, alpha_filename, me = TexturePool::load_texture(filename, alpha_filename,
primary_file_num_channels, primary_file_num_channels,
alpha_file_channel, alpha_file_channel,
false, manager->get_loader_options()); false, options);
} }
break; break;
case TT_3d_texture: case TT_3d_texture:
me = TexturePool::load_3d_texture(filename, false, me = TexturePool::load_3d_texture(filename, false, options);
manager->get_loader_options());
break; break;
case TT_cube_map: case TT_cube_map:
me = TexturePool::load_cube_map(filename, false, me = TexturePool::load_cube_map(filename, false, options);
manager->get_loader_options());
break; break;
} }
} }
@ -5822,7 +5877,7 @@ write_datagram(BamWriter *manager, Datagram &me) {
me.add_string(alpha_filename); me.add_string(alpha_filename);
me.add_uint8(_primary_file_num_channels); me.add_uint8(_primary_file_num_channels);
me.add_uint8(_alpha_file_channel); me.add_uint8(_alpha_file_channel);
me.add_uint8(has_rawdata); me.add_bool(has_rawdata);
me.add_uint8(_texture_type); me.add_uint8(_texture_type);
// The data beginning at this point is handled by fillin(). // The data beginning at this point is handled by fillin().

View File

@ -321,7 +321,7 @@ PUBLISHED:
INLINE int get_num_ram_mipmap_images() const; INLINE int get_num_ram_mipmap_images() const;
INLINE bool has_ram_mipmap_image(int n) const; INLINE bool has_ram_mipmap_image(int n) const;
int get_num_loadable_ram_mipmap_images() const; int get_num_loadable_ram_mipmap_images() const;
bool has_all_ram_mipmap_images() const; INLINE bool has_all_ram_mipmap_images() const;
INLINE size_t get_ram_mipmap_image_size(int n) const; INLINE size_t get_ram_mipmap_image_size(int n) const;
INLINE size_t get_ram_mipmap_page_size(int n) const; INLINE size_t get_ram_mipmap_page_size(int n) const;
INLINE size_t get_expected_ram_mipmap_image_size(int n) const; INLINE size_t get_expected_ram_mipmap_image_size(int n) const;
@ -332,7 +332,7 @@ PUBLISHED:
void set_ram_mipmap_image(int n, PTA_uchar image, size_t page_size = 0); void set_ram_mipmap_image(int n, PTA_uchar image, size_t page_size = 0);
void clear_ram_mipmap_image(int n); void clear_ram_mipmap_image(int n);
INLINE void clear_ram_mipmap_images(); INLINE void clear_ram_mipmap_images();
void generate_ram_mipmap_images(); INLINE void generate_ram_mipmap_images();
INLINE int get_simple_x_size() const; INLINE int get_simple_x_size() const;
INLINE int get_simple_y_size() const; INLINE int get_simple_y_size() const;
@ -480,11 +480,13 @@ protected:
PTA_uchar do_modify_ram_mipmap_image(int n); PTA_uchar do_modify_ram_mipmap_image(int n);
PTA_uchar do_make_ram_mipmap_image(int n); PTA_uchar do_make_ram_mipmap_image(int n);
bool consider_auto_compress_ram_image(); bool consider_auto_process_ram_image(bool generate_mipmaps,
bool allow_compression);
bool do_compress_ram_image(CompressionMode compression, bool do_compress_ram_image(CompressionMode compression,
QualityLevel quality_level, QualityLevel quality_level,
GraphicsStateGuardianBase *gsg); GraphicsStateGuardianBase *gsg);
bool do_uncompress_ram_image(); bool do_uncompress_ram_image();
bool do_has_all_ram_mipmap_images() const;
bool do_reconsider_z_size(int z); bool do_reconsider_z_size(int z);
bool do_reconsider_image_properties(int x_size, int y_size, int num_components, bool do_reconsider_image_properties(int x_size, int y_size, int num_components,
@ -533,6 +535,7 @@ protected:
INLINE void do_clear_ram_image(); INLINE void do_clear_ram_image();
void do_clear_simple_ram_image(); void do_clear_simple_ram_image();
void do_clear_ram_mipmap_images(); void do_clear_ram_mipmap_images();
void do_generate_ram_mipmap_images();
void do_set_pad_size(int x, int y, int z); void do_set_pad_size(int x, int y, int z);
// This nested class declaration is used below. // This nested class declaration is used below.

View File

@ -921,14 +921,20 @@ try_load_cache(PT(Texture) &tex, BamCache *cache, const Filename &filename,
// But drop the RAM until we need it. // But drop the RAM until we need it.
tex->clear_ram_image(); tex->clear_ram_image();
} else if (tex->consider_auto_compress_ram_image()) { } else {
if (cache->get_cache_compressed_textures()) { bool was_compressed = (tex->get_ram_image_compression() != Texture::CM_off);
// We've re-compressed the image after loading it from the if (tex->consider_auto_process_ram_image(tex->uses_mipmaps(), true)) {
// cache. To keep the cache current, rewrite it to the bool is_compressed = (tex->get_ram_image_compression() != Texture::CM_off);
// cache now, in its newly compressed form. if (!was_compressed && is_compressed &&
record->set_data(tex, false); cache->get_cache_compressed_textures()) {
cache->store(record); // We've re-compressed the image after loading it
compressed_cache_record = true; // from the cache. To keep the cache current,
// rewrite it to the cache now, in its newly
// compressed form.
record->set_data(tex, false);
cache->store(record);
compressed_cache_record = true;
}
} }
} }
tex->set_keep_ram_image(false); tex->set_keep_ram_image(false);

View File

@ -57,6 +57,7 @@ output(ostream &out) const {
write_flag(out, sep, "LF_no_disk_cache", LF_no_disk_cache); write_flag(out, sep, "LF_no_disk_cache", LF_no_disk_cache);
write_flag(out, sep, "LF_no_ram_cache", LF_no_ram_cache); write_flag(out, sep, "LF_no_ram_cache", LF_no_ram_cache);
} }
write_flag(out, sep, "LF_allow_instance", LF_allow_instance);
if (sep.empty()) { if (sep.empty()) {
out << "0"; out << "0";
} }
@ -66,6 +67,8 @@ output(ostream &out) const {
sep = ""; sep = "";
write_texture_flag(out, sep, "TF_preload", TF_preload); write_texture_flag(out, sep, "TF_preload", TF_preload);
write_texture_flag(out, sep, "TF_preload_simple", TF_preload_simple); write_texture_flag(out, sep, "TF_preload_simple", TF_preload_simple);
write_texture_flag(out, sep, "TF_allow_1d", TF_allow_1d);
write_texture_flag(out, sep, "TF_generate_mipmaps", TF_generate_mipmaps);
if (sep.empty()) { if (sep.empty()) {
out << "0"; out << "0";
} }

View File

@ -43,6 +43,7 @@ PUBLISHED:
TF_preload = 0x0004, // Texture will have RAM image TF_preload = 0x0004, // Texture will have RAM image
TF_preload_simple = 0x0008, // Texture will have simple RAM image TF_preload_simple = 0x0008, // Texture will have simple RAM image
TF_allow_1d = 0x0010, // If texture is Nx1, make a 1-d texture TF_allow_1d = 0x0010, // If texture is Nx1, make a 1-d texture
TF_generate_mipmaps = 0x0020, // Consider generating mipmaps
}; };
LoaderOptions(int flags = LF_search | LF_report_errors); LoaderOptions(int flags = LF_search | LF_report_errors);