add support for txaFileFilter

This commit is contained in:
David Rose 2006-07-28 20:37:14 +00:00
parent df10d43e2f
commit 7834728560
17 changed files with 771 additions and 55 deletions

View File

@ -855,7 +855,7 @@ load_textures() {
// Description:
////////////////////////////////////////////////////////////////////
bool EggLoader::
load_texture(TextureDef &def, const EggTexture *egg_tex) {
load_texture(TextureDef &def, EggTexture *egg_tex) {
// Check to see if we should reduce the number of channels in
// the texture.
int wanted_channels = 0;
@ -951,6 +951,30 @@ load_texture(TextureDef &def, const EggTexture *egg_tex) {
tex->set_alpha_filename(egg_tex->get_alpha_filename());
}
// See if there is some egg data hanging on the texture. In
// particular, the TxaFileFilter might have left that here for us.
TypedReferenceCount *aux = tex->get_aux_data("egg");
if (aux != (TypedReferenceCount *)NULL &&
aux->is_of_type(EggTexture::get_class_type())) {
EggTexture *aux_egg_tex = DCAST(EggTexture, aux);
if (aux_egg_tex->get_alpha_mode() != EggTexture::AM_unspecified) {
egg_tex->set_alpha_mode(aux_egg_tex->get_alpha_mode());
}
if (aux_egg_tex->get_format() != EggTexture::F_unspecified) {
egg_tex->set_format(aux_egg_tex->get_format());
}
if (aux_egg_tex->get_minfilter() != EggTexture::FT_unspecified) {
egg_tex->set_minfilter(aux_egg_tex->get_minfilter());
}
if (aux_egg_tex->get_magfilter() != EggTexture::FT_unspecified) {
egg_tex->set_magfilter(aux_egg_tex->get_magfilter());
}
if (aux_egg_tex->has_anisotropic_degree()) {
egg_tex->set_anisotropic_degree(aux_egg_tex->get_anisotropic_degree());
}
}
apply_texture_attributes(tex, egg_tex);
// Make a texture stage for the texture.

View File

@ -122,7 +122,7 @@ private:
const LMatrix4d &mat);
void load_textures();
bool load_texture(TextureDef &def, const EggTexture *egg_tex);
bool load_texture(TextureDef &def, EggTexture *egg_tex);
void apply_texture_attributes(Texture *tex, const EggTexture *egg_tex);
Texture::CompressionMode convert_compression_mode(EggTexture::CompressionMode compression_mode) const;
Texture::WrapMode convert_wrap_mode(EggTexture::WrapMode wrap_mode) const;

View File

@ -60,6 +60,7 @@ fill_state(EggPrimitive *egg_prim) {
EggRenderMode::DepthTestMode dtm = EggRenderMode::DTM_unspecified;
EggRenderMode::VisibilityMode vm = EggRenderMode::VM_unspecified;
bool implicit_alpha = false;
bool binary_alpha_only = true; // true if all alpha sources are binary alpha.
bool has_draw_order = false;
int draw_order = 0;
bool has_bin = false;
@ -111,18 +112,26 @@ fill_state(EggPrimitive *egg_prim) {
texture_attrib = texture_attrib->compose(def._texture);
}
// If neither the primitive nor the texture specified an alpha
// mode, assume it should be alpha'ed if the texture has an
// alpha channel (unless the texture environment type is one
// that doesn't apply its alpha to the result).
if (egg_tex->affects_polygon_alpha() &&
am == EggRenderMode::AM_unspecified) {
if (egg_tex->affects_polygon_alpha()) {
const TextureAttrib *tex_attrib = DCAST(TextureAttrib, def._texture);
Texture *tex = tex_attrib->get_texture();
nassertv(tex != (Texture *)NULL);
int num_components = tex->get_num_components();
if (egg_tex->has_alpha_channel(num_components)) {
implicit_alpha = true;
Texture::Format format = tex->get_format();
if (Texture::has_alpha(format) && !Texture::has_binary_alpha(format)) {
// This texture specifies a gradient alpha format.
binary_alpha_only = false;
}
if (am == EggRenderMode::AM_unspecified) {
// If neither the primitive nor the texture specified an
// alpha mode, assume it should be alpha'ed if the texture
// has an alpha channel (unless the texture environment type
// is one that doesn't apply its alpha to the result).
int num_components = tex->get_num_components();
if (egg_tex->has_alpha_channel(num_components)) {
implicit_alpha = true;
}
}
}
@ -247,6 +256,7 @@ fill_state(EggPrimitive *egg_prim) {
if (egg_prim->has_color()) {
if (egg_prim->get_color()[3] != 1.0) {
implicit_alpha = true;
binary_alpha_only = false;
}
}
EggPrimitive::const_iterator vi;
@ -256,6 +266,7 @@ fill_state(EggPrimitive *egg_prim) {
if ((*vi)->has_color()) {
if ((*vi)->get_color()[3] != 1.0) {
implicit_alpha = true;
binary_alpha_only = false;
}
}
}
@ -265,10 +276,30 @@ fill_state(EggPrimitive *egg_prim) {
}
}
if (am == EggRenderMode::AM_on &&
egg_alpha_mode != EggRenderMode::AM_unspecified) {
switch (am) {
case EggRenderMode::AM_on:
// Alpha type "on" means to get the default transparency type.
am = egg_alpha_mode;
if (binary_alpha_only) {
am = EggRenderMode::AM_binary;
} else if (egg_alpha_mode != EggRenderMode::AM_unspecified) {
am = egg_alpha_mode;
}
break;
case EggRenderMode::AM_blend:
case EggRenderMode::AM_ms:
case EggRenderMode::AM_ms_mask:
case EggRenderMode::AM_dual:
// Any of these modes gets implicitly downgraded to AM_binary, if
// all of the alpha sources only contribute a binary value to
// alpha.
if (binary_alpha_only) {
am = EggRenderMode::AM_binary;
}
break;
default:
break;
}
switch (am) {

View File

@ -54,6 +54,7 @@
texture.I texture.h \
textureContext.I textureContext.h \
texturePool.I texturePool.h \
texturePoolFilter.I texturePoolFilter.h \
textureStage.I textureStage.h \
transformBlend.I transformBlend.h \
transformBlendTable.I transformBlendTable.h \
@ -107,6 +108,7 @@
shaderExpansion.cxx \
sliderTable.cxx \
texture.cxx textureContext.cxx texturePool.cxx \
texturePoolFilter.cxx \
textureStage.cxx \
transformBlend.cxx \
transformBlendTable.cxx \
@ -164,6 +166,7 @@
texture.I texture.h \
textureContext.I textureContext.h \
texturePool.I texturePool.h \
texturePoolFilter.I texturePoolFilter.h \
textureStage.I textureStage.h \
transformBlend.I transformBlend.h \
transformBlendTable.I transformBlendTable.h \

View File

@ -41,6 +41,7 @@
#include "queryContext.h"
#include "sliderTable.h"
#include "texture.h"
#include "texturePoolFilter.h"
#include "textureStage.h"
#include "textureContext.h"
#include "shaderExpansion.h"
@ -248,60 +249,62 @@ ConfigVariableDouble default_keystone
ConfigureFn(config_gobj) {
BufferContext::init_type();
Geom::init_type();
GeomMunger::init_type();
GeomPrimitive::init_type();
GeomTriangles::init_type();
GeomTristrips::init_type();
GeomTrifans::init_type();
GeomContext::init_type();
GeomLines::init_type();
GeomLinestrips::init_type();
GeomMunger::init_type();
GeomPoints::init_type();
GeomPrimitive::init_type();
GeomTriangles::init_type();
GeomTrifans::init_type();
GeomTristrips::init_type();
GeomVertexArrayData::init_type();
GeomVertexArrayFormat::init_type();
GeomVertexData::init_type();
GeomVertexFormat::init_type();
TextureContext::init_type();
GeomContext::init_type();
VertexBufferContext::init_type();
IndexBufferContext::init_type();
InternalName::init_type();
Lens::init_type();
Material::init_type();
MatrixLens::init_type();
OcclusionQueryContext::init_type();
OrthographicLens::init_type();
MatrixLens::init_type();
PerspectiveLens::init_type();
Lens::init_type();
QueryContext::init_type();
ShaderContext::init_type();
ShaderExpansion::init_type();
SliderTable::init_type();
Texture::init_type();
TextureContext::init_type();
TexturePoolFilter::init_type();
TextureStage::init_type();
ShaderExpansion::init_type();
ShaderContext::init_type();
TransformBlend::init_type();
TransformBlendTable::init_type();
TransformTable::init_type();
UserVertexSlider::init_type();
UserVertexTransform::init_type();
VertexTransform::init_type();
VertexBufferContext::init_type();
VertexSlider::init_type();
VertexTransform::init_type();
VideoTexture::init_type();
InternalName::init_type();
//Registration of writeable object's creation
//functions with BamReader's factory
Geom::register_with_read_factory();
GeomTriangles::register_with_read_factory();
GeomTristrips::register_with_read_factory();
GeomTrifans::register_with_read_factory();
GeomLines::register_with_read_factory();
GeomLinestrips::register_with_read_factory();
GeomPoints::register_with_read_factory();
GeomTriangles::register_with_read_factory();
GeomTrifans::register_with_read_factory();
GeomTristrips::register_with_read_factory();
GeomVertexArrayData::register_with_read_factory();
GeomVertexArrayFormat::register_with_read_factory();
GeomVertexData::register_with_read_factory();
GeomVertexFormat::register_with_read_factory();
InternalName::register_with_read_factory();
Material::register_with_read_factory();
OrthographicLens::register_with_read_factory();
MatrixLens::register_with_read_factory();
OrthographicLens::register_with_read_factory();
PerspectiveLens::register_with_read_factory();
SliderTable::register_with_read_factory();
Texture::register_with_read_factory();
@ -310,7 +313,6 @@ ConfigureFn(config_gobj) {
TransformTable::register_with_read_factory();
UserVertexSlider::register_with_read_factory();
UserVertexTransform::register_with_read_factory();
InternalName::register_with_read_factory();
}
ostream &

View File

@ -15,6 +15,7 @@
#include "texture.cxx"
#include "textureContext.cxx"
#include "texturePool.cxx"
#include "texturePoolFilter.cxx"
#include "textureStage.cxx"
#include "shaderExpansion.cxx"
#include "shaderContext.cxx"

View File

@ -415,6 +415,50 @@ estimate_texture_memory() const {
return bytes;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::set_aux_data
// Access: Published
// Description: Records an arbitrary object in the Texture,
// associated with a specified key. The object may
// later be retrieved by calling get_aux_data() with the
// same key.
//
// These data objects are not recorded to a bam or txo
// file.
////////////////////////////////////////////////////////////////////
void Texture::
set_aux_data(const string &key, TypedReferenceCount *aux_data) {
_aux_data[key] = aux_data;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::clear_aux_data
// Access: Published
// Description: Removes a record previously recorded via
// set_aux_data().
////////////////////////////////////////////////////////////////////
void Texture::
clear_aux_data(const string &key) {
_aux_data.erase(key);
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_aux_data
// Access: Published
// Description: Returns a record previously recorded via
// set_aux_data(). Returns NULL if there was no record
// associated with the indicated key.
////////////////////////////////////////////////////////////////////
TypedReferenceCount *Texture::
get_aux_data(const string &key) const {
AuxData::const_iterator di;
di = _aux_data.find(key);
if (di != _aux_data.end()) {
return (*di).second;
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::read_txo
// Access: Published
@ -2357,6 +2401,23 @@ has_alpha(Format format) {
}
}
////////////////////////////////////////////////////////////////////
// Function: Texture::has_binary_alpha
// Access: Public, Static
// Description: Returns true if the indicated format includes a
// binary alpha only, false otherwise.
////////////////////////////////////////////////////////////////////
bool Texture::
has_binary_alpha(Format format) {
switch (format) {
case F_rgbm:
return true;
default:
return false;
}
}
////////////////////////////////////////////////////////////////////
// Function: Texture::reconsider_z_size
// Access: Protected

View File

@ -311,6 +311,10 @@ PUBLISHED:
size_t estimate_texture_memory() const;
void set_aux_data(const string &key, TypedReferenceCount *aux_data);
void clear_aux_data(const string &key);
TypedReferenceCount *get_aux_data(const string &key) const;
PUBLISHED:
// These are published, but in general, you shouldn't be mucking
// with these values; they are set automatically when a texture is
@ -360,6 +364,7 @@ public:
static bool is_specific(CompressionMode compression);
static bool has_alpha(Format format);
static bool has_binary_alpha(Format format);
protected:
virtual bool do_read(const Filename &fullpath, const Filename &alpha_fullpath,
@ -516,6 +521,11 @@ protected:
UpdateSeq _modified;
private:
// The auxiliary data is not recorded to a bam file.
typedef pmap<string, PT(TypedReferenceCount) > AuxData;
AuxData _aux_data;
// Datagram stuff
public:
static void register_with_read_factory();

View File

@ -25,10 +25,11 @@
#include "bamCache.h"
#include "bamCacheRecord.h"
#include "pnmFileTypeRegistry.h"
#include "texturePoolFilter.h"
#include "configVariableList.h"
#include "load_dso.h"
TexturePool *TexturePool::_global_ptr = (TexturePool *)NULL;
TexturePool *TexturePool::_global_ptr;
////////////////////////////////////////////////////////////////////
// Function: TexturePool::write
@ -62,6 +63,19 @@ register_texture_type(MakeTextureFunc *func, const string &extensions) {
}
}
////////////////////////////////////////////////////////////////////
// Function: TexturePool::register_filter
// Access: Public
// Description: Records a TexturePoolFilter object that may operate
// on texture images as they are loaded from disk.
////////////////////////////////////////////////////////////////////
void TexturePool::
register_filter(TexturePoolFilter *filter) {
gobj_cat.info()
<< "Registering Texture filter " << *filter << "\n";
_filter_registry.push_back(filter);
}
////////////////////////////////////////////////////////////////////
// Function: TexturePool::get_texture_type
// Access: Public
@ -152,6 +166,11 @@ TexturePool *TexturePool::
get_global_ptr() {
if (_global_ptr == (TexturePool *)NULL) {
_global_ptr = new TexturePool;
// We have to call this here, not in the constructor, so that the
// _global_ptr is safely assigned by the time the filters begin to
// load.
_global_ptr->load_filters();
}
return _global_ptr;
}
@ -229,20 +248,27 @@ ns_load_texture(const Filename &orig_filename, int primary_file_num_channels,
return tex;
}
// The texture was not found in the pool.
PT(Texture) tex;
PT(BamCacheRecord) record;
bool store_record = false;
// Can one of our texture filters supply the texture?
tex = pre_load(orig_filename, Filename(), primary_file_num_channels, 0,
read_mipmaps);
BamCache *cache = BamCache::get_global_ptr();
if (cache->get_active() && !textures_header_only) {
// See if the texture can be found in the on-disk cache, if it is
// active.
record = cache->lookup(filename, "txo");
if (record != (BamCacheRecord *)NULL) {
if (record->has_data()) {
gobj_cat.info()
<< "Texture " << filename << " found in disk cache.\n";
tex = DCAST(Texture, record->extract_data());
if (tex == (Texture *)NULL) {
// The texture was not supplied by a texture filter. See if it
// can be found in the on-disk cache, if it is active.
if (cache->get_active() && !textures_header_only) {
record = cache->lookup(filename, "txo");
if (record != (BamCacheRecord *)NULL) {
if (record->has_data()) {
gobj_cat.info()
<< "Texture " << filename << " found in disk cache.\n";
tex = DCAST(Texture, record->extract_data());
}
}
}
}
@ -276,6 +302,10 @@ ns_load_texture(const Filename &orig_filename, int primary_file_num_channels,
}
nassertr(!tex->get_fullpath().empty(), tex);
// Finally, apply any post-loading texture filters.
tex = post_load(tex);
return tex;
}
@ -318,16 +348,24 @@ ns_load_texture(const Filename &orig_filename,
PT(BamCacheRecord) record;
bool store_record = false;
// Can one of our texture filters supply the texture?
tex = pre_load(orig_filename, alpha_filename, primary_file_num_channels,
alpha_file_channel, read_mipmaps);
BamCache *cache = BamCache::get_global_ptr();
if (cache->get_active() && !textures_header_only) {
// See if the texture can be found in the on-disk cache, if it is
// active.
record = cache->lookup(filename, "txo");
if (record != (BamCacheRecord *)NULL) {
if (record->has_data()) {
gobj_cat.info()
<< "Texture " << filename << " found in disk cache.\n";
tex = DCAST(Texture, record->extract_data());
if (tex == (Texture *)NULL) {
// The texture was not supplied by a texture filter. See if it
// can be found in the on-disk cache, if it is active.
if (cache->get_active() && !textures_header_only) {
// See if the texture can be found in the on-disk cache, if it is
// active.
record = cache->lookup(filename, "txo");
if (record != (BamCacheRecord *)NULL) {
if (record->has_data()) {
gobj_cat.info()
<< "Texture " << filename << " found in disk cache.\n";
tex = DCAST(Texture, record->extract_data());
}
}
}
}
@ -364,6 +402,10 @@ ns_load_texture(const Filename &orig_filename,
}
nassertr(!tex->get_fullpath().empty(), tex);
// Finally, apply any post-loading texture filters.
tex = post_load(tex);
return tex;
}
@ -684,3 +726,82 @@ report_texture_unreadable(const Filename &filename) const {
}
}
}
////////////////////////////////////////////////////////////////////
// Function: TexturePool::pre_load
// Access: Private
// Description: Invokes pre_load() on all registered filters until
// one returns non-NULL; returns NULL if there are no
// registered filters or if all registered filters
// returned NULL.
////////////////////////////////////////////////////////////////////
PT(Texture) TexturePool::
pre_load(const Filename &orig_filename, const Filename &orig_alpha_filename,
int primary_file_num_channels, int alpha_file_channel,
bool read_mipmaps) {
PT(Texture) tex;
FilterRegistry::iterator fi;
for (fi = _filter_registry.begin();
fi != _filter_registry.end();
++fi) {
tex = (*fi)->pre_load(orig_filename, orig_alpha_filename,
primary_file_num_channels, alpha_file_channel,
read_mipmaps);
if (tex != (Texture *)NULL) {
return tex;
}
}
return tex;
}
////////////////////////////////////////////////////////////////////
// Function: TexturePool::post_load
// Access: Public, Virtual
// Description: Invokes post_load() on all registered filters.
////////////////////////////////////////////////////////////////////
PT(Texture) TexturePool::
post_load(Texture *tex) {
PT(Texture) result = tex;
FilterRegistry::iterator fi;
for (fi = _filter_registry.begin();
fi != _filter_registry.end();
++fi) {
result = (*fi)->post_load(result);
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: TexturePool::load_filters
// Access: Private
// Description: Loads up all of the dll's named by the texture-filter
// Config.prc variable.
////////////////////////////////////////////////////////////////////
void TexturePool::
load_filters() {
ConfigVariableList texture_filter
("texture-filter",
PRC_DESC("Names one or more external libraries that should be loaded for the "
"purposes of performing texture filtering. This variable may be repeated several "
"times. As in load-display, the actual library filename is derived by "
"prefixing 'lib' to the specified name."));
int num_aux = texture_filter.get_num_unique_values();
for (int i = 0; i < num_aux; i++) {
string name = texture_filter.get_unique_value(i);
Filename dlname = Filename::dso_filename("lib" + name + ".so");
gobj_cat.info()
<< "loading texture filter: " << dlname.to_os_specific() << endl;
void *tmp = load_dso(dlname);
if (tmp == (void *)NULL) {
gobj_cat.info()
<< "Unable to load: " << load_dso_error() << endl;
}
}
}

View File

@ -26,6 +26,8 @@
#include "pmap.h"
class TexturePoolFilter;
////////////////////////////////////////////////////////////////////
// Class : TexturePool
// Description : This is the preferred interface for loading textures
@ -74,6 +76,7 @@ PUBLISHED:
public:
typedef PT(Texture) MakeTextureFunc();
void register_texture_type(MakeTextureFunc *func, const string &extensions);
void register_filter(TexturePoolFilter *filter);
MakeTextureFunc *get_texture_type(const string &extension) const;
PT(Texture) make_texture(const string &extension) const;
@ -107,6 +110,16 @@ private:
void report_texture_unreadable(const Filename &filename) const;
// Methods to invoke a TexturePoolFilter.
PT(Texture) pre_load(const Filename &orig_filename,
const Filename &orig_alpha_filename,
int primary_file_num_channels,
int alpha_file_channel,
bool read_mipmaps);
PT(Texture) post_load(Texture *tex);
void load_filters();
static TexturePool *_global_ptr;
typedef phash_map<string, PT(Texture), string_hash> Textures;
Textures _textures;
@ -116,6 +129,9 @@ private:
typedef pmap<string, MakeTextureFunc *> TypeRegistry;
TypeRegistry _type_registry;
typedef pvector<TexturePoolFilter *> FilterRegistry;
FilterRegistry _filter_registry;
};
#include "texturePool.I"

View File

@ -0,0 +1,18 @@
// Filename: texturePoolFilter.I
// Created by: drose (27Jul06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,72 @@
// Filename: texturePoolFilter.cxx
// Created by: drose (27Jul06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "texturePoolFilter.h"
TypeHandle TexturePoolFilter::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: TexturePoolFilter::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
TexturePoolFilter::
~TexturePoolFilter() {
}
////////////////////////////////////////////////////////////////////
// Function: TexturePoolFilter::pre_load
// Access: Public, Virtual
// Description: This method is called before each texture is loaded
// from disk, via the TexturePool, for the first time.
// If this method returns NULL, then a new Texture will
// be allocated and loaded from disk normally by the
// TexturePool; otherwise, if it returns non-NULL, then
// that returned pointer will be used as the Texture for
// this filename.
////////////////////////////////////////////////////////////////////
PT(Texture) TexturePoolFilter::
pre_load(const Filename &, const Filename &, int, int, bool) {
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: TexturePoolFilter::post_load
// Access: Public, Virtual
// Description: This method is called after each texture has been
// loaded from disk, via the TexturePool, for the first
// time. By the time this method is called, the Texture
// has already been fully read from disk. This method
// should return the Texture pointer that the
// TexturePool should actually return (usually it is the
// same as the pointer supplied).
////////////////////////////////////////////////////////////////////
PT(Texture) TexturePoolFilter::
post_load(Texture *tex) {
return tex;
}
////////////////////////////////////////////////////////////////////
// Function: TexturePoolFilter::output
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void TexturePoolFilter::
output(ostream &out) const {
out << get_type();
}

View File

@ -0,0 +1,87 @@
// Filename: texturePoolFilter.h
// Created by: drose (27Jul06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef TEXTUREPOOLFILTER_H
#define TEXTUREPOOLFILTER_H
#include "pandabase.h"
#include "texture.h"
#include "pointerTo.h"
#include "typedObject.h"
////////////////////////////////////////////////////////////////////
// Class : TexturePoolFilter
// Description : This is an abstract base class, a placeholder for any
// number of different classes that may wish to
// implement an effect on every texture loaded from disk
// via the TexturePool.
//
// In practice, as of the time of this writing, only the
// TxaFileFilter (in pandatool) actually implements
// this. But other kinds of filters are possible.
//
// This filter, once registered, will get a callback and
// a chance to modify each texture as it is loaded from
// disk the first time. If more than one filter is
// registered, each will be called in sequence, in the
// order in which they were registered.
//
// The filter does not get called again if the texture
// is subsequently reloaded from disk. It is suggested
// that filters for which this might be a problem should
// call tex->set_keep_ram_image(true).
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA TexturePoolFilter : public TypedObject {
public:
virtual ~TexturePoolFilter();
virtual PT(Texture) pre_load(const Filename &orig_filename,
const Filename &orig_alpha_filename,
int primary_file_num_channels,
int alpha_file_channel,
bool read_mipmaps);
virtual PT(Texture) post_load(Texture *tex);
virtual void output(ostream &out) const;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedObject::init_type();
register_type(_type_handle, "TexturePoolFilter",
TypedObject::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
INLINE ostream &operator << (ostream &out, const TexturePoolFilter &filter) {
filter.output(out);
return out;
}
#include "texturePoolFilter.I"
#endif

View File

@ -15,3 +15,13 @@
#end bin_target
#begin lib_target
#define TARGET txafile
#define LOCAL_LIBS \
palettizer
#define SOURCES \
txaFileFilter.h txaFileFilter.I txaFileFilter.cxx
#end lib_target

View File

@ -0,0 +1,18 @@
// Filename: txaFileFilter.I
// Created by: drose (27Jul06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,162 @@
// Filename: txaFileFilter.cxx
// Created by: drose (27Jul06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "txaFileFilter.h"
#include "palettizer.h"
#include "txaFile.h"
#include "textureImage.h"
#include "sourceTextureImage.h"
#include "texturePool.h"
#include "dconfig.h"
#include "configVariableFilename.h"
#include "virtualFileSystem.h"
#include "config_util.h"
NotifyCategoryDeclNoExport(txafile);
NotifyCategoryDef(txafile, "");
// A few lines to register this filter type with the TexturePool when
// the shared library is loaded.
Configure(config_txaFileFilter);
ConfigureFn(config_txaFileFilter) {
TxaFileFilter::init_type();
TexturePool *pool = TexturePool::get_global_ptr();
pool->register_filter(new TxaFileFilter);
}
TypeHandle TxaFileFilter::_type_handle;
TxaFile *TxaFileFilter::_txa_file;
bool TxaFileFilter::_got_txa_file;
////////////////////////////////////////////////////////////////////
// Function: TxaFileFilter::post_load
// Access: Public, Virtual
// Description: This method is called after each texture has been
// loaded from disk, via the TexturePool, for the first
// time. By the time this method is called, the Texture
// has already been fully read from disk. This method
// should return the Texture pointer that the
// TexturePool should actually return (usually it is the
// same as the pointer supplied).
////////////////////////////////////////////////////////////////////
PT(Texture) TxaFileFilter::
post_load(Texture *tex) {
if (!_got_txa_file) {
read_txa_file();
}
TextureImage tex_image;
string name = tex->get_filename().get_basename_wo_extension();
tex_image.set_name(name);
SourceTextureImage *source = tex_image.get_source
(tex->get_fullpath(), tex->get_alpha_fullpath(), 0);
PNMImage pnm_image;
tex->store(pnm_image);
source->set_header(pnm_image);
tex_image.set_source_image(pnm_image);
tex_image.pre_txa_file();
bool matched = _txa_file->match_texture(&tex_image);
if (txafile_cat.is_debug()) {
if (!matched) {
txafile_cat.debug()
<< "Not matched: " << name << "\n";
} else {
txafile_cat.debug()
<< "Matched: " << name << "\n";
}
}
tex_image.post_txa_file();
PNMImage dest(tex_image.get_x_size(),
tex_image.get_y_size(),
tex_image.get_num_channels(),
pnm_image.get_maxval());
dest.quick_filter_from(pnm_image);
tex->load(dest);
// Create an EggTexture to pass back the requested alpha mode to
// the egg loader, if the texture is now being loaded from an egg
// file.
PT(EggTexture) egg_tex = new EggTexture(tex->get_name(), tex->get_fullpath());
const TextureProperties &props = tex_image.get_properties();
egg_tex->set_alpha_mode(tex_image.get_alpha_mode());
egg_tex->set_format(props._format);
egg_tex->set_minfilter(props._minfilter);
egg_tex->set_minfilter(props._magfilter);
egg_tex->set_anisotropic_degree(props._anisotropic_degree);
tex->set_aux_data("egg", egg_tex);
return tex;
}
////////////////////////////////////////////////////////////////////
// Function: TxaFileFilter::read_txa_file
// Access: Private, Static
// Description: Reads the textures.txa file named by the variable
// txa-file. Called only once, at startup.
////////////////////////////////////////////////////////////////////
void TxaFileFilter::
read_txa_file() {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
// We need to create a global Palettizer object to hold some of the
// global properties that may be specified in a txa file.
if (pal == (Palettizer *)NULL) {
pal = new Palettizer;
}
_txa_file = new TxaFile;
_got_txa_file = true;
ConfigVariableFilename txa_file
("txa-file", Filename("textures.txa"),
PRC_DESC("Specify the name of the txa file to load when the txafile texture filter"
"is in effect."));
Filename filename = txa_file;
vfs->resolve_filename(filename, texture_path);
vfs->resolve_filename(filename, model_path);
if (!vfs->exists(filename)) {
txafile_cat.warning()
<< "Filename " << filename << " not found.\n";
} else {
filename.set_text();
istream *ifile = vfs->open_read_file(filename, true);
if (ifile == (istream *)NULL) {
txafile_cat.warning()
<< "Filename " << filename << " cannot be read.\n";
} else {
if (!_txa_file->read(*ifile, filename)) {
txafile_cat.warning()
<< "Syntax errors in " << filename << "\n";
} else {
txafile_cat.info()
<< "Read " << filename << "\n";
}
vfs->close_read_file(ifile);
}
}
}

View File

@ -0,0 +1,80 @@
// Filename: txaFileFilter.h
// Created by: drose (27Jul06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef TXAFILEFILTER_H
#define TXAFILEFILTER_H
#include "pandatoolbase.h"
#include "texturePoolFilter.h"
class TxaFile;
////////////////////////////////////////////////////////////////////
// Class : TxaFileFilter
// Description : This is an abstract base class, a placeholder for any
// number of different classes that may wish to
// implement an effect on every texture loaded from disk
// via the TexturePool.
//
// In practice, as of the time of this writing, only the
// TxaFileFilter (in pandatool) actually implements
// this. But other kinds of filters are possible.
//
// This filter, once registered, will get a callback and
// a chance to modify each texture as it is loaded from
// disk the first time. If more than one filter is
// registered, each will be called in sequence, in the
// order in which they were registered.
//
// The filter does not get called again if the texture
// is subsequently reloaded from disk. It is suggested
// that filters for which this might be a problem should
// call tex->set_keep_ram_image(true).
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA TxaFileFilter : public TexturePoolFilter {
public:
virtual PT(Texture) post_load(Texture *tex);
private:
static void read_txa_file();
private:
static TxaFile *_txa_file;
static bool _got_txa_file;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TexturePoolFilter::init_type();
register_type(_type_handle, "TxaFileFilter",
TexturePoolFilter::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "txaFileFilter.I"
#endif