load cube maps etc. from egg files

This commit is contained in:
David Rose 2005-09-22 20:47:56 +00:00
parent b5d0ee8a7a
commit 5fde282d94
11 changed files with 383 additions and 24 deletions

View File

@ -171,6 +171,7 @@ appear before they are referenced.
<Scalar> wrap { repeat-definition }
<Scalar> wrapu { repeat-definition }
<Scalar> wrapv { repeat-definition }
<Scalar> wrapw { repeat-definition }
This defines the behavior of the texture image outside of the
normal (u,v) range 0.0 - 1.0. It is "REPEAT" to repeat the
@ -178,6 +179,32 @@ appear before they are referenced.
specified independently for each axis via "wrapu" and "wrapv", or
it may be specified for both simultaneously via "wrap".
Although less often used, for 3-d textures wrapw may also be
specified, and it behaves similarly to wrapu and wrapv.
<Scalar> type { texture-type }
This may be one of the following attributes:
1D
2D
3D
CUBE_MAP
The default is "2D", which specifies a normal, 2-d texture. If
any of the other types is specified instead, a texture image of
the corresponding type is loaded.
If 3D or CUBE_MAP is specified, then a series of texture images
must be loaded to make up the complete texture; in this case, the
texture filename is expected to include a sequence of one or more
hash mark ("#") characters, which will be filled in with the
sequence number. The first image in the sequence must be numbered
0, and there must be no gaps in the sequence. In this case, a
separate alpha-file designation is ignored; the alpha channel, if
present, must be included in the same image with the color
channel(s).
<Scalar> minfilter { filter-type }
<Scalar> magfilter { filter-type }
<Scalar> magfilteralpha { filter-type }

View File

@ -33,6 +33,7 @@
#include "pt_EggMaterial.h"
#include "config_egg.h"
#include "hashFilename.h"
#include "dSearchPath.h"
#include "deg_2_rad.h"
#include "dcast.h"
@ -421,6 +422,7 @@ has_absolute_pathnames() const {
////////////////////////////////////////////////////////////////////
void EggGroupNode::
resolve_filenames(const DSearchPath &searchpath) {
cerr << "resolve_filenames " << get_name() << "\n";
Children::iterator ci;
for (ci = _children.begin();
ci != _children.end();
@ -428,14 +430,27 @@ resolve_filenames(const DSearchPath &searchpath) {
EggNode *child = *ci;
if (child->is_of_type(EggTexture::get_class_type())) {
EggTexture *tex = DCAST(EggTexture, child);
Filename tex_filename = tex->get_filename();
tex_filename.resolve_filename(searchpath);
tex->set_filename(tex_filename);
if (tex->has_hash_filename()) {
HashFilename tex_filename = tex->get_filename();
tex_filename.resolve_filename(searchpath);
tex->set_filename(tex_filename);
if (tex->has_alpha_filename()) {
HashFilename alpha_filename = tex->get_alpha_filename();
alpha_filename.resolve_filename(searchpath);
tex->set_alpha_filename(alpha_filename);
}
if (tex->has_alpha_filename()) {
Filename alpha_filename = tex->get_alpha_filename();
alpha_filename.resolve_filename(searchpath);
tex->set_alpha_filename(alpha_filename);
} else {
Filename tex_filename = tex->get_filename();
tex_filename.resolve_filename(searchpath);
tex->set_filename(tex_filename);
if (tex->has_alpha_filename()) {
Filename alpha_filename = tex->get_alpha_filename();
alpha_filename.resolve_filename(searchpath);
tex->set_alpha_filename(alpha_filename);
}
}
} else if (child->is_of_type(EggFilenameNode::get_class_type())) {

View File

@ -17,6 +17,41 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: EggTexture::has_hash_filename
// Access: Published
// Description: Returns true if the texture filename is expected to
// contain a hash mark standing in for a sequence
// number, or false if the filename is a literal
// filename. This will be true only if TextureType is
// TT_3d_texture or TT_cube_map.
////////////////////////////////////////////////////////////////////
INLINE bool EggTexture::
has_hash_filename() const {
return (_texture_type == TT_3d_texture ||
_texture_type == TT_cube_map);
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::set_texture_type
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EggTexture::
set_texture_type(TextureType texture_type) {
_texture_type = texture_type;
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::get_texture_type
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE EggTexture::TextureType EggTexture::
get_texture_type() const {
return _texture_type;
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::set_format
// Access: Published
@ -116,7 +151,7 @@ get_wrap_v() const {
// Function: EggTexture::determine_wrap_v
// Access: Published
// Description: Determines the appropriate wrap in the V direction.
// This is different from get_wrap_v() in that if the U
// This is different from get_wrap_v() in that if the V
// wrap is unspecified, it returns the overall wrap
// value.
////////////////////////////////////////////////////////////////////
@ -125,6 +160,40 @@ determine_wrap_v() const {
return (_wrap_v == WM_unspecified) ? get_wrap_mode() : get_wrap_v();
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::set_wrap_w
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EggTexture::
set_wrap_w(WrapMode mode) {
_wrap_w = mode;
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::get_wrap_w
// Access: Published
// Description: Returns the amount specified for W wrap. This may be
// unspecified, even if there is an overall wrap value.
////////////////////////////////////////////////////////////////////
INLINE EggTexture::WrapMode EggTexture::
get_wrap_w() const {
return _wrap_w;
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::determine_wrap_w
// Access: Published
// Description: Determines the appropriate wrap in the W direction.
// This is different from get_wrap_w() in that if the W
// wrap is unspecified, it returns the overall wrap
// value.
////////////////////////////////////////////////////////////////////
INLINE EggTexture::WrapMode EggTexture::
determine_wrap_w() const {
return (_wrap_w == WM_unspecified) ? get_wrap_mode() : get_wrap_w();
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::set_minfilter
// Access: Published

View File

@ -35,10 +35,12 @@ EggTexture::
EggTexture(const string &tref_name, const string &filename)
: EggFilenameNode(tref_name, filename)
{
_texture_type = TT_unspecified;
_format = F_unspecified;
_wrap_mode = WM_unspecified;
_wrap_u = WM_unspecified;
_wrap_v = WM_unspecified;
_wrap_w = WM_unspecified;
_minfilter = FT_unspecified;
_magfilter = FT_unspecified;
_anisotropic_degree = 0;
@ -75,10 +77,12 @@ operator = (const EggTexture &copy) {
EggRenderMode::operator = (copy);
EggTransform::operator = (copy);
_texture_type = copy._texture_type;
_format = copy._format;
_wrap_mode = copy._wrap_mode;
_wrap_u = copy._wrap_u;
_wrap_v = copy._wrap_v;
_wrap_w = copy._wrap_w;
_minfilter = copy._minfilter;
_magfilter = copy._magfilter;
_anisotropic_degree = copy._anisotropic_degree;
@ -136,6 +140,11 @@ write(ostream &out, int indent_level) const {
<< get_alpha_file_channel() << " }\n";
}
if (get_texture_type() != TT_unspecified) {
indent(out, indent_level + 2)
<< "<Scalar> texture_type { " << get_texture_type() << " }\n";
}
if (get_format() != F_unspecified) {
indent(out, indent_level + 2)
<< "<Scalar> format { " << get_format() << " }\n";
@ -156,6 +165,11 @@ write(ostream &out, int indent_level) const {
<< "<Scalar> wrapv { " << get_wrap_v() << " }\n";
}
if (get_wrap_w() != WM_unspecified) {
indent(out, indent_level + 2)
<< "<Scalar> wrapw { " << get_wrap_w() << " }\n";
}
if (get_minfilter() != FT_unspecified) {
indent(out, indent_level + 2)
<< "<Scalar> minfilter { " << get_minfilter() << " }\n";
@ -331,10 +345,12 @@ is_equivalent_to(const EggTexture &other, int eq) const {
if (eq & E_attributes) {
//cout << "compared by attributes" << endl;
if (_format != other._format ||
if (_texture_type != other._texture_type ||
_format != other._format ||
_wrap_mode != other._wrap_mode ||
_wrap_u != other._wrap_u ||
_wrap_v != other._wrap_v ||
_wrap_w != other._wrap_w ||
_minfilter != other._minfilter ||
_magfilter != other._magfilter ||
_env_type != other._env_type) {
@ -407,6 +423,9 @@ sorts_less_than(const EggTexture &other, int eq) const {
}
if (eq & E_attributes) {
if (_texture_type != other._texture_type) {
return (int)_texture_type < (int)other._texture_type;
}
if (_format != other._format) {
return (int)_format < (int)other._format;
}
@ -419,6 +438,9 @@ sorts_less_than(const EggTexture &other, int eq) const {
if (_wrap_v != other._wrap_v) {
return (int)_wrap_v < (int)other._wrap_v;
}
if (_wrap_w != other._wrap_w) {
return (int)_wrap_w < (int)other._wrap_w;
}
if (_minfilter != other._minfilter) {
return (int)_minfilter < (int)other._minfilter;
}
@ -560,6 +582,40 @@ multitexture_over(EggTexture *other) {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::string_texture_type
// Access: Published, Static
// Description: Returns the Texture_ype value associated with the given
// string representation, or TT_unspecified if the string
// does not match any known TextureType value.
////////////////////////////////////////////////////////////////////
EggTexture::TextureType EggTexture::
string_texture_type(const string &string) {
if (cmp_nocase_uh(string, "1d") == 0 ||
cmp_nocase_uh(string, "1dtexture") == 0 ||
cmp_nocase_uh(string, "1d_texture") == 0) {
return TT_1d_texture;
} else if (cmp_nocase_uh(string, "2d") == 0 ||
cmp_nocase_uh(string, "2dtexture") == 0 ||
cmp_nocase_uh(string, "2d_texture") == 0) {
return TT_2d_texture;
} else if (cmp_nocase_uh(string, "3d") == 0 ||
cmp_nocase_uh(string, "3dtexture") == 0 ||
cmp_nocase_uh(string, "3d_texture") == 0) {
return TT_2d_texture;
} else if (cmp_nocase_uh(string, "cube") == 0 ||
cmp_nocase_uh(string, "cubemap") == 0 ||
cmp_nocase_uh(string, "cube_map") == 0) {
return TT_cube_map;
} else {
return TT_unspecified;
}
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::string_format
// Access: Published, Static
@ -912,6 +968,33 @@ r_min_multitexture_sort(int sort, EggTexture::MultiTextures &cycle_detector) {
}
////////////////////////////////////////////////////////////////////
// Function: TextureType output operator
// Description:
////////////////////////////////////////////////////////////////////
ostream &operator << (ostream &out, EggTexture::TextureType texture_type) {
switch (texture_type) {
case EggTexture::TT_unspecified:
return out << "unspecified";
case EggTexture::TT_1d_texture:
return out << "1d";
case EggTexture::TT_2d_texture:
return out << "2d";
case EggTexture::TT_3d_texture:
return out << "3d";
case EggTexture::TT_cube_map:
return out << "cube-map";
}
nassertr(false, out);
return out << "(**invalid**)";
}
////////////////////////////////////////////////////////////////////
// Function: Format output operator
// Description:

View File

@ -58,6 +58,10 @@ PUBLISHED:
bool has_alpha_channel(int num_components) const;
enum TextureType {
TT_unspecified, TT_1d_texture,
TT_2d_texture, TT_3d_texture, TT_cube_map
};
enum Format {
F_unspecified,
F_rgba, F_rgbm, F_rgba12, F_rgba8, F_rgba4, F_rgba5,
@ -146,6 +150,11 @@ PUBLISHED:
TG_point_sprite,
};
INLINE bool has_hash_filename() const;
INLINE void set_texture_type(TextureType texture_type);
INLINE TextureType get_texture_type() const;
INLINE void set_format(Format format);
INLINE Format get_format() const;
@ -160,6 +169,10 @@ PUBLISHED:
INLINE WrapMode get_wrap_v() const;
INLINE WrapMode determine_wrap_v() const;
INLINE void set_wrap_w(WrapMode mode);
INLINE WrapMode get_wrap_w() const;
INLINE WrapMode determine_wrap_w() const;
INLINE void set_minfilter(FilterType type);
INLINE FilterType get_minfilter() const;
@ -234,6 +247,7 @@ PUBLISHED:
bool multitexture_over(EggTexture *other);
INLINE int get_multitexture_sort() const;
static TextureType string_texture_type(const string &string);
static Format string_format(const string &string);
static WrapMode string_wrap_mode(const string &string);
static FilterType string_filter_type(const string &string);
@ -265,8 +279,9 @@ private:
F_has_alpha_scale = 0x0200,
};
TextureType _texture_type;
Format _format;
WrapMode _wrap_mode, _wrap_u, _wrap_v;
WrapMode _wrap_mode, _wrap_u, _wrap_v, _wrap_w;
FilterType _minfilter, _magfilter;
int _anisotropic_degree;
EnvType _env_type;
@ -344,6 +359,7 @@ INLINE ostream &operator << (ostream &out, const EggTexture &n) {
return out << n.get_filename();
}
EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::TextureType texture_type);
EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::Format format);
EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::WrapMode mode);
EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::FilterType type);

View File

@ -344,7 +344,15 @@ texture_body:
double value = $<_number>5;
string strval = $<_string>5;
if (cmp_nocase_uh(name, "format") == 0) {
if (cmp_nocase_uh(name, "type") == 0) {
EggTexture::TextureType tt = EggTexture::string_texture_type(strval);
if (tt == EggTexture::TT_unspecified) {
eggyywarning("Unknown texture texture_type " + strval);
} else {
texture->set_texture_type(tt);
}
} else if (cmp_nocase_uh(name, "format") == 0) {
EggTexture::Format f = EggTexture::string_format(strval);
if (f == EggTexture::F_unspecified) {
eggyywarning("Unknown texture format " + strval);

View File

@ -852,16 +852,31 @@ load_texture(TextureDef &def, const EggTexture *egg_tex) {
break;
}
Texture *tex;
if (egg_tex->has_alpha_filename() && wanted_alpha) {
tex = TexturePool::load_texture(egg_tex->get_fullpath(),
egg_tex->get_alpha_fullpath(),
wanted_channels,
egg_tex->get_alpha_file_channel());
} else {
tex = TexturePool::load_texture(egg_tex->get_fullpath(),
wanted_channels);
PT(Texture) tex;
switch (egg_tex->get_texture_type()) {
case EggTexture::TT_unspecified:
case EggTexture::TT_1d_texture:
case EggTexture::TT_2d_texture:
if (egg_tex->has_alpha_filename() && wanted_alpha) {
tex = TexturePool::load_texture(egg_tex->get_fullpath(),
egg_tex->get_alpha_fullpath(),
wanted_channels,
egg_tex->get_alpha_file_channel());
} else {
tex = TexturePool::load_texture(egg_tex->get_fullpath(),
wanted_channels);
}
break;
case EggTexture::TT_3d_texture:
tex = TexturePool::load_3d_texture(HashFilename(egg_tex->get_fullpath()));
break;
case EggTexture::TT_cube_map:
tex = TexturePool::load_cube_map(HashFilename(egg_tex->get_fullpath()));
break;
}
if (tex == (Texture *)NULL) {
return false;
}
@ -941,6 +956,30 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
<< (int)egg_tex->determine_wrap_v() << "\n";
}
switch (egg_tex->determine_wrap_w()) {
case EggTexture::WM_repeat:
tex->set_wrap_w(Texture::WM_repeat);
break;
case EggTexture::WM_clamp:
if (egg_ignore_clamp) {
egg2pg_cat.warning()
<< "Ignoring clamp request\n";
tex->set_wrap_w(Texture::WM_repeat);
} else {
tex->set_wrap_w(Texture::WM_clamp);
}
break;
case EggTexture::WM_unspecified:
break;
default:
egg2pg_cat.warning()
<< "Unexpected texture wrap flag: "
<< (int)egg_tex->determine_wrap_w() << "\n";
}
switch (egg_tex->get_minfilter()) {
case EggTexture::FT_nearest:
tex->set_minfilter(Texture::FT_nearest);

View File

@ -90,7 +90,7 @@ AnimInterface::
void AnimInterface::
play(double from, double to) {
if (from >= to) {
pose(from);
pose((int)from);
return;
}
@ -122,7 +122,7 @@ play(double from, double to) {
void AnimInterface::
loop(bool restart, double from, double to) {
if (from >= to) {
pose(from);
pose((int)from);
return;
}
@ -157,7 +157,7 @@ loop(bool restart, double from, double to) {
void AnimInterface::
pingpong(bool restart, double from, double to) {
if (from >= to) {
pose(from);
pose((int)from);
return;
}

View File

@ -42,6 +42,18 @@ HashFilename(const HashFilename &copy) :
{
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::Copy Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE HashFilename::
HashFilename(const Filename &copy) :
Filename(copy)
{
locate_hash();
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::Copy Assignment Operator
// Access: Published

View File

@ -46,7 +46,7 @@ get_filename_index(int index) const {
// Function: HashFilename::set_hash_to_end
// Access: Published
// Description: Replaces the part of the filename from the beginning
// of the has sequence to the end of the filename.
// of the hash sequence to the end of the filename.
////////////////////////////////////////////////////////////////////
void HashFilename::
set_hash_to_end(const string &s) {
@ -57,6 +57,91 @@ set_hash_to_end(const string &s) {
locate_hash();
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::resolve_filename
// Access: Published
// Description: Searches the given search path for the filename. If
// it is found, updates the filename to the full
// pathname found and returns true; otherwise, returns
// false.
////////////////////////////////////////////////////////////////////
bool HashFilename::
resolve_filename(const DSearchPath &searchpath,
const string &default_extension) {
if (!has_hash()) {
return Filename::resolve_filename(searchpath, default_extension);
}
Filename file0 = get_filename_index(0);
if (!file0.resolve_filename(searchpath, default_extension)) {
return false;
}
int change = file0.length() - length();
if (file0.length() < _hash_start || _hash_end + change < 0 ||
file0.substr(_hash_end + change) != substr(_hash_end)) {
// Hmm, somehow the suffix part of the filename--everything after
// the hash sequence--was changed by the above resolve operation.
// Abandon ship.
return false;
}
// Replace the prefix part of the filename--everything before the
// hash sequence.
_filename = file0.substr(0, _hash_start + change) + substr(_hash_start);
_hash_start += change;
_hash_end += change;
return true;
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::find_on_searchpath
// Access: Published
// Description: Performs the reverse of the resolve_filename()
// operation: assuming that the current filename is
// fully-specified pathname (i.e. beginning with '/'),
// look on the indicated search path for a directory
// under which the file can be found. When found,
// adjust the Filename to be relative to the indicated
// directory name.
//
// Returns the index of the directory on the searchpath
// at which the file was found, or -1 if it was not
// found.
////////////////////////////////////////////////////////////////////
int HashFilename::
find_on_searchpath(const DSearchPath &searchpath) {
if (!has_hash()) {
return Filename::find_on_searchpath(searchpath);
}
Filename file0 = get_filename_index(0);
int index = file0.find_on_searchpath(searchpath);
if (index == -1) {
return -1;
}
int change = file0.length() - length();
if (file0.length() < _hash_start || _hash_end + change < 0 ||
file0.substr(_hash_end + change) != substr(_hash_end)) {
// Hmm, somehow the suffix part of the filename--everything after
// the hash sequence--was changed by the above resolve operation.
// Abandon ship.
return false;
}
// Replace the prefix part of the filename--everything before the
// hash sequence.
_filename = file0.substr(0, _hash_start + change) + substr(_hash_start);
_hash_start += change;
_hash_end += change;
return index;
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::locate_hash
// Access: Private

View File

@ -38,6 +38,7 @@ class EXPCL_PANDA HashFilename : public Filename {
PUBLISHED:
INLINE HashFilename(const string &filename_pattern = string());
INLINE HashFilename(const HashFilename &copy);
INLINE HashFilename(const Filename &copy);
INLINE void operator = (const HashFilename &copy);
INLINE void operator = (const Filename &copy);
INLINE ~HashFilename();
@ -47,6 +48,10 @@ PUBLISHED:
INLINE string get_hash_to_end() const;
void set_hash_to_end(const string &s);
bool resolve_filename(const DSearchPath &searchpath,
const string &default_extension = string());
int find_on_searchpath(const DSearchPath &searchpath);
private:
void locate_hash();