mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 18:03:56 -04:00
better fixes for auto-compressed textures
This commit is contained in:
parent
2f47cbbb17
commit
32581604cf
@ -196,14 +196,6 @@ ConfigVariableString red_blue_stereo_colors
|
||||
"be a two-word string, where each word is one of 'red', 'blue', "
|
||||
"'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
|
||||
("color-scale-via-lighting", true,
|
||||
PRC_DESC("When this is true, Panda will try to implement ColorAttribs and "
|
||||
|
@ -57,7 +57,6 @@ extern EXPCL_PANDA_DISPLAY ConfigVariableBool copy_texture_inverted;
|
||||
extern EXPCL_PANDA_DISPLAY ConfigVariableBool window_inverted;
|
||||
extern EXPCL_PANDA_DISPLAY ConfigVariableBool red_blue_stereo;
|
||||
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 alpha_scale_via_texture;
|
||||
extern EXPCL_PANDA_DISPLAY ConfigVariableBool allow_incomplete_render;
|
||||
|
@ -934,6 +934,21 @@ load_texture(TextureDef &def, EggTexture *egg_tex) {
|
||||
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;
|
||||
switch (egg_tex->get_texture_type()) {
|
||||
case EggTexture::TT_unspecified:
|
||||
|
@ -660,11 +660,6 @@ reset() {
|
||||
_supports_generate_mipmap =
|
||||
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_mesa_6 = false;
|
||||
@ -7278,9 +7273,12 @@ upload_texture_image(CLP(TextureContext) *gtc,
|
||||
|
||||
if (num_ram_mipmap_levels == 1) {
|
||||
// No RAM mipmap levels available. Should we generate some?
|
||||
if (!_supports_generate_mipmap ||
|
||||
(!auto_generate_mipmaps && image_compression == Texture::CM_off)) {
|
||||
// Yes, the GL won't generate them, so we need to.
|
||||
if (!_supports_generate_mipmap || !driver_generate_mipmaps ||
|
||||
image_compression != Texture::CM_off) {
|
||||
// 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();
|
||||
num_ram_mipmap_levels = tex->get_num_ram_mipmap_images();
|
||||
}
|
||||
|
@ -125,6 +125,15 @@ ConfigVariableBool driver_compress_textures
|
||||
"and will always be handed to the graphics driver, regardless "
|
||||
"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
|
||||
("vertex-buffers", true,
|
||||
PRC_DESC("Set this true to allow the use of vertex buffers (or buffer "
|
||||
|
@ -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 compressed_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_arrays;
|
||||
extern EXPCL_PANDA_GOBJ ConfigVariableBool display_lists;
|
||||
|
@ -254,7 +254,8 @@ load(const PNMImage &pnmimage, const LoaderOptions &options) {
|
||||
++_properties_modified;
|
||||
++_image_modified;
|
||||
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 false;
|
||||
@ -272,7 +273,6 @@ load(const PNMImage &pnmimage, int z, int n, const LoaderOptions &options) {
|
||||
++_properties_modified;
|
||||
++_image_modified;
|
||||
if (do_load_one(pnmimage, get_name(), z, n, options)) {
|
||||
consider_auto_compress_ram_image();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -1296,6 +1296,19 @@ has_ram_mipmap_image(int n) const {
|
||||
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
|
||||
// Access: Published
|
||||
@ -1403,6 +1416,26 @@ 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
|
||||
// Access: Published
|
||||
|
@ -859,42 +859,6 @@ get_num_loadable_ram_mipmap_images() const {
|
||||
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
|
||||
// Access: Published
|
||||
@ -959,67 +923,6 @@ clear_ram_mipmap_image(int n) {
|
||||
_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
|
||||
// Access: Published
|
||||
@ -2097,8 +2000,9 @@ do_read(const Filename &fullpath, const Filename &alpha_fullpath,
|
||||
} else {
|
||||
if ((options.get_texture_flags() & LoaderOptions::TF_preload) != 0) {
|
||||
// If we intend to keep the ram image around, consider
|
||||
// compressing it.
|
||||
consider_auto_compress_ram_image();
|
||||
// compressing it etc.
|
||||
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;
|
||||
_loaded_from_image = true;
|
||||
|
||||
if (allow_compression && consider_auto_compress_ram_image()) {
|
||||
if (cache->get_cache_compressed_textures()) {
|
||||
bool was_compressed = (_ram_image_compression != CM_off);
|
||||
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
|
||||
// cache. To keep the cache current, rewrite it to the
|
||||
// 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
|
||||
// Description: Should be called after a texture has been loaded into
|
||||
// RAM, this considers compressing the RAM image, if
|
||||
// cpu-compress-textures has been set and the default
|
||||
// GSG has been set and supports it.
|
||||
|
||||
// RAM, this considers generating mipmaps and/or
|
||||
// compressing the RAM image.
|
||||
//
|
||||
// Returns true if the image was modified by this
|
||||
// operation, false if it wasn't.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
consider_auto_compress_ram_image() {
|
||||
if (!driver_compress_textures) {
|
||||
consider_auto_process_ram_image(bool generate_mipmaps, bool allow_compression) {
|
||||
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;
|
||||
if (compression == CM_default) {
|
||||
if (!compressed_textures) {
|
||||
return false;
|
||||
}
|
||||
if (compression == CM_default && compressed_textures) {
|
||||
compression = CM_on;
|
||||
}
|
||||
if (compression != CM_off && _ram_image_compression == CM_off) {
|
||||
GraphicsStateGuardianBase *gsg = GraphicsStateGuardianBase::get_default_gsg();
|
||||
if (do_compress_ram_image(compression, QL_default, gsg)) {
|
||||
gobj_cat.info()
|
||||
<< "Compressed " << get_name() << " with "
|
||||
<< _ram_image_compression << "\n";
|
||||
return true;
|
||||
if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "Compressed " << get_name() << " with "
|
||||
<< _ram_image_compression << "\n";
|
||||
}
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return modified;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -3324,6 +3237,39 @@ do_uncompress_ram_image() {
|
||||
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
|
||||
// Access: Protected
|
||||
@ -3866,8 +3812,10 @@ do_get_uncompressed_ram_image() {
|
||||
// We have an image in-ram, but it's compressed. Try to
|
||||
// uncompress it first.
|
||||
if (do_uncompress_ram_image()) {
|
||||
gobj_cat.info()
|
||||
<< "Uncompressed " << get_name() << "\n";
|
||||
if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "Uncompressed " << get_name() << "\n";
|
||||
}
|
||||
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
|
||||
// Access: Protected
|
||||
@ -5328,6 +5373,13 @@ do_squish(Texture::CompressionMode compression, int squish_flags) {
|
||||
if (_ram_images.empty()) {
|
||||
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;
|
||||
compressed_ram_images.reserve(_ram_images.size());
|
||||
for (size_t n = 0; n < _ram_images.size(); ++n) {
|
||||
@ -5562,28 +5614,31 @@ make_from_bam(const FactoryParams ¶ms) {
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
case TT_1d_texture:
|
||||
case TT_2d_texture:
|
||||
if (alpha_filename.empty()) {
|
||||
me = TexturePool::load_texture(filename, primary_file_num_channels,
|
||||
false, manager->get_loader_options());
|
||||
false, options);
|
||||
} else {
|
||||
me = TexturePool::load_texture(filename, alpha_filename,
|
||||
primary_file_num_channels,
|
||||
alpha_file_channel,
|
||||
false, manager->get_loader_options());
|
||||
false, options);
|
||||
}
|
||||
break;
|
||||
|
||||
case TT_3d_texture:
|
||||
me = TexturePool::load_3d_texture(filename, false,
|
||||
manager->get_loader_options());
|
||||
me = TexturePool::load_3d_texture(filename, false, options);
|
||||
break;
|
||||
|
||||
case TT_cube_map:
|
||||
me = TexturePool::load_cube_map(filename, false,
|
||||
manager->get_loader_options());
|
||||
me = TexturePool::load_cube_map(filename, false, options);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -5822,7 +5877,7 @@ write_datagram(BamWriter *manager, Datagram &me) {
|
||||
me.add_string(alpha_filename);
|
||||
me.add_uint8(_primary_file_num_channels);
|
||||
me.add_uint8(_alpha_file_channel);
|
||||
me.add_uint8(has_rawdata);
|
||||
me.add_bool(has_rawdata);
|
||||
me.add_uint8(_texture_type);
|
||||
|
||||
// The data beginning at this point is handled by fillin().
|
||||
|
@ -321,7 +321,7 @@ PUBLISHED:
|
||||
INLINE int get_num_ram_mipmap_images() const;
|
||||
INLINE bool has_ram_mipmap_image(int n) 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_page_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 clear_ram_mipmap_image(int n);
|
||||
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_y_size() const;
|
||||
@ -480,11 +480,13 @@ protected:
|
||||
PTA_uchar do_modify_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,
|
||||
QualityLevel quality_level,
|
||||
GraphicsStateGuardianBase *gsg);
|
||||
bool do_uncompress_ram_image();
|
||||
bool do_has_all_ram_mipmap_images() const;
|
||||
|
||||
bool do_reconsider_z_size(int z);
|
||||
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();
|
||||
void do_clear_simple_ram_image();
|
||||
void do_clear_ram_mipmap_images();
|
||||
void do_generate_ram_mipmap_images();
|
||||
void do_set_pad_size(int x, int y, int z);
|
||||
|
||||
// This nested class declaration is used below.
|
||||
|
@ -921,14 +921,20 @@ try_load_cache(PT(Texture) &tex, BamCache *cache, const Filename &filename,
|
||||
// But drop the RAM until we need it.
|
||||
tex->clear_ram_image();
|
||||
|
||||
} else if (tex->consider_auto_compress_ram_image()) {
|
||||
if (cache->get_cache_compressed_textures()) {
|
||||
// We've re-compressed the image after loading it 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;
|
||||
} else {
|
||||
bool was_compressed = (tex->get_ram_image_compression() != Texture::CM_off);
|
||||
if (tex->consider_auto_process_ram_image(tex->uses_mipmaps(), true)) {
|
||||
bool is_compressed = (tex->get_ram_image_compression() != Texture::CM_off);
|
||||
if (!was_compressed && is_compressed &&
|
||||
cache->get_cache_compressed_textures()) {
|
||||
// We've re-compressed the image after loading it
|
||||
// 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);
|
||||
|
@ -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_ram_cache", LF_no_ram_cache);
|
||||
}
|
||||
write_flag(out, sep, "LF_allow_instance", LF_allow_instance);
|
||||
if (sep.empty()) {
|
||||
out << "0";
|
||||
}
|
||||
@ -66,6 +67,8 @@ output(ostream &out) const {
|
||||
sep = "";
|
||||
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_allow_1d", TF_allow_1d);
|
||||
write_texture_flag(out, sep, "TF_generate_mipmaps", TF_generate_mipmaps);
|
||||
if (sep.empty()) {
|
||||
out << "0";
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ PUBLISHED:
|
||||
TF_preload = 0x0004, // Texture will have 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_generate_mipmaps = 0x0020, // Consider generating mipmaps
|
||||
};
|
||||
|
||||
LoaderOptions(int flags = LF_search | LF_report_errors);
|
||||
|
Loading…
x
Reference in New Issue
Block a user