mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
add support for libsquish
This commit is contained in:
parent
6954933382
commit
b37a30fe63
@ -470,6 +470,13 @@
|
|||||||
// drfftw instead of rfftw.
|
// drfftw instead of rfftw.
|
||||||
#defer HAVE_DRFFTW_H $[libtest $[FFTW_LPATH],drfftw]
|
#defer HAVE_DRFFTW_H $[libtest $[FFTW_LPATH],drfftw]
|
||||||
|
|
||||||
|
// Is libsquish installed, and where?
|
||||||
|
#define SQUISH_IPATH /usr/local/include
|
||||||
|
#define SQUISH_LPATH /usr/local/lib
|
||||||
|
#define SQUISH_LIBS squish
|
||||||
|
#defer HAVE_SQUISH $[libtest $[SQUISH_LPATH],$[SQUISH_LIBS]]
|
||||||
|
|
||||||
|
|
||||||
// Is Berkeley DB installed, and where? Presently, this is only used
|
// Is Berkeley DB installed, and where? Presently, this is only used
|
||||||
// for some applications (egg-optchar in particular) in Pandatool, and
|
// for some applications (egg-optchar in particular) in Pandatool, and
|
||||||
// it is completely optional there. If available, egg-optchar takes
|
// it is completely optional there. If available, egg-optchar takes
|
||||||
|
@ -41,6 +41,11 @@
|
|||||||
#else
|
#else
|
||||||
#print - Did not find fftw
|
#print - Did not find fftw
|
||||||
#endif
|
#endif
|
||||||
|
#if $[HAVE_SQUISH]
|
||||||
|
#print + squish
|
||||||
|
#else
|
||||||
|
#print - Did not find squish
|
||||||
|
#endif
|
||||||
#if $[HAVE_CG]
|
#if $[HAVE_CG]
|
||||||
#print + Nvidia Cg High Level Shading Language
|
#print + Nvidia Cg High Level Shading Language
|
||||||
#else
|
#else
|
||||||
@ -232,6 +237,9 @@ $[cdefine HAVE_TAR]
|
|||||||
/* Define if we have libfftw installed. */
|
/* Define if we have libfftw installed. */
|
||||||
$[cdefine HAVE_FFTW]
|
$[cdefine HAVE_FFTW]
|
||||||
|
|
||||||
|
/* Define if we have libsquish installed. */
|
||||||
|
$[cdefine HAVE_SQUISH]
|
||||||
|
|
||||||
/* Define if we have Berkeley DB installed. */
|
/* Define if we have Berkeley DB installed. */
|
||||||
$[cdefine HAVE_BDB]
|
$[cdefine HAVE_BDB]
|
||||||
|
|
||||||
|
@ -145,6 +145,11 @@
|
|||||||
#set FFTW_LIBS $[FFTW_LIBS]
|
#set FFTW_LIBS $[FFTW_LIBS]
|
||||||
#set HAVE_FFTW $[HAVE_FFTW]
|
#set HAVE_FFTW $[HAVE_FFTW]
|
||||||
|
|
||||||
|
#set SQUISH_IPATH $[unixfilename $[SQUISH_IPATH]]
|
||||||
|
#set SQUISH_LPATH $[unixfilename $[SQUISH_LPATH]]
|
||||||
|
#set SQUISH_LIBS $[SQUISH_LIBS]
|
||||||
|
#set HAVE_SQUISH $[HAVE_SQUISH]
|
||||||
|
|
||||||
#set BDB_IPATH $[unixfilename $[BDB_IPATH]]
|
#set BDB_IPATH $[unixfilename $[BDB_IPATH]]
|
||||||
#set BDB_LPATH $[unixfilename $[BDB_LPATH]]
|
#set BDB_LPATH $[unixfilename $[BDB_LPATH]]
|
||||||
#set BDB_LIBS $[BDB_LIBS]
|
#set BDB_LIBS $[BDB_LIBS]
|
||||||
|
@ -241,6 +241,13 @@
|
|||||||
#define fftw_libs $[FFTW_LIBS]
|
#define fftw_libs $[FFTW_LIBS]
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if $[HAVE_SQUISH]
|
||||||
|
#define squish_ipath $[wildcard $[SQUISH_IPATH]]
|
||||||
|
#define squish_lpath $[wildcard $[SQUISH_LPATH]]
|
||||||
|
#define squish_cflags $[SQUISH_CFLAGS]
|
||||||
|
#define squish_libs $[SQUISH_LIBS]
|
||||||
|
#endif
|
||||||
|
|
||||||
#if $[HAVE_BDB]
|
#if $[HAVE_BDB]
|
||||||
#define bdb_ipath $[wildcard $[BDB_IPATH]]
|
#define bdb_ipath $[wildcard $[BDB_IPATH]]
|
||||||
#define bdb_lpath $[wildcard $[BDB_LPATH]]
|
#define bdb_lpath $[wildcard $[BDB_LPATH]]
|
||||||
|
@ -419,13 +419,15 @@ get_supports_compressed_texture() const {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GraphicsStateGuardian::get_supports_compressed_texture_format
|
// Function: GraphicsStateGuardian::get_supports_compressed_texture_format
|
||||||
// Access: Published
|
// Access: Published, Virtual
|
||||||
// Description: Returns true if this GSG can accept textures
|
// Description: Returns true if this GSG can accept textures
|
||||||
// pre-compressed in the indicated format.
|
// pre-compressed in the indicated format.
|
||||||
|
// compression_mode may be any of the
|
||||||
|
// Texture::CompressionMode enums.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE bool GraphicsStateGuardian::
|
INLINE bool GraphicsStateGuardian::
|
||||||
get_supports_compressed_texture_format(Texture::CompressionMode compression) const {
|
get_supports_compressed_texture_format(int compression_mode) const {
|
||||||
return _compressed_texture_formats.get_bit(compression);
|
return _compressed_texture_formats.get_bit(compression_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -122,7 +122,7 @@ PUBLISHED:
|
|||||||
INLINE bool get_supports_tex_non_pow2() const;
|
INLINE bool get_supports_tex_non_pow2() const;
|
||||||
|
|
||||||
INLINE bool get_supports_compressed_texture() const;
|
INLINE bool get_supports_compressed_texture() const;
|
||||||
INLINE bool get_supports_compressed_texture_format(Texture::CompressionMode compression) const;
|
virtual INLINE bool get_supports_compressed_texture_format(int compression_mode) const;
|
||||||
|
|
||||||
INLINE int get_max_lights() const;
|
INLINE int get_max_lights() const;
|
||||||
INLINE int get_max_clip_planes() const;
|
INLINE int get_max_clip_planes() const;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
|
#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
|
||||||
dtoolutil:c dtoolbase:c dtool:m prc:c
|
dtoolutil:c dtoolbase:c dtool:m prc:c
|
||||||
//#define OSX_SYS_LIBS mx
|
//#define OSX_SYS_LIBS mx
|
||||||
#define USE_PACKAGES zlib cg
|
#define USE_PACKAGES zlib cg squish
|
||||||
|
|
||||||
#begin lib_target
|
#begin lib_target
|
||||||
#define TARGET gobj
|
#define TARGET gobj
|
||||||
|
@ -106,6 +106,17 @@ ConfigVariableBool compressed_textures
|
|||||||
"changes the meaning of set_compression(Texture::CM_default) to "
|
"changes the meaning of set_compression(Texture::CM_default) to "
|
||||||
"Texture::CM_on."));
|
"Texture::CM_on."));
|
||||||
|
|
||||||
|
ConfigVariableBool cpu_compress_textures
|
||||||
|
("cpu-compress-textures", false,
|
||||||
|
PRC_DESC("Set this true to use the squish library to compress textures on "
|
||||||
|
"the CPU, as they are loaded, rather than to hand them off to "
|
||||||
|
"the graphics driver to compress them. This will be done "
|
||||||
|
"only if the graphics window is already open and is the default "
|
||||||
|
"graphics context, and it claims to support DXT1/3/5 "
|
||||||
|
"compression. If any of this is not true, the texture will "
|
||||||
|
"not be automatically compressed via squish, but it may still "
|
||||||
|
"be compressed by the graphics driver."));
|
||||||
|
|
||||||
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 "
|
||||||
|
@ -54,6 +54,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 cpu_compress_textures;
|
||||||
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;
|
||||||
|
@ -253,7 +253,11 @@ load(const PNMImage &pnmimage, const LoaderOptions &options) {
|
|||||||
do_clear();
|
do_clear();
|
||||||
++_properties_modified;
|
++_properties_modified;
|
||||||
++_image_modified;
|
++_image_modified;
|
||||||
return do_load_one(pnmimage, get_name(), 0, 0, options);
|
if (do_load_one(pnmimage, get_name(), 0, 0, options)) {
|
||||||
|
consider_auto_compress_ram_image();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -267,7 +271,11 @@ load(const PNMImage &pnmimage, int z, int n, const LoaderOptions &options) {
|
|||||||
MutexHolder holder(_lock);
|
MutexHolder holder(_lock);
|
||||||
++_properties_modified;
|
++_properties_modified;
|
||||||
++_image_modified;
|
++_image_modified;
|
||||||
return 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 false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1205,6 +1213,56 @@ set_keep_ram_image(bool keep_ram_image) {
|
|||||||
_keep_ram_image = keep_ram_image;
|
_keep_ram_image = keep_ram_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Texture::compress_ram_image
|
||||||
|
// Access: Published
|
||||||
|
// Description: Attempts to compress the texture's RAM image
|
||||||
|
// internally, to a format supported by the indicated
|
||||||
|
// GSG. In order for this to work, the squish library
|
||||||
|
// must have been compiled into Panda.
|
||||||
|
//
|
||||||
|
// If compression is CM_on, then an appropriate
|
||||||
|
// compression method that is supported by the indicated
|
||||||
|
// GSG is automatically chosen. If the GSG pointer is
|
||||||
|
// NULL, any of the standard DXT1/3/5 compression
|
||||||
|
// methods will be used, regardless of whether it is
|
||||||
|
// supported.
|
||||||
|
//
|
||||||
|
// If compression is any specific compression method,
|
||||||
|
// that method is used regardless of whether the GSG
|
||||||
|
// supports it.
|
||||||
|
//
|
||||||
|
// quality_level determines the speed/quality tradeoff
|
||||||
|
// of the compression. If it is QL_default, the
|
||||||
|
// texture's own quality_level parameter is used.
|
||||||
|
//
|
||||||
|
// Returns true if successful, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool Texture::
|
||||||
|
compress_ram_image(Texture::CompressionMode compression,
|
||||||
|
Texture::QualityLevel quality_level,
|
||||||
|
GraphicsStateGuardianBase *gsg) {
|
||||||
|
MutexHolder holder(_lock);
|
||||||
|
return do_compress_ram_image(compression, quality_level, gsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Texture::uncompress_ram_image
|
||||||
|
// Access: Published
|
||||||
|
// Description: Attempts to uncompress the texture's RAM image
|
||||||
|
// internally. In order for this to work, the squish
|
||||||
|
// library must have been compiled into Panda, and the
|
||||||
|
// ram image must be compressed in a format supported by
|
||||||
|
// squish.
|
||||||
|
//
|
||||||
|
// Returns true if successful, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool Texture::
|
||||||
|
uncompress_ram_image() {
|
||||||
|
MutexHolder holder(_lock);
|
||||||
|
return do_uncompress_ram_image();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Texture::get_num_ram_mipmap_images
|
// Function: Texture::get_num_ram_mipmap_images
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -39,13 +39,17 @@
|
|||||||
#include "streamReader.h"
|
#include "streamReader.h"
|
||||||
#include "texturePeeker.h"
|
#include "texturePeeker.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_SQUISH
|
||||||
|
#include <squish.h>
|
||||||
|
#endif // HAVE_SQUISH
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
ConfigVariableEnum<Texture::QualityLevel> texture_quality_level
|
ConfigVariableEnum<Texture::QualityLevel> texture_quality_level
|
||||||
("texture-quality-level", Texture::QL_normal,
|
("texture-quality-level", Texture::QL_normal,
|
||||||
PRC_DESC("This specifies a global quality level for all textures. You "
|
PRC_DESC("This specifies a global quality level for all textures. You "
|
||||||
"may specify either fastest, normal, or best. This actually "
|
"may specify either fastest, normal, or best. This actually "
|
||||||
"affects the meaning of Texture::set_quality_level(TQL_default), "
|
"affects the meaning of Texture::set_quality_level(QL_default), "
|
||||||
"so it may be overridden on a per-texture basis. This generally "
|
"so it may be overridden on a per-texture basis. This generally "
|
||||||
"only has an effect when using the tinydisplay software renderer; "
|
"only has an effect when using the tinydisplay software renderer; "
|
||||||
"it has little or no effect on normal, hardware-accelerated "
|
"it has little or no effect on normal, hardware-accelerated "
|
||||||
@ -2082,6 +2086,12 @@ do_read(const Filename &fullpath, const Filename &alpha_fullpath,
|
|||||||
// information, don't let the Texture think that it's got the
|
// information, don't let the Texture think that it's got the
|
||||||
// image now.
|
// image now.
|
||||||
do_clear_ram_image();
|
do_clear_ram_image();
|
||||||
|
} 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -2472,6 +2482,7 @@ do_read_txo(istream &in, const string &filename) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Namable::operator = (*other);
|
||||||
do_assign(*other);
|
do_assign(*other);
|
||||||
_loaded_from_image = true;
|
_loaded_from_image = true;
|
||||||
_loaded_from_txo = true;
|
_loaded_from_txo = true;
|
||||||
@ -2798,7 +2809,7 @@ do_write_one(const Filename &fullpath, int z, int n) const {
|
|||||||
bool Texture::
|
bool Texture::
|
||||||
do_store_one(PNMImage &pnmimage, int z, int n) const {
|
do_store_one(PNMImage &pnmimage, int z, int n) const {
|
||||||
// First, reload the ram image if necessary.
|
// First, reload the ram image if necessary.
|
||||||
((Texture *)this)->do_get_ram_image();
|
((Texture *)this)->do_get_uncompressed_ram_image();
|
||||||
|
|
||||||
nassertr(do_has_ram_mipmap_image(n), false);
|
nassertr(do_has_ram_mipmap_image(n), false);
|
||||||
nassertr(z >= 0 && z < do_get_expected_mipmap_z_size(n), false);
|
nassertr(z >= 0 && z < do_get_expected_mipmap_z_size(n), false);
|
||||||
@ -3009,6 +3020,17 @@ do_reload_ram_image(bool allow_compression) {
|
|||||||
_ram_image_compression = tex->_ram_image_compression;
|
_ram_image_compression = tex->_ram_image_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()) {
|
||||||
|
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(this, false);
|
||||||
|
cache->store(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3122,6 +3144,180 @@ do_make_ram_mipmap_image(int n) {
|
|||||||
return _ram_images[n]._image;
|
return _ram_images[n]._image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Texture::consider_auto_compress_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.
|
||||||
|
|
||||||
|
// Returns true if the image was modified by this
|
||||||
|
// operation, false if it wasn't.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool Texture::
|
||||||
|
consider_auto_compress_ram_image() {
|
||||||
|
if (cpu_compress_textures) {
|
||||||
|
CompressionMode compression = _compression;
|
||||||
|
if (compression == CM_default) {
|
||||||
|
if (!compressed_textures) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
compression = CM_on;
|
||||||
|
}
|
||||||
|
if (compression != CM_off && _ram_image_compression == CM_off) {
|
||||||
|
GraphicsStateGuardianBase *gsg = GraphicsStateGuardianBase::get_default_gsg();
|
||||||
|
if (gsg != (GraphicsStateGuardianBase *)NULL) {
|
||||||
|
if (do_compress_ram_image(compression, QL_default, gsg)) {
|
||||||
|
gobj_cat.info()
|
||||||
|
<< "Compressed " << get_name() << " with "
|
||||||
|
<< _ram_image_compression << "\n";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Texture::do_compress_ram_image
|
||||||
|
// Access: Protected
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool Texture::
|
||||||
|
do_compress_ram_image(Texture::CompressionMode compression,
|
||||||
|
Texture::QualityLevel quality_level,
|
||||||
|
GraphicsStateGuardianBase *gsg) {
|
||||||
|
nassertr(compression != CM_off, false);
|
||||||
|
|
||||||
|
if (compression == CM_on) {
|
||||||
|
// Select an appropriate compression mode automatically.
|
||||||
|
switch (_format) {
|
||||||
|
case Texture::F_rgbm:
|
||||||
|
case Texture::F_rgb:
|
||||||
|
case Texture::F_rgb5:
|
||||||
|
case Texture::F_rgba5:
|
||||||
|
case Texture::F_rgb8:
|
||||||
|
case Texture::F_rgb12:
|
||||||
|
case Texture::F_rgb332:
|
||||||
|
if (gsg == NULL || gsg->get_supports_compressed_texture_format(CM_dxt1)) {
|
||||||
|
compression = CM_dxt1;
|
||||||
|
} else if (gsg == NULL || gsg->get_supports_compressed_texture_format(CM_dxt3)) {
|
||||||
|
compression = CM_dxt3;
|
||||||
|
} else if (gsg == NULL || gsg->get_supports_compressed_texture_format(CM_dxt5)) {
|
||||||
|
compression = CM_dxt5;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Texture::F_rgba4:
|
||||||
|
if (gsg == NULL || gsg->get_supports_compressed_texture_format(CM_dxt3)) {
|
||||||
|
compression = CM_dxt3;
|
||||||
|
} else if (gsg == NULL || gsg->get_supports_compressed_texture_format(CM_dxt5)) {
|
||||||
|
compression = CM_dxt5;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Texture::F_rgba:
|
||||||
|
case Texture::F_rgba8:
|
||||||
|
case Texture::F_rgba12:
|
||||||
|
if (gsg == NULL || gsg->get_supports_compressed_texture_format(CM_dxt5)) {
|
||||||
|
compression = CM_dxt5;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Choose an appropriate quality level.
|
||||||
|
if (quality_level == Texture::QL_default) {
|
||||||
|
quality_level = _quality_level;
|
||||||
|
}
|
||||||
|
if (quality_level == Texture::QL_default) {
|
||||||
|
quality_level = texture_quality_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_SQUISH
|
||||||
|
if (_texture_type != TT_3d_texture && _component_type == T_unsigned_byte) {
|
||||||
|
int squish_flags = 0;
|
||||||
|
switch (compression) {
|
||||||
|
case CM_dxt1:
|
||||||
|
squish_flags |= squish::kDxt1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CM_dxt3:
|
||||||
|
squish_flags |= squish::kDxt3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CM_dxt5:
|
||||||
|
squish_flags |= squish::kDxt5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (squish_flags != 0) {
|
||||||
|
// This compression mode is supported by squish; use it.
|
||||||
|
switch (quality_level) {
|
||||||
|
case QL_fastest:
|
||||||
|
squish_flags |= squish::kColourRangeFit;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QL_normal:
|
||||||
|
// ColourClusterFit is just too slow for everyday use.
|
||||||
|
squish_flags |= squish::kColourRangeFit;
|
||||||
|
// squish_flags |= squish::kColourClusterFit;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QL_best:
|
||||||
|
squish_flags |= squish::kColourIterativeClusterFit;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (do_squish(compression, squish_flags)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // HAVE_SQUISH
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Texture::do_uncompress_ram_image
|
||||||
|
// Access: Protected
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool Texture::
|
||||||
|
do_uncompress_ram_image() {
|
||||||
|
|
||||||
|
#ifdef HAVE_SQUISH
|
||||||
|
if (_texture_type != TT_3d_texture && _component_type == T_unsigned_byte) {
|
||||||
|
int squish_flags = 0;
|
||||||
|
switch (_ram_image_compression) {
|
||||||
|
case CM_dxt1:
|
||||||
|
squish_flags |= squish::kDxt1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CM_dxt3:
|
||||||
|
squish_flags |= squish::kDxt3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CM_dxt5:
|
||||||
|
squish_flags |= squish::kDxt5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (squish_flags != 0) {
|
||||||
|
// This compression mode is supported by squish; use it.
|
||||||
|
if (do_unsquish(squish_flags)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // HAVE_SQUISH
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Texture::do_reconsider_z_size
|
// Function: Texture::do_reconsider_z_size
|
||||||
// Access: Protected
|
// Access: Protected
|
||||||
@ -3660,6 +3856,17 @@ do_get_ram_image() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
CPTA_uchar Texture::
|
CPTA_uchar Texture::
|
||||||
do_get_uncompressed_ram_image() {
|
do_get_uncompressed_ram_image() {
|
||||||
|
if (!_ram_images.empty() && _ram_image_compression != CM_off) {
|
||||||
|
// 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";
|
||||||
|
return _ram_images[0]._image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Couldn't uncompress the existing image. Try to reload it.
|
||||||
if (_loaded_from_image && (!do_has_ram_image() || _ram_image_compression != CM_off) && !_fullpath.empty()) {
|
if (_loaded_from_image && (!do_has_ram_image() || _ram_image_compression != CM_off) && !_fullpath.empty()) {
|
||||||
do_unlock_and_reload_ram_image(false);
|
do_unlock_and_reload_ram_image(false);
|
||||||
}
|
}
|
||||||
@ -5094,6 +5301,183 @@ filter_3d_unsigned_short(unsigned char *&p, const unsigned char *&q,
|
|||||||
q += 2;
|
q += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Texture::do_squish
|
||||||
|
// Access: Private
|
||||||
|
// Description: Invokes the squish library to compress the RAM
|
||||||
|
// image(s).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool Texture::
|
||||||
|
do_squish(Texture::CompressionMode compression, int squish_flags) {
|
||||||
|
#ifdef HAVE_SQUISH
|
||||||
|
if (_ram_images.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
RamImages compressed_ram_images;
|
||||||
|
compressed_ram_images.reserve(_ram_images.size());
|
||||||
|
for (size_t n = 0; n < _ram_images.size(); ++n) {
|
||||||
|
RamImage compressed_image;
|
||||||
|
int x_size = do_get_expected_mipmap_x_size(n);
|
||||||
|
int y_size = do_get_expected_mipmap_y_size(n);
|
||||||
|
int z_size = do_get_expected_mipmap_z_size(n);
|
||||||
|
int page_size = squish::GetStorageRequirements(x_size, y_size, squish_flags);
|
||||||
|
int cell_size = squish::GetStorageRequirements(4, 4, squish_flags);
|
||||||
|
|
||||||
|
compressed_image._page_size = page_size;
|
||||||
|
compressed_image._image = PTA_uchar::empty_array(page_size * z_size);
|
||||||
|
for (int z = 0; z < z_size; ++z) {
|
||||||
|
unsigned char *dest_page = compressed_image._image.p() + z * page_size;
|
||||||
|
unsigned const char *source_page = _ram_images[n]._image.p() + z * _ram_images[n]._page_size;
|
||||||
|
unsigned const char *source_page_end = source_page + _ram_images[n]._page_size;
|
||||||
|
// Convert one 4 x 4 cell at a time.
|
||||||
|
unsigned char *d = dest_page;
|
||||||
|
for (int y = 0; y < y_size; y += 4) {
|
||||||
|
for (int x = 0; x < x_size; x += 4) {
|
||||||
|
unsigned char tb[16 * 4];
|
||||||
|
int mask = 0;
|
||||||
|
unsigned char *t = tb;
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
int xi = x + i % 4;
|
||||||
|
int yi = y + i / 4;
|
||||||
|
unsigned const char *s = source_page + (yi * x_size + xi) * _num_components;
|
||||||
|
if (s < source_page_end) {
|
||||||
|
switch (_num_components) {
|
||||||
|
case 1:
|
||||||
|
t[0] = s[0]; // r
|
||||||
|
t[1] = s[0]; // g
|
||||||
|
t[2] = s[0]; // b
|
||||||
|
t[3] = 255; // a
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
t[0] = s[0]; // r
|
||||||
|
t[1] = s[0]; // g
|
||||||
|
t[2] = s[0]; // b
|
||||||
|
t[3] = s[1]; // a
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
t[0] = s[2]; // r
|
||||||
|
t[1] = s[1]; // g
|
||||||
|
t[2] = s[0]; // b
|
||||||
|
t[3] = 255; // a
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
t[0] = s[2]; // r
|
||||||
|
t[1] = s[1]; // g
|
||||||
|
t[2] = s[0]; // b
|
||||||
|
t[3] = s[3]; // a
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mask |= (1 << i);
|
||||||
|
}
|
||||||
|
t += 4;
|
||||||
|
}
|
||||||
|
squish::CompressMasked(tb, mask, d, squish_flags);
|
||||||
|
d += cell_size;
|
||||||
|
Thread::consider_yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compressed_ram_images.push_back(compressed_image);
|
||||||
|
}
|
||||||
|
_ram_images.swap(compressed_ram_images);
|
||||||
|
_ram_image_compression = compression;
|
||||||
|
++_image_modified;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#else // HAVE_SQUISH
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#endif // HAVE_SQUISH
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Texture::do_unsquish
|
||||||
|
// Access: Private
|
||||||
|
// Description: Invokes the squish library to uncompress the RAM
|
||||||
|
// image(s).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool Texture::
|
||||||
|
do_unsquish(int squish_flags) {
|
||||||
|
#ifdef HAVE_SQUISH
|
||||||
|
if (_ram_images.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
RamImages uncompressed_ram_images;
|
||||||
|
uncompressed_ram_images.reserve(_ram_images.size());
|
||||||
|
for (size_t n = 0; n < _ram_images.size(); ++n) {
|
||||||
|
RamImage uncompressed_image;
|
||||||
|
int x_size = do_get_expected_mipmap_x_size(n);
|
||||||
|
int y_size = do_get_expected_mipmap_y_size(n);
|
||||||
|
int z_size = do_get_expected_mipmap_z_size(n);
|
||||||
|
int page_size = squish::GetStorageRequirements(x_size, y_size, squish_flags);
|
||||||
|
int cell_size = squish::GetStorageRequirements(4, 4, squish_flags);
|
||||||
|
|
||||||
|
uncompressed_image._page_size = do_get_expected_ram_mipmap_page_size(n);
|
||||||
|
uncompressed_image._image = PTA_uchar::empty_array(uncompressed_image._page_size * z_size);
|
||||||
|
for (int z = 0; z < z_size; ++z) {
|
||||||
|
unsigned char *dest_page = uncompressed_image._image.p() + z * uncompressed_image._page_size;
|
||||||
|
unsigned char *dest_page_end = dest_page + uncompressed_image._page_size;
|
||||||
|
unsigned const char *source_page = _ram_images[n]._image.p() + z * page_size;
|
||||||
|
// Unconvert one 4 x 4 cell at a time.
|
||||||
|
unsigned const char *s = source_page;
|
||||||
|
for (int y = 0; y < y_size; y += 4) {
|
||||||
|
for (int x = 0; x < x_size; x += 4) {
|
||||||
|
unsigned char tb[16 * 4];
|
||||||
|
squish::Decompress(tb, s, squish_flags);
|
||||||
|
s += cell_size;
|
||||||
|
|
||||||
|
unsigned char *t = tb;
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
int xi = x + i % 4;
|
||||||
|
int yi = y + i / 4;
|
||||||
|
unsigned char *d = dest_page + (yi * x_size + xi) * _num_components;
|
||||||
|
if (d < dest_page_end) {
|
||||||
|
switch (_num_components) {
|
||||||
|
case 1:
|
||||||
|
d[0] = t[1]; // g
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
d[0] = t[1]; // g
|
||||||
|
d[1] = t[3]; // a
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
d[2] = t[0]; // r
|
||||||
|
d[1] = t[1]; // g
|
||||||
|
d[0] = t[2]; // b
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
d[2] = t[0]; // r
|
||||||
|
d[1] = t[1]; // g
|
||||||
|
d[0] = t[2]; // b
|
||||||
|
d[3] = t[3]; // a
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Thread::consider_yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uncompressed_ram_images.push_back(uncompressed_image);
|
||||||
|
}
|
||||||
|
_ram_images.swap(uncompressed_ram_images);
|
||||||
|
_ram_image_compression = CM_off;
|
||||||
|
++_image_modified;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#else // HAVE_SQUISH
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#endif // HAVE_SQUISH
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Texture::register_with_read_factory
|
// Function: Texture::register_with_read_factory
|
||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
|
@ -313,6 +313,11 @@ PUBLISHED:
|
|||||||
INLINE void set_keep_ram_image(bool keep_ram_image);
|
INLINE void set_keep_ram_image(bool keep_ram_image);
|
||||||
virtual bool get_keep_ram_image() const;
|
virtual bool get_keep_ram_image() const;
|
||||||
|
|
||||||
|
INLINE bool compress_ram_image(CompressionMode compression = CM_on,
|
||||||
|
QualityLevel quality_level = QL_default,
|
||||||
|
GraphicsStateGuardianBase *gsg = NULL);
|
||||||
|
INLINE bool uncompress_ram_image();
|
||||||
|
|
||||||
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;
|
||||||
@ -475,6 +480,12 @@ 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 do_compress_ram_image(CompressionMode compression,
|
||||||
|
QualityLevel quality_level,
|
||||||
|
GraphicsStateGuardianBase *gsg);
|
||||||
|
bool do_uncompress_ram_image();
|
||||||
|
|
||||||
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,
|
||||||
ComponentType component_type, int z,
|
ComponentType component_type, int z,
|
||||||
@ -607,6 +618,9 @@ private:
|
|||||||
const unsigned char *&q,
|
const unsigned char *&q,
|
||||||
size_t pixel_size, size_t row_size,
|
size_t pixel_size, size_t row_size,
|
||||||
size_t page_size);
|
size_t page_size);
|
||||||
|
|
||||||
|
bool do_squish(CompressionMode compression, int squish_flags);
|
||||||
|
bool do_unsquish(int squish_flags);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Protects all of the members of this class.
|
// Protects all of the members of this class.
|
||||||
|
@ -920,6 +920,16 @@ try_load_cache(PT(Texture) &tex, BamCache *cache, const Filename &filename,
|
|||||||
if (!(options.get_texture_flags() & LoaderOptions::TF_preload)) {
|
if (!(options.get_texture_flags() & LoaderOptions::TF_preload)) {
|
||||||
// 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()) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tex->set_keep_ram_image(false);
|
tex->set_keep_ram_image(false);
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,7 @@ PUBLISHED:
|
|||||||
virtual int get_max_vertices_per_primitive() const=0;
|
virtual int get_max_vertices_per_primitive() const=0;
|
||||||
|
|
||||||
virtual int get_max_texture_dimension() const=0;
|
virtual int get_max_texture_dimension() const=0;
|
||||||
|
virtual bool get_supports_compressed_texture_format(int compression_mode) const=0;
|
||||||
|
|
||||||
virtual bool get_supports_multisample() const=0;
|
virtual bool get_supports_multisample() const=0;
|
||||||
virtual int get_supported_geom_rendering() const=0;
|
virtual int get_supported_geom_rendering() const=0;
|
||||||
|
@ -101,8 +101,9 @@ get_cache_textures() const {
|
|||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Indicates whether compressed texture files will be
|
// Description: Indicates whether compressed texture files will be
|
||||||
// stored in the cache, as compressed txo files. The
|
// stored in the cache, as compressed txo files. The
|
||||||
// compression data is extracted from the GSG after the
|
// compressed data may either be generated in-CPU, via
|
||||||
// texture has been loaded.
|
// the squish library, or it may be extracted from the
|
||||||
|
// GSG after the texture has been loaded.
|
||||||
//
|
//
|
||||||
// This may be set in conjunction with
|
// This may be set in conjunction with
|
||||||
// set_cache_textures(), or independently of it. If
|
// set_cache_textures(), or independently of it. If
|
||||||
|
@ -1597,17 +1597,22 @@ prepare_texture(Texture *tex) {
|
|||||||
default:
|
default:
|
||||||
// Anything else is not supported.
|
// Anything else is not supported.
|
||||||
tinydisplay_cat.info()
|
tinydisplay_cat.info()
|
||||||
<< "not loading texture " << tex->get_name() << ": "
|
<< "Not loading texture " << tex->get_name() << ": "
|
||||||
<< tex->get_texture_type() << "\n";
|
<< tex->get_texture_type() << "\n";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Even though the texture might be compressed now, it might have an
|
||||||
|
// available uncompressed version that we can load. So don't reject
|
||||||
|
// it out-of-hand just because it's compressed.
|
||||||
|
/*
|
||||||
if (tex->get_ram_image_compression() != Texture::CM_off) {
|
if (tex->get_ram_image_compression() != Texture::CM_off) {
|
||||||
tinydisplay_cat.info()
|
tinydisplay_cat.info()
|
||||||
<< "not loading texture " << tex->get_name() << ": "
|
<< "Not loading texture " << tex->get_name() << ": "
|
||||||
<< tex->get_ram_image_compression() << "\n";
|
<< tex->get_ram_image_compression() << "\n";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
TinyTextureContext *gtc = new TinyTextureContext(_prepared_objects, tex);
|
TinyTextureContext *gtc = new TinyTextureContext(_prepared_objects, tex);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user