*** empty log message ***
This commit is contained in:
parent
0a25316f29
commit
98a4f21207
|
|
@ -19,7 +19,10 @@
|
|||
eggFilenameNode.cxx eggFilenameNode.h eggGroup.I eggGroup.cxx \
|
||||
eggGroup.h eggGroupNode.I eggGroupNode.cxx eggGroupNode.h \
|
||||
eggGroupUniquifier.h eggGroupUniquifier.cxx \
|
||||
eggMaterial.I eggMaterial.cxx eggMaterial.h eggMiscFuncs.I \
|
||||
eggMaterial.I eggMaterial.cxx eggMaterial.h \
|
||||
eggMaterialCollection.I eggMaterialCollection.cxx \
|
||||
eggMaterialCollection.h \
|
||||
eggMiscFuncs.I \
|
||||
eggMiscFuncs.cxx eggMiscFuncs.h eggNamedObject.I eggNamedObject.cxx \
|
||||
eggNamedObject.h eggNameUniquifier.cxx eggNameUniquifier.h \
|
||||
eggNode.I eggNode.cxx eggNode.h eggNurbsCurve.I \
|
||||
|
|
@ -51,7 +54,8 @@
|
|||
eggExternalReference.h eggFilenameNode.I eggFilenameNode.h \
|
||||
eggGroup.I eggGroup.h eggGroupNode.I eggGroupNode.h \
|
||||
eggGroupUniquifier.h eggMaterial.I \
|
||||
eggMaterial.h eggMorph.I eggMorph.h eggMorphList.I eggMorphList.h \
|
||||
eggMaterial.h eggMaterialCollection.I eggMaterialCollection.h \
|
||||
eggMorph.I eggMorph.h eggMorphList.I eggMorphList.h \
|
||||
eggNamedObject.I eggNamedObject.h eggNameUniquifier.h eggNode.I eggNode.h \
|
||||
eggNurbsCurve.I eggNurbsCurve.h eggNurbsSurface.I eggNurbsSurface.h \
|
||||
eggObject.I eggObject.h eggParameters.h eggPoint.I eggPoint.h \
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "eggData.h"
|
||||
#include "eggCoordinateSystem.h"
|
||||
#include "eggTextureCollection.h"
|
||||
#include "eggMaterialCollection.h"
|
||||
#include "eggComment.h"
|
||||
#include "eggPoolUniquifier.h"
|
||||
#include "config_egg.h"
|
||||
|
|
@ -133,9 +134,9 @@ resolve_externals(const DSearchPath &searchpath) {
|
|||
// Description: Removes duplicate references to the same texture
|
||||
// image with the same properties. Considers two
|
||||
// texture references with identical properties, but
|
||||
// different tref names, to be the equivalent, and
|
||||
// collapses them, choosing one tref name to keep
|
||||
// arbitrarily. Returns the number of textures removed.
|
||||
// different tref names, to be equivalent, and collapses
|
||||
// them, choosing one tref name to keep arbitrarily.
|
||||
// Returns the number of textures removed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggData::
|
||||
collapse_equivalent_textures() {
|
||||
|
|
@ -145,6 +146,24 @@ collapse_equivalent_textures() {
|
|||
textures.collapse_equivalent_textures(~EggTexture::E_tref_name, this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggData::collapse_equivalent_materials
|
||||
// Access: Public
|
||||
// Description: Removes duplicate references to the same material
|
||||
// with the same properties. Considers two material
|
||||
// references with identical properties, but different
|
||||
// mref names, to be equivalent, and collapses them,
|
||||
// choosing one mref name to keep arbitrarily. Returns
|
||||
// the number of materials removed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggData::
|
||||
collapse_equivalent_materials() {
|
||||
EggMaterialCollection materials;
|
||||
materials.find_used_materials(this);
|
||||
return
|
||||
materials.collapse_equivalent_materials(~EggMaterial::E_mref_name, this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggData::write_egg
|
||||
// Access: Public
|
||||
|
|
@ -286,8 +305,17 @@ pre_write() {
|
|||
|
||||
textures.insert_textures(this, ci);
|
||||
|
||||
// Also make sure that the vertex pools and materials are uniquely
|
||||
// named. This also checks textures, which is kind of redundant
|
||||
// Do the same thing with the materials.
|
||||
EggMaterialCollection materials;
|
||||
materials.extract_materials(this);
|
||||
materials.remove_unused_materials(this);
|
||||
materials.collapse_equivalent_materials(~0, this);
|
||||
materials.uniquify_mrefs();
|
||||
materials.sort_by_mref();
|
||||
materials.insert_materials(this, ci);
|
||||
|
||||
// Also make sure that the vertex pools are uniquely named. This
|
||||
// also checks textures and materials, which is kind of redundant
|
||||
// since we just did that, but we don't mind.
|
||||
EggPoolUniquifier pu;
|
||||
pu.uniquify(this);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ public:
|
|||
|
||||
bool resolve_externals(const DSearchPath &searchpath = DSearchPath());
|
||||
int collapse_equivalent_textures();
|
||||
int collapse_equivalent_materials();
|
||||
|
||||
bool write_egg(Filename filename);
|
||||
bool write_egg(ostream &out);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "eggVertexPool.h"
|
||||
#include "eggVertex.h"
|
||||
#include "eggTextureCollection.h"
|
||||
#include "eggMaterialCollection.h"
|
||||
#include "config_egg.h"
|
||||
|
||||
#include <dSearchPath.h>
|
||||
|
|
@ -830,6 +831,52 @@ find_textures(EggTextureCollection *collection) {
|
|||
return num_found;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggGroupNode::find_materials()
|
||||
// Access: Protected
|
||||
// Description: Walks the tree, looking for EggMaterials. Each
|
||||
// EggMaterial that is found is removed from the
|
||||
// hierarchy and added to the EggMaterialCollection.
|
||||
// Returns the number of EggMaterials found.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggGroupNode::
|
||||
find_materials(EggMaterialCollection *collection) {
|
||||
int num_found = 0;
|
||||
|
||||
// We can do this ci/cnext iteration through the list as we modify
|
||||
// it, only because we know this works with an STL list type
|
||||
// container. If this were a vector or a set, this wouldn't
|
||||
// necessarily work.
|
||||
|
||||
Children::iterator ci, cnext;
|
||||
ci = _children.begin();
|
||||
while (ci != _children.end()) {
|
||||
cnext = ci;
|
||||
++cnext;
|
||||
EggNode *child = *ci;
|
||||
|
||||
if (child->is_of_type(EggMaterial::get_class_type())) {
|
||||
PT(EggMaterial) tex = DCAST(EggMaterial, child);
|
||||
|
||||
// Now remove the EggMaterial entry from our child list.
|
||||
prepare_remove_child(tex);
|
||||
_children.erase(ci);
|
||||
|
||||
// And add it to the collection.
|
||||
collection->add_material(tex);
|
||||
num_found++;
|
||||
|
||||
} else if (child->is_of_type(EggGroupNode::get_class_type())) {
|
||||
num_found +=
|
||||
DCAST(EggGroupNode, child)->find_materials(collection);
|
||||
}
|
||||
|
||||
ci = cnext;
|
||||
}
|
||||
|
||||
return num_found;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggGroupNode::r_resolve_externals
|
||||
// Access: Protected
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <list>
|
||||
|
||||
class EggTextureCollection;
|
||||
class EggMaterialCollection;
|
||||
class EggPolygon;
|
||||
class EggVertex;
|
||||
class DSearchPath;
|
||||
|
|
@ -119,6 +120,7 @@ protected:
|
|||
|
||||
CoordinateSystem find_coordsys_entry();
|
||||
int find_textures(EggTextureCollection *collection);
|
||||
int find_materials(EggMaterialCollection *collection);
|
||||
bool r_resolve_externals(const DSearchPath &searchpath,
|
||||
CoordinateSystem coordsys);
|
||||
|
||||
|
|
@ -163,6 +165,7 @@ private:
|
|||
static TypeHandle _type_handle;
|
||||
|
||||
friend class EggTextureCollection;
|
||||
friend class EggMaterialCollection;
|
||||
};
|
||||
|
||||
#include "eggGroupNode.I"
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ get_emit() const {
|
|||
if (has_emit()) {
|
||||
return _emit;
|
||||
} else {
|
||||
return RGBColorf(1.0, 1.0, 1.0);
|
||||
return RGBColorf(0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -188,6 +188,116 @@ get_spec() const {
|
|||
if (has_spec()) {
|
||||
return _spec;
|
||||
} else {
|
||||
return RGBColorf(1.0, 1.0, 1.0);
|
||||
return RGBColorf(0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterial::set_shininess
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggMaterial::
|
||||
set_shininess(double shininess) {
|
||||
_shininess = shininess;
|
||||
_flags |= F_shininess;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterial::clear_shininess
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggMaterial::
|
||||
clear_shininess() {
|
||||
_flags &= ~F_shininess;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterial::has_shininess
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMaterial::
|
||||
has_shininess() const {
|
||||
return (_flags & F_shininess) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterial::get_shininess
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double EggMaterial::
|
||||
get_shininess() const {
|
||||
if (has_shininess()) {
|
||||
return _shininess;
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterial::set_local
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggMaterial::
|
||||
set_local(bool local) {
|
||||
_local = local;
|
||||
_flags |= F_local;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterial::clear_local
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggMaterial::
|
||||
clear_local() {
|
||||
_flags &= ~F_local;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterial::has_local
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMaterial::
|
||||
has_local() const {
|
||||
return (_flags & F_local) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterial::get_local
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMaterial::
|
||||
get_local() const {
|
||||
if (has_local()) {
|
||||
return _local;
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: UniqueEggMaterials::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UniqueEggMaterials::
|
||||
UniqueEggMaterials(int eq) : _eq(eq) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: UniqueEggMaterials::Function operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool UniqueEggMaterials::
|
||||
operator ()(const EggMaterial *t1, const EggMaterial *t2) const {
|
||||
return t1->sorts_less_than(*t2, _eq);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,5 +55,127 @@ write(ostream &out, int indent_level) const {
|
|||
<< "<Scalar> diffb { " << get_diff()[2] << " }\n";
|
||||
}
|
||||
|
||||
if (has_amb()) {
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> ambr { " << get_amb()[0] << " }\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> ambg { " << get_amb()[1] << " }\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> ambb { " << get_amb()[2] << " }\n";
|
||||
}
|
||||
|
||||
if (has_emit()) {
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> emitr { " << get_emit()[0] << " }\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> emitg { " << get_emit()[1] << " }\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> emitb { " << get_emit()[2] << " }\n";
|
||||
}
|
||||
|
||||
if (has_spec()) {
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> specr { " << get_spec()[0] << " }\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> specg { " << get_spec()[1] << " }\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> specb { " << get_spec()[2] << " }\n";
|
||||
}
|
||||
|
||||
if (has_shininess()) {
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> shininess { " << get_shininess() << " }\n";
|
||||
}
|
||||
|
||||
if (has_local()) {
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> local { " << get_local() << " }\n";
|
||||
}
|
||||
|
||||
indent(out, indent_level) << "}\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterial::is_equivalent_to
|
||||
// Access: Public
|
||||
// Description: Returns true if the two materials are equivalent in
|
||||
// all relevant properties (according to eq), false
|
||||
// otherwise.
|
||||
//
|
||||
// The Equivalence parameter, eq, should be set to the
|
||||
// bitwise OR of the following properties, according to
|
||||
// what you consider relevant:
|
||||
//
|
||||
// EggMaterial::E_attributes:
|
||||
// All material attributes (diff, spec,
|
||||
// etc.) except MRef name.
|
||||
//
|
||||
// EggMaterial::E_mref_name:
|
||||
// The MRef name.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggMaterial::
|
||||
is_equivalent_to(const EggMaterial &other, int eq) const {
|
||||
if (eq & E_attributes) {
|
||||
if (_flags != other._flags ||
|
||||
(has_diff() && get_diff() != other.get_diff()) ||
|
||||
(has_amb() && get_amb() != other.get_amb()) ||
|
||||
(has_emit() && get_emit() != other.get_emit()) ||
|
||||
(has_spec() && get_spec() != other.get_spec()) ||
|
||||
(has_shininess() && get_shininess() != other.get_shininess()) ||
|
||||
(has_local() && get_local() != other.get_local())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (eq & E_mref_name) {
|
||||
if (get_name() != other.get_name()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterial::sorts_less_than
|
||||
// Access: Public
|
||||
// Description: An ordering operator to compare two materials for
|
||||
// sorting order. This imposes an arbitrary ordering
|
||||
// useful to identify unique materials, according to the
|
||||
// indicated Equivalence factor. See
|
||||
// is_equivalent_to().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggMaterial::
|
||||
sorts_less_than(const EggMaterial &other, int eq) const {
|
||||
if (eq & E_attributes) {
|
||||
if (_flags != other._flags) {
|
||||
return _flags < (int)other._flags;
|
||||
}
|
||||
if (has_diff() && get_diff() != other.get_diff()) {
|
||||
return get_diff().compare_to(other.get_diff()) < 0;
|
||||
}
|
||||
if (has_amb() && get_amb() != other.get_amb()) {
|
||||
return get_amb().compare_to(other.get_amb()) < 0;
|
||||
}
|
||||
if (has_emit() && get_emit() != other.get_emit()) {
|
||||
return get_emit().compare_to(other.get_emit()) < 0;
|
||||
}
|
||||
if (has_spec() && get_spec() != other.get_spec()) {
|
||||
return get_spec().compare_to(other.get_spec()) < 0;
|
||||
}
|
||||
if (has_shininess() && get_shininess() != other.get_shininess()) {
|
||||
return get_shininess() < other.get_shininess() ? -1 : 1;
|
||||
}
|
||||
if (has_local() && get_local() != other.get_local()) {
|
||||
return get_local() - other.get_local();
|
||||
}
|
||||
}
|
||||
|
||||
if (eq & E_mref_name) {
|
||||
if (get_name() != other.get_name()) {
|
||||
return get_name() < other.get_name();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,14 @@ public:
|
|||
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
enum Equivalence {
|
||||
E_attributes = 0x001,
|
||||
E_mref_name = 0x002,
|
||||
};
|
||||
|
||||
bool is_equivalent_to(const EggMaterial &other, int eq) const;
|
||||
bool sorts_less_than(const EggMaterial &other, int eq) const;
|
||||
|
||||
INLINE void set_diff(const RGBColorf &diff);
|
||||
INLINE void clear_diff();
|
||||
INLINE bool has_diff() const;
|
||||
|
|
@ -43,18 +51,32 @@ public:
|
|||
INLINE bool has_spec() const;
|
||||
INLINE RGBColorf get_spec() const;
|
||||
|
||||
INLINE void set_shininess(double shininess);
|
||||
INLINE void clear_shininess();
|
||||
INLINE bool has_shininess() const;
|
||||
INLINE double get_shininess() const;
|
||||
|
||||
INLINE void set_local(bool local);
|
||||
INLINE void clear_local();
|
||||
INLINE bool has_local() const;
|
||||
INLINE bool get_local() const;
|
||||
|
||||
private:
|
||||
enum Flags {
|
||||
F_diff = 0x001,
|
||||
F_amb = 0x002,
|
||||
F_emit = 0x004,
|
||||
F_spec = 0x008
|
||||
F_diff = 0x001,
|
||||
F_amb = 0x002,
|
||||
F_emit = 0x004,
|
||||
F_spec = 0x008,
|
||||
F_shininess = 0x010,
|
||||
F_local = 0x020
|
||||
};
|
||||
|
||||
RGBColorf _diff;
|
||||
RGBColorf _amb;
|
||||
RGBColorf _emit;
|
||||
RGBColorf _spec;
|
||||
double _shininess;
|
||||
bool _local;
|
||||
int _flags;
|
||||
|
||||
|
||||
|
|
@ -76,6 +98,21 @@ private:
|
|||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : UniqueEggMaterials
|
||||
// Description : An STL function object for sorting materials into
|
||||
// order by properties. Returns true if the two
|
||||
// referenced EggMaterial pointers are in sorted order,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEGG UniqueEggMaterials {
|
||||
public:
|
||||
INLINE UniqueEggMaterials(int eq = ~0);
|
||||
INLINE bool operator ()(const EggMaterial *t1, const EggMaterial *t2) const;
|
||||
|
||||
int _eq;
|
||||
};
|
||||
|
||||
#include "eggMaterial.I"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
// Filename: eggMaterialCollection.I
|
||||
// Created by: drose (30Apr01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
INLINE EggMaterialCollection::iterator EggMaterialCollection::
|
||||
begin() const {
|
||||
nassertr(_ordered_materials.size() == _materials.size(),
|
||||
_ordered_materials.begin());
|
||||
return _ordered_materials.begin();
|
||||
}
|
||||
|
||||
INLINE EggMaterialCollection::iterator EggMaterialCollection::
|
||||
end() const {
|
||||
return _ordered_materials.end();
|
||||
}
|
||||
|
||||
INLINE bool EggMaterialCollection::
|
||||
empty() const {
|
||||
return _ordered_materials.empty();
|
||||
}
|
||||
|
||||
INLINE EggMaterialCollection::size_type EggMaterialCollection::
|
||||
size() const {
|
||||
nassertr(_ordered_materials.size() == _materials.size(), 0);
|
||||
return _ordered_materials.size();
|
||||
}
|
||||
|
|
@ -0,0 +1,440 @@
|
|||
// Filename: eggMaterialCollection.cxx
|
||||
// Created by: drose (30Apr01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "eggMaterialCollection.h"
|
||||
#include "eggGroupNode.h"
|
||||
#include "eggPrimitive.h"
|
||||
#include "eggMaterial.h"
|
||||
|
||||
#include <nameUniquifier.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggMaterialCollection::
|
||||
EggMaterialCollection() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggMaterialCollection::
|
||||
EggMaterialCollection(const EggMaterialCollection ©) :
|
||||
_materials(copy._materials),
|
||||
_ordered_materials(copy._ordered_materials)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggMaterialCollection &EggMaterialCollection::
|
||||
operator = (const EggMaterialCollection ©) {
|
||||
_materials = copy._materials;
|
||||
_ordered_materials = copy._ordered_materials;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::clear
|
||||
// Access: Public
|
||||
// Description: Removes all materials from the collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMaterialCollection::
|
||||
clear() {
|
||||
_materials.clear();
|
||||
_ordered_materials.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::extract_materials
|
||||
// Access: Public
|
||||
// Description: Walks the egg hierarchy beginning at the indicated
|
||||
// node, and removes any EggMaterials encountered in the
|
||||
// hierarchy, adding them to the collection. Returns
|
||||
// the number of EggMaterials encountered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggMaterialCollection::
|
||||
extract_materials(EggGroupNode *node) {
|
||||
// Since this traversal is destructive, we'll handle it within the
|
||||
// EggGroupNode code.
|
||||
return node->find_materials(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::insert_materials
|
||||
// Access: Public
|
||||
// Description: Adds a series of EggMaterial nodes to the beginning of
|
||||
// the indicated node to reflect each of the materials in
|
||||
// the collection. Returns the number of material nodes
|
||||
// added.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggMaterialCollection::
|
||||
insert_materials(EggGroupNode *node) {
|
||||
return insert_materials(node, node->begin());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::insert_materials
|
||||
// Access: Public
|
||||
// Description: Adds a series of EggMaterial nodes to the beginning of
|
||||
// the indicated node to reflect each of the materials in
|
||||
// the collection. Returns the number of material nodes
|
||||
// added.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggMaterialCollection::
|
||||
insert_materials(EggGroupNode *node, EggGroupNode::iterator position) {
|
||||
OrderedMaterials::iterator oti;
|
||||
for (oti = _ordered_materials.begin();
|
||||
oti != _ordered_materials.end();
|
||||
++oti) {
|
||||
node->insert(position, (*oti).p());
|
||||
}
|
||||
|
||||
return size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::find_used_materials
|
||||
// Access: Public
|
||||
// Description: Walks the egg hierarchy beginning at the indicated
|
||||
// node, looking for materials that are referenced by
|
||||
// primitives but are not already members of the
|
||||
// collection, adding them to the collection.
|
||||
//
|
||||
// If this is called following extract_materials(), it
|
||||
// can be used to pick up any additional material
|
||||
// references that appeared in the egg hierarchy (but
|
||||
// whose EggMaterial node was not actually part of the
|
||||
// hierarchy).
|
||||
//
|
||||
// If this is called in lieu of extract_materials(), it
|
||||
// will fill up the collection with all of the
|
||||
// referenced materials (and only the referenced
|
||||
// materials), without destructively removing the
|
||||
// EggMaterials from the hierarchy.
|
||||
//
|
||||
// This also has the side effect of incrementing the
|
||||
// internal usage count for a material in the collection
|
||||
// each time a material reference is encountered. This
|
||||
// side effect is taken advantage of by
|
||||
// remove_unused_materials().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggMaterialCollection::
|
||||
find_used_materials(EggNode *node) {
|
||||
int num_found = 0;
|
||||
|
||||
if (node->is_of_type(EggPrimitive::get_class_type())) {
|
||||
EggPrimitive *primitive = DCAST(EggPrimitive, node);
|
||||
if (primitive->has_material()) {
|
||||
EggMaterial *tex = primitive->get_material();
|
||||
Materials::iterator ti = _materials.find(tex);
|
||||
if (ti == _materials.end()) {
|
||||
// Here's a new material!
|
||||
num_found++;
|
||||
_materials.insert(Materials::value_type(tex, 1));
|
||||
_ordered_materials.push_back(tex);
|
||||
} else {
|
||||
// Here's a material we'd already known about. Increment its
|
||||
// usage count.
|
||||
(*ti).second++;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (node->is_of_type(EggGroupNode::get_class_type())) {
|
||||
EggGroupNode *group = DCAST(EggGroupNode, node);
|
||||
|
||||
EggGroupNode::iterator ci;
|
||||
for (ci = group->begin(); ci != group->end(); ++ci) {
|
||||
EggNode *child = *ci;
|
||||
|
||||
num_found += find_used_materials(child);
|
||||
}
|
||||
}
|
||||
|
||||
return num_found;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::remove_unused_materials
|
||||
// Access: Public
|
||||
// Description: Removes any materials from the collection that aren't
|
||||
// referenced by any primitives in the indicated egg
|
||||
// hierarchy. This also, incidentally, adds materials to
|
||||
// the collection that had been referenced by primitives
|
||||
// but had not previously appeared in the collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMaterialCollection::
|
||||
remove_unused_materials(EggNode *node) {
|
||||
// We'll do this the easy way: First, we'll remove *all* the
|
||||
// materials from the collection, and then we'll add back only those
|
||||
// that appear in the hierarchy.
|
||||
clear();
|
||||
find_used_materials(node);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::collapse_equivalent_materials
|
||||
// Access: Public
|
||||
// Description: Walks through the collection and collapses together
|
||||
// any separate materials that are equivalent according
|
||||
// to the indicated equivalence factor, eq (see
|
||||
// EggMaterial::is_equivalent_to()). The return value is
|
||||
// the number of materials removed.
|
||||
//
|
||||
// This flavor of collapse_equivalent_materials()
|
||||
// automatically adjusts all the primitives in the egg
|
||||
// hierarchy to refer to the new material pointers.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggMaterialCollection::
|
||||
collapse_equivalent_materials(int eq, EggGroupNode *node) {
|
||||
MaterialReplacement removed;
|
||||
int num_collapsed = collapse_equivalent_materials(eq, removed);
|
||||
|
||||
// And now walk the egg hierarchy and replace any references to a
|
||||
// removed material with its replacement.
|
||||
replace_materials(node, removed);
|
||||
|
||||
return num_collapsed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::collapse_equivalent_materials
|
||||
// Access: Public
|
||||
// Description: Walks through the collection and collapses together
|
||||
// any separate materials that are equivalent according
|
||||
// to the indicated equivalence factor, eq (see
|
||||
// EggMaterial::is_equivalent_to()). The return value is
|
||||
// the number of materials removed.
|
||||
//
|
||||
// This flavor of collapse_equivalent_materials() does
|
||||
// not adjust any primitives in the egg hierarchy;
|
||||
// instead, it fills up the 'removed' map with an entry
|
||||
// for each removed material, mapping it back to the
|
||||
// equivalent retained material. It's up to the user to
|
||||
// then call replace_materials() with this map, if
|
||||
// desired, to apply these changes to the egg hierarchy.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggMaterialCollection::
|
||||
collapse_equivalent_materials(int eq, EggMaterialCollection::MaterialReplacement &removed) {
|
||||
int num_collapsed = 0;
|
||||
|
||||
typedef set<PT(EggMaterial), UniqueEggMaterials> Collapser;
|
||||
UniqueEggMaterials uet(eq);
|
||||
Collapser collapser(uet);
|
||||
|
||||
// First, put all of the materials into the Collapser structure, to
|
||||
// find out the unique materials.
|
||||
OrderedMaterials::const_iterator oti;
|
||||
for (oti = _ordered_materials.begin();
|
||||
oti != _ordered_materials.end();
|
||||
++oti) {
|
||||
EggMaterial *tex = (*oti);
|
||||
|
||||
pair<Collapser::const_iterator, bool> result = collapser.insert(tex);
|
||||
if (!result.second) {
|
||||
// This material is non-unique; another one was already there.
|
||||
EggMaterial *first = *(result.first);
|
||||
removed.insert(MaterialReplacement::value_type(tex, first));
|
||||
num_collapsed++;
|
||||
}
|
||||
}
|
||||
|
||||
// Now record all of the unique materials only.
|
||||
clear();
|
||||
Collapser::const_iterator ci;
|
||||
for (ci = collapser.begin(); ci != collapser.end(); ++ci) {
|
||||
add_material(*ci);
|
||||
}
|
||||
|
||||
return num_collapsed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::replace_materials
|
||||
// Access: Public, Static
|
||||
// Description: Walks the egg hierarchy, changing out any reference
|
||||
// to a material appearing on the left side of the map
|
||||
// with its corresponding material on the right side.
|
||||
// This is most often done following a call to
|
||||
// collapse_equivalent_materials(). It does not directly
|
||||
// affect the Collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMaterialCollection::
|
||||
replace_materials(EggGroupNode *node,
|
||||
const EggMaterialCollection::MaterialReplacement &replace) {
|
||||
EggGroupNode::iterator ci;
|
||||
for (ci = node->begin();
|
||||
ci != node->end();
|
||||
++ci) {
|
||||
EggNode *child = *ci;
|
||||
if (child->is_of_type(EggPrimitive::get_class_type())) {
|
||||
EggPrimitive *primitive = DCAST(EggPrimitive, child);
|
||||
if (primitive->has_material()) {
|
||||
PT(EggMaterial) tex = primitive->get_material();
|
||||
MaterialReplacement::const_iterator ri;
|
||||
ri = replace.find(tex);
|
||||
if (ri != replace.end()) {
|
||||
// Here's a material we want to replace.
|
||||
primitive->set_material((*ri).second);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (child->is_of_type(EggGroupNode::get_class_type())) {
|
||||
EggGroupNode *group_child = DCAST(EggGroupNode, child);
|
||||
replace_materials(group_child, replace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::uniquify_mrefs
|
||||
// Access: Public
|
||||
// Description: Guarantees that each material in the collection has a
|
||||
// unique MRef name. This is essential before writing
|
||||
// an egg file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMaterialCollection::
|
||||
uniquify_mrefs() {
|
||||
NameUniquifier nu(".mref", "mref");
|
||||
|
||||
OrderedMaterials::const_iterator oti;
|
||||
for (oti = _ordered_materials.begin();
|
||||
oti != _ordered_materials.end();
|
||||
++oti) {
|
||||
EggMaterial *tex = (*oti);
|
||||
|
||||
tex->set_name(nu.add_name(tex->get_name()));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::sort_by_mref
|
||||
// Access: Public
|
||||
// Description: Sorts all the materials into alphabetical order by
|
||||
// MRef name. Subsequent operations using begin()/end()
|
||||
// will traverse in this sorted order.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMaterialCollection::
|
||||
sort_by_mref() {
|
||||
sort(_ordered_materials.begin(), _ordered_materials.end(),
|
||||
NamableOrderByName());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::add_material
|
||||
// Access: Public
|
||||
// Description: Explicitly adds a new material to the collection.
|
||||
// Returns true if the material was added, false if it
|
||||
// was already there or if there was some error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggMaterialCollection::
|
||||
add_material(EggMaterial *material) {
|
||||
nassertr(_materials.size() == _ordered_materials.size(), false);
|
||||
|
||||
PT(EggMaterial) new_tex = material;
|
||||
|
||||
Materials::const_iterator ti;
|
||||
ti = _materials.find(new_tex);
|
||||
if (ti != _materials.end()) {
|
||||
// This material is already a member of the collection.
|
||||
return false;
|
||||
}
|
||||
|
||||
_materials.insert(Materials::value_type(new_tex, 0));
|
||||
_ordered_materials.push_back(new_tex);
|
||||
|
||||
nassertr(_materials.size() == _ordered_materials.size(), false);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::remove_material
|
||||
// Access: Public
|
||||
// Description: Explicitly removes a material from the collection.
|
||||
// Returns true if the material was removed, false if it
|
||||
// wasn't there or if there was some error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggMaterialCollection::
|
||||
remove_material(EggMaterial *material) {
|
||||
nassertr(_materials.size() == _ordered_materials.size(), false);
|
||||
|
||||
Materials::iterator ti;
|
||||
ti = _materials.find(material);
|
||||
if (ti == _materials.end()) {
|
||||
// This material is not a member of the collection.
|
||||
return false;
|
||||
}
|
||||
|
||||
_materials.erase(ti);
|
||||
|
||||
OrderedMaterials::iterator oti;
|
||||
PT(EggMaterial) ptex = material;
|
||||
oti = find(_ordered_materials.begin(), _ordered_materials.end(), ptex);
|
||||
nassertr(oti != _ordered_materials.end(), false);
|
||||
|
||||
_ordered_materials.erase(oti);
|
||||
|
||||
nassertr(_materials.size() == _ordered_materials.size(), false);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::create_unique_material
|
||||
// Access: Public
|
||||
// Description: Creates a new material if there is not already one
|
||||
// equivalent (according to eq, see
|
||||
// EggMaterial::is_equivalent_to()) to the indicated
|
||||
// material, or returns the existing one if there is.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggMaterial *EggMaterialCollection::
|
||||
create_unique_material(const EggMaterial ©, int eq) {
|
||||
// This requires a complete linear traversal, not terribly
|
||||
// efficient.
|
||||
OrderedMaterials::const_iterator oti;
|
||||
for (oti = _ordered_materials.begin();
|
||||
oti != _ordered_materials.end();
|
||||
++oti) {
|
||||
EggMaterial *tex = (*oti);
|
||||
if (copy.is_equivalent_to(*tex, eq)) {
|
||||
return tex;
|
||||
}
|
||||
}
|
||||
|
||||
EggMaterial *new_material = new EggMaterial(copy);
|
||||
add_material(new_material);
|
||||
return new_material;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMaterialCollection::find_mref
|
||||
// Access: Public
|
||||
// Description: Returns the material with the indicated MRef name, or
|
||||
// NULL if no material matches.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggMaterial *EggMaterialCollection::
|
||||
find_mref(const string &mref_name) const {
|
||||
// This requires a complete linear traversal, not terribly
|
||||
// efficient.
|
||||
OrderedMaterials::const_iterator oti;
|
||||
for (oti = _ordered_materials.begin();
|
||||
oti != _ordered_materials.end();
|
||||
++oti) {
|
||||
EggMaterial *tex = (*oti);
|
||||
if (tex->get_name() == mref_name) {
|
||||
return tex;
|
||||
}
|
||||
}
|
||||
|
||||
return (EggMaterial *)NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
// Filename: eggMaterialCollection.h
|
||||
// Created by: drose (30Apr01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EGGMATERIALCOLLECTION_H
|
||||
#define EGGMATERIALCOLLECTION_H
|
||||
|
||||
#include <pandabase.h>
|
||||
|
||||
#include "eggMaterial.h"
|
||||
#include "eggGroupNode.h"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : EggMaterialCollection
|
||||
// Description : This is a collection of materials by MRef name. It
|
||||
// can extract the materials from an egg file and sort
|
||||
// them all together; it can also manage the creation of
|
||||
// unique materials and the assignment of unique MRef
|
||||
// names.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEGG EggMaterialCollection {
|
||||
|
||||
// This is a bit of private interface stuff that must be here as a
|
||||
// forward reference. This allows us to define the
|
||||
// EggMaterialCollection as an STL container.
|
||||
|
||||
private:
|
||||
typedef map<PT(EggMaterial), int> Materials;
|
||||
typedef vector< PT(EggMaterial) > OrderedMaterials;
|
||||
|
||||
public:
|
||||
typedef OrderedMaterials::const_iterator iterator;
|
||||
typedef iterator const_iterator;
|
||||
typedef OrderedMaterials::size_type size_type;
|
||||
|
||||
typedef map<PT(EggMaterial), PT(EggMaterial) > MaterialReplacement;
|
||||
|
||||
// Here begins the actual public interface to EggMaterialCollection.
|
||||
|
||||
public:
|
||||
EggMaterialCollection();
|
||||
EggMaterialCollection(const EggMaterialCollection ©);
|
||||
EggMaterialCollection &operator = (const EggMaterialCollection ©);
|
||||
|
||||
void clear();
|
||||
|
||||
int extract_materials(EggGroupNode *node);
|
||||
int insert_materials(EggGroupNode *node);
|
||||
int insert_materials(EggGroupNode *node, EggGroupNode::iterator position);
|
||||
|
||||
int find_used_materials(EggNode *node);
|
||||
void remove_unused_materials(EggNode *node);
|
||||
|
||||
int collapse_equivalent_materials(int eq, EggGroupNode *node);
|
||||
int collapse_equivalent_materials(int eq, MaterialReplacement &removed);
|
||||
static void replace_materials(EggGroupNode *node,
|
||||
const MaterialReplacement &replace);
|
||||
|
||||
void uniquify_mrefs();
|
||||
void sort_by_mref();
|
||||
|
||||
// Can be used to traverse all the materials in the collection, in
|
||||
// order as last sorted.
|
||||
INLINE iterator begin() const;
|
||||
INLINE iterator end() const;
|
||||
INLINE bool empty() const;
|
||||
INLINE size_type size() const;
|
||||
|
||||
bool add_material(EggMaterial *material);
|
||||
bool remove_material(EggMaterial *material);
|
||||
|
||||
// create_unique_material() creates a new material if there is not
|
||||
// already one equivalent (according to eq, see
|
||||
// EggMaterial::is_equivalent_to()) to the indicated material, or
|
||||
// returns the existing one if there is.
|
||||
EggMaterial *create_unique_material(const EggMaterial ©, int eq);
|
||||
|
||||
// Find a material with a particular MRef name.
|
||||
EggMaterial *find_mref(const string &mref_name) const;
|
||||
|
||||
private:
|
||||
Materials _materials;
|
||||
OrderedMaterials _ordered_materials;
|
||||
};
|
||||
|
||||
#include "eggMaterialCollection.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -196,17 +196,17 @@ is_equivalent_to(const EggTexture &other, int eq) const {
|
|||
|
||||
if (eq & E_basename) {
|
||||
if (a.get_basename_wo_extension() != b.get_basename_wo_extension()) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (eq & E_extension) {
|
||||
if (a.get_extension() != b.get_extension()) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (eq & E_dirname) {
|
||||
if (a.get_dirname() != b.get_dirname()) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -218,21 +218,21 @@ is_equivalent_to(const EggTexture &other, int eq) const {
|
|||
|
||||
if (has_transform() && other.has_transform()) {
|
||||
if (!_transform.almost_equal(other._transform, 0.0001)) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (eq & E_attributes) {
|
||||
if (_format != other._format ||
|
||||
_wrap_mode != other._wrap_mode ||
|
||||
_wrap_u != other._wrap_u ||
|
||||
_wrap_v != other._wrap_v ||
|
||||
_minfilter != other._minfilter ||
|
||||
_magfilter != other._magfilter ||
|
||||
_magfilteralpha != other._magfilteralpha ||
|
||||
_magfiltercolor != other._magfiltercolor ||
|
||||
_env_type != other._env_type) {
|
||||
_wrap_mode != other._wrap_mode ||
|
||||
_wrap_u != other._wrap_u ||
|
||||
_wrap_v != other._wrap_v ||
|
||||
_minfilter != other._minfilter ||
|
||||
_magfilter != other._magfilter ||
|
||||
_magfilteralpha != other._magfilteralpha ||
|
||||
_magfiltercolor != other._magfiltercolor ||
|
||||
_env_type != other._env_type) {
|
||||
return false;
|
||||
}
|
||||
if (EggRenderMode::operator != (other)) {
|
||||
|
|
@ -270,17 +270,17 @@ sorts_less_than(const EggTexture &other, int eq) const {
|
|||
|
||||
if (eq & E_basename) {
|
||||
if (a.get_basename_wo_extension() != b.get_basename_wo_extension()) {
|
||||
return a.get_basename_wo_extension() < b.get_basename_wo_extension();
|
||||
return a.get_basename_wo_extension() < b.get_basename_wo_extension();
|
||||
}
|
||||
}
|
||||
if (eq & E_extension) {
|
||||
if (a.get_extension() != b.get_extension()) {
|
||||
return a.get_extension() < b.get_extension();
|
||||
return a.get_extension() < b.get_extension();
|
||||
}
|
||||
}
|
||||
if (eq & E_dirname) {
|
||||
if (a.get_dirname() != b.get_dirname()) {
|
||||
return a.get_dirname() < b.get_dirname();
|
||||
return a.get_dirname() < b.get_dirname();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ private:
|
|||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : UniqueEggTextures
|
||||
// Class : UniqueEggTextures
|
||||
// Description : An STL function object for sorting textures into
|
||||
// order by properties. Returns true if the two
|
||||
// referenced EggTexture pointers are in sorted order,
|
||||
|
|
@ -179,16 +179,6 @@ public:
|
|||
int _eq;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : TRefEggTextures
|
||||
// Description : An STL function object for sorting textures into
|
||||
// order by TRef name.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEGG TRefEggTextures {
|
||||
public:
|
||||
INLINE bool operator ()(const EggTexture *t1, const EggTexture *t2) const;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const EggTexture &n) {
|
||||
return out << n.get_filename();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -516,6 +516,12 @@ material_body:
|
|||
spec[2] = value;
|
||||
material->set_spec(spec);
|
||||
|
||||
} else if (cmp_nocase_uh(name, "shininess") == 0) {
|
||||
material->set_shininess(value);
|
||||
|
||||
} else if (cmp_nocase_uh(name, "local") == 0) {
|
||||
material->set_local(value != 0.0);
|
||||
|
||||
} else {
|
||||
eggyywarning("Unsupported material scalar: " + name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@
|
|||
#include <builderVertex.h>
|
||||
#include <texturePool.h>
|
||||
#include <textureTransition.h>
|
||||
#include <material.h>
|
||||
#include <materialPool.h>
|
||||
#include <materialTransition.h>
|
||||
#include <transformTransition.h>
|
||||
#include <transparencyTransition.h>
|
||||
#include <cullFaceTransition.h>
|
||||
|
|
@ -862,6 +865,65 @@ apply_texture_apply_attributes(TextureApplyTransition *apply,
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggLoader::get_material_transition
|
||||
// Access: Private
|
||||
// Description: Returns a transition suitable for enabling the
|
||||
// material indicated by the given EggMaterial, and with
|
||||
// the indicated backface flag.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MaterialTransition *EggLoader::
|
||||
get_material_transition(const EggMaterial *egg_mat, bool bface) {
|
||||
Materials &materials = bface ? _materials_bface : _materials;
|
||||
|
||||
// First, check whether we've seen this material before.
|
||||
Materials::const_iterator mi;
|
||||
mi = materials.find(egg_mat);
|
||||
if (mi != materials.end()) {
|
||||
return (*mi).second;
|
||||
}
|
||||
|
||||
// Ok, this is the first time we've seen this particular
|
||||
// EggMaterial. Create a new Material that matches it.
|
||||
PT(Material) mat = new Material;
|
||||
if (egg_mat->has_diff()) {
|
||||
RGBColorf diff = egg_mat->get_diff();
|
||||
mat->set_diffuse(Colorf(diff[0], diff[1], diff[2], 1.0));
|
||||
// By default, ambient is the same as diffuse, if diffuse is
|
||||
// specified but ambient is not.
|
||||
mat->set_ambient(Colorf(diff[0], diff[1], diff[2], 1.0));
|
||||
}
|
||||
if (egg_mat->has_amb()) {
|
||||
RGBColorf amb = egg_mat->get_amb();
|
||||
mat->set_ambient(Colorf(amb[0], amb[1], amb[2], 1.0));
|
||||
}
|
||||
if (egg_mat->has_emit()) {
|
||||
RGBColorf emit = egg_mat->get_emit();
|
||||
mat->set_emission(Colorf(emit[0], emit[1], emit[2], 1.0));
|
||||
}
|
||||
if (egg_mat->has_spec()) {
|
||||
RGBColorf spec = egg_mat->get_spec();
|
||||
mat->set_specular(Colorf(spec[0], spec[1], spec[2], 1.0));
|
||||
}
|
||||
if (egg_mat->has_shininess()) {
|
||||
mat->set_shininess(egg_mat->get_shininess());
|
||||
}
|
||||
if (egg_mat->has_local()) {
|
||||
mat->set_local(egg_mat->get_local());
|
||||
}
|
||||
|
||||
mat->set_twoside(bface);
|
||||
|
||||
// Now get a global Material pointer, shared with other models.
|
||||
const Material *shared_mat = MaterialPool::get_material(mat);
|
||||
|
||||
// And create a MaterialTransition for this Material.
|
||||
PT(MaterialTransition) mt = new MaterialTransition(shared_mat);
|
||||
materials.insert(Materials::value_type(egg_mat, mt));
|
||||
|
||||
return mt;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggLoader::setup_bucket
|
||||
|
|
@ -957,6 +1019,13 @@ setup_bucket(BuilderBucket &bucket, NamedNode *parent,
|
|||
}
|
||||
}
|
||||
|
||||
if (egg_prim->has_material()) {
|
||||
MaterialTransition *mt = get_material_transition(egg_prim->get_material(),
|
||||
egg_prim->get_bface_flag());
|
||||
bucket._trans.set_transition(mt);
|
||||
}
|
||||
|
||||
|
||||
// Also check the color of the primitive to see if we should assume
|
||||
// alpha based on the alpha values specified in the egg file.
|
||||
if (am == EggRenderMode::AM_unspecified) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <eggData.h>
|
||||
#include <eggTexture.h>
|
||||
#include <eggGroup.h>
|
||||
#include <eggMaterial.h>
|
||||
#include <texture.h>
|
||||
#include <namedNode.h>
|
||||
#include <pt_NamedNode.h>
|
||||
|
|
@ -22,6 +23,7 @@
|
|||
#include <indirectCompareTo.h>
|
||||
#include <textureTransition.h>
|
||||
#include <textureApplyTransition.h>
|
||||
#include <materialTransition.h>
|
||||
|
||||
class EggNode;
|
||||
class EggBin;
|
||||
|
|
@ -29,6 +31,7 @@ class EggTable;
|
|||
class EggNurbsCurve;
|
||||
class EggPrimitive;
|
||||
class EggPolygon;
|
||||
class EggMaterial;
|
||||
class ComputedVerticesMaker;
|
||||
class RenderRelation;
|
||||
class CollisionSolid;
|
||||
|
|
@ -73,6 +76,9 @@ private:
|
|||
void apply_texture_apply_attributes(TextureApplyTransition *apply,
|
||||
const EggTexture *egg_tex);
|
||||
|
||||
MaterialTransition *get_material_transition(const EggMaterial *egg_mat,
|
||||
bool bface);
|
||||
|
||||
void setup_bucket(BuilderBucket &bucket, NamedNode *parent,
|
||||
EggPrimitive *egg_prim);
|
||||
|
||||
|
|
@ -116,6 +122,10 @@ private:
|
|||
typedef map<PT(EggTexture), TextureDef> Textures;
|
||||
Textures _textures;
|
||||
|
||||
typedef map<CPT(EggMaterial), PT(MaterialTransition) > Materials;
|
||||
Materials _materials;
|
||||
Materials _materials_bface;
|
||||
|
||||
typedef set<RenderRelation *> Decals;
|
||||
Decals _decals;
|
||||
|
||||
|
|
|
|||
|
|
@ -1159,3 +1159,20 @@ INLINE const float &GLGraphicsStateGuardian::
|
|||
get_current_alpha_scale() const {
|
||||
return _current_alpha_scale;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::report_errors
|
||||
// Access: Protected
|
||||
// Description: Checks for any outstanding error codes and outputs
|
||||
// them, if found. If NDEBUG is defined, this function
|
||||
// does nothing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GLGraphicsStateGuardian::
|
||||
report_errors() const {
|
||||
#ifndef NDEBUG
|
||||
GLenum error_code = glGetError();
|
||||
if (error_code != GL_NO_ERROR) {
|
||||
report_errors_loop(error_code);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -466,6 +466,7 @@ render_frame(const AllAttributesWrapper &initial_state) {
|
|||
#endif
|
||||
|
||||
_win->begin_frame();
|
||||
report_errors();
|
||||
_decal_level = 0;
|
||||
|
||||
if (_clear_buffer_type != 0) {
|
||||
|
|
@ -539,6 +540,7 @@ render_frame(const AllAttributesWrapper &initial_state) {
|
|||
// more aware of whether their parameters or positions have changed
|
||||
// at all?
|
||||
|
||||
report_errors();
|
||||
_win->end_frame();
|
||||
|
||||
#ifdef GSG_VERBOSE
|
||||
|
|
@ -740,6 +742,7 @@ draw_point(const GeomPoint *geom) {
|
|||
}
|
||||
|
||||
glEnd();
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -799,6 +802,7 @@ draw_line(const GeomLine* geom) {
|
|||
}
|
||||
|
||||
glEnd();
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -876,6 +880,7 @@ draw_linestrip(const GeomLinestrip* geom) {
|
|||
}
|
||||
glEnd();
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1181,6 +1186,7 @@ draw_sprite(const GeomSprite *geom) {
|
|||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(_current_projection_mat.get_data());
|
||||
#endif
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1252,6 +1258,7 @@ draw_polygon(const GeomPolygon *geom) {
|
|||
}
|
||||
glEnd();
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1318,6 +1325,7 @@ draw_tri(const GeomTri *geom) {
|
|||
}
|
||||
|
||||
glEnd();
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1384,6 +1392,7 @@ draw_quad(const GeomQuad *geom) {
|
|||
}
|
||||
|
||||
glEnd();
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1472,6 +1481,7 @@ draw_tristrip(const GeomTristrip *geom) {
|
|||
}
|
||||
glEnd();
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1560,6 +1570,7 @@ draw_trifan(const GeomTrifan *geom) {
|
|||
}
|
||||
glEnd();
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1639,6 +1650,7 @@ draw_sphere(const GeomSphere *geom) {
|
|||
}
|
||||
|
||||
gluDeleteQuadric(sph);
|
||||
report_errors();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1669,7 +1681,8 @@ prepare_texture(Texture *tex) {
|
|||
// which shouldn't be possible, since the texture itself should
|
||||
// detect this.
|
||||
nassertr(inserted, NULL);
|
||||
|
||||
|
||||
report_errors();
|
||||
return gtc;
|
||||
}
|
||||
|
||||
|
|
@ -1689,6 +1702,7 @@ apply_texture(TextureContext *tc) {
|
|||
specify_texture(tex);
|
||||
apply_texture_immediate(tex);
|
||||
*/
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1715,6 +1729,7 @@ release_texture(TextureContext *tc) {
|
|||
tex->clear_gsg(this);
|
||||
|
||||
delete gtc;
|
||||
report_errors();
|
||||
}
|
||||
|
||||
static int logs[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
|
||||
|
|
@ -1898,6 +1913,7 @@ texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb) {
|
|||
texture_to_pixel_buffer(tc, pb, dr);
|
||||
|
||||
pop_frame_buffer(old_fb);
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1925,6 +1941,7 @@ texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb,
|
|||
pb->_image = PTA_uchar(w * h * pb->get_num_components());
|
||||
copy_pixel_buffer(pb, dr);
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1994,6 +2011,7 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
|||
pb->_image.p() );
|
||||
|
||||
nassertv(!pb->_image.empty());
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2131,6 +2149,7 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
|||
glPopMatrix();
|
||||
|
||||
pop_display_region(old_dr);
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2188,6 +2207,7 @@ void GLGraphicsStateGuardian::apply_material(const Material *material) {
|
|||
|
||||
call_glLightModelLocal(material->get_local());
|
||||
call_glLightModelTwoSide(material->get_twoside());
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2211,6 +2231,7 @@ apply_fog(Fog *fog) {
|
|||
break;
|
||||
}
|
||||
call_glFogColor(fog->get_color());
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2270,6 +2291,7 @@ void GLGraphicsStateGuardian::apply_light( PointLight* light )
|
|||
glgsg_cat.debug()
|
||||
<< "glPopMatrix()" << endl;
|
||||
#endif
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2327,6 +2349,7 @@ void GLGraphicsStateGuardian::apply_light( DirectionalLight* light )
|
|||
glgsg_cat.debug()
|
||||
<< "glPopMatrix()" << endl;
|
||||
#endif
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2382,6 +2405,7 @@ void GLGraphicsStateGuardian::apply_light( Spotlight* light )
|
|||
glgsg_cat.debug()
|
||||
<< "glPopMatrix()" << endl;
|
||||
#endif
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2438,6 +2462,7 @@ issue_transform(const TransformAttribute *attrib) {
|
|||
enable_texturing(texturing_was_enabled);
|
||||
}
|
||||
#endif
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2489,6 +2514,7 @@ issue_tex_matrix(const TexMatrixAttribute *attrib) {
|
|||
#endif
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf(attrib->get_matrix().get_data());
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2503,6 +2529,7 @@ issue_color(const ColorAttribute *attrib) {
|
|||
const Colorf c = attrib->get_color();
|
||||
glColor4f(c[0], c[1], c[2], c[3]);
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2522,6 +2549,7 @@ issue_texture(const TextureAttribute *attrib) {
|
|||
} else {
|
||||
enable_texturing(false);
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2574,6 +2602,7 @@ issue_tex_gen(const TexGenAttribute *attrib) {
|
|||
<< "Unknown texgen mode " << (int)mode << endl;
|
||||
break;
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2589,6 +2618,7 @@ issue_material(const MaterialAttribute *attrib) {
|
|||
nassertv(material != (const Material *)NULL);
|
||||
apply_material(material);
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2608,6 +2638,7 @@ issue_fog(const FogAttribute *attrib) {
|
|||
} else {
|
||||
enable_fog(false);
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2636,6 +2667,7 @@ issue_render_mode(const RenderModeAttribute *attrib) {
|
|||
glgsg_cat.error()
|
||||
<< "Unknown render mode " << (int)mode << endl;
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2732,6 +2764,7 @@ void GLGraphicsStateGuardian::issue_light(const LightAttribute *attrib )
|
|||
} else {
|
||||
call_glLightModelAmbient(_cur_ambient_light);
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2769,6 +2802,7 @@ issue_color_blend(const ColorBlendAttribute *attrib) {
|
|||
<< "Unknown color blend mode " << (int)mode << endl;
|
||||
break;
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2781,6 +2815,7 @@ issue_texture_apply(const TextureApplyAttribute *attrib) {
|
|||
// activate();
|
||||
GLint glmode = get_texture_apply_mode_type(attrib->get_mode());
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, glmode);
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2792,9 +2827,10 @@ void GLGraphicsStateGuardian::
|
|||
issue_color_mask(const ColorMaskAttribute *attrib) {
|
||||
// activate();
|
||||
glColorMask(attrib->is_write_r(),
|
||||
attrib->is_write_g(),
|
||||
attrib->is_write_b(),
|
||||
attrib->is_write_a());
|
||||
attrib->is_write_g(),
|
||||
attrib->is_write_b(),
|
||||
attrib->is_write_a());
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2813,6 +2849,7 @@ issue_depth_test(const DepthTestAttribute *attrib) {
|
|||
enable_depth_test(true);
|
||||
glDepthFunc(get_depth_func_type(mode));
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2825,6 +2862,7 @@ issue_depth_write(const DepthWriteAttribute *attrib) {
|
|||
// activate();
|
||||
|
||||
call_glDepthMask(attrib->is_on());
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2845,6 +2883,7 @@ issue_stencil(const StencilAttribute *attrib) {
|
|||
call_glStencilFunc(get_stencil_func_type(mode));
|
||||
call_glStencilOp(get_stencil_action_type(attrib->get_action()));
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2879,6 +2918,7 @@ issue_cull_face(const CullFaceAttribute *attrib) {
|
|||
<< "invalid cull face mode " << (int)mode << endl;
|
||||
break;
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2967,6 +3007,7 @@ issue_clip_plane(const ClipPlaneAttribute *attrib)
|
|||
if (_cur_clip_plane_enabled[i] == false)
|
||||
enable_clip_plane(i, false);
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3027,6 +3068,7 @@ issue_transparency(const TransparencyAttribute *attrib )
|
|||
<< "invalid transparency mode " << (int)mode << endl;
|
||||
break;
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3038,6 +3080,7 @@ void GLGraphicsStateGuardian::
|
|||
issue_linesmooth(const LinesmoothAttribute *attrib) {
|
||||
// activate();
|
||||
enable_line_smooth(attrib->is_on());
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3053,6 +3096,7 @@ issue_point_shape(const PointShapeAttribute *attrib) {
|
|||
glDisable(GL_POINT_SMOOTH);
|
||||
else
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3080,6 +3124,7 @@ issue_polygon_offset(const PolygonOffsetAttribute *attrib) {
|
|||
{
|
||||
enable_polygon_offset(false);
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3180,6 +3225,7 @@ begin_decal(GeomNode *base_geom) {
|
|||
// buffer write off during this.
|
||||
}
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3279,6 +3325,7 @@ end_decal(GeomNode *base_geom) {
|
|||
enable_texturing(was_textured);
|
||||
}
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3299,6 +3346,24 @@ compute_distance_to(const LPoint3f &point) const {
|
|||
return -point[2];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::report_errors_loop
|
||||
// Access: Protected
|
||||
// Description: The internal implementation of report_errors().
|
||||
// Don't call this function; use report_errors()
|
||||
// instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GLGraphicsStateGuardian::
|
||||
report_errors_loop(GLenum error_code) const {
|
||||
#ifndef NDEBUG
|
||||
while (error_code != GL_NO_ERROR) {
|
||||
glgsg_cat.error()
|
||||
<< gluErrorString(error_code) << "\n";
|
||||
error_code = glGetError();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::set_draw_buffer
|
||||
// Access: Protected
|
||||
|
|
@ -3345,6 +3410,7 @@ set_draw_buffer(const RenderBuffer &rb) {
|
|||
default:
|
||||
call_glDrawBuffer(GL_FRONT_AND_BACK);
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3393,6 +3459,7 @@ set_read_buffer(const RenderBuffer &rb) {
|
|||
default:
|
||||
call_glReadBuffer(GL_FRONT_AND_BACK);
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3413,6 +3480,7 @@ bind_texture(TextureContext *tc) {
|
|||
<< ")" << endl;
|
||||
#endif
|
||||
glBindTexture(GL_TEXTURE_2D, gtc->_index);
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3438,6 +3506,7 @@ specify_texture(Texture *tex) {
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||
get_texture_filter_type(tex->get_magfilter()));
|
||||
}
|
||||
report_errors();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3494,6 +3563,7 @@ apply_texture_immediate(Texture *tex) {
|
|||
glTexImage2D( GL_TEXTURE_2D, 0, internal_format,
|
||||
pb->get_xsize(), pb->get_ysize(), pb->get_border(),
|
||||
external_format, type, pb->_image );
|
||||
report_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3688,17 +3758,16 @@ get_internal_image_format(PixelBuffer::Format format) {
|
|||
GLint GLGraphicsStateGuardian::
|
||||
get_texture_apply_mode_type( TextureApplyProperty::Mode am ) const
|
||||
{
|
||||
switch( am )
|
||||
{
|
||||
case TextureApplyProperty::M_modulate: return GL_MODULATE;
|
||||
case TextureApplyProperty::M_decal: return GL_DECAL;
|
||||
case TextureApplyProperty::M_blend: return GL_BLEND;
|
||||
case TextureApplyProperty::M_replace: return GL_REPLACE;
|
||||
case TextureApplyProperty::M_add: return GL_ADD;
|
||||
}
|
||||
glgsg_cat.error()
|
||||
<< "Invalid TextureApplyProperty::Mode value" << endl;
|
||||
return GL_MODULATE;
|
||||
switch( am ) {
|
||||
case TextureApplyProperty::M_modulate: return GL_MODULATE;
|
||||
case TextureApplyProperty::M_decal: return GL_DECAL;
|
||||
case TextureApplyProperty::M_blend: return GL_BLEND;
|
||||
case TextureApplyProperty::M_replace: return GL_REPLACE;
|
||||
case TextureApplyProperty::M_add: return GL_ADD;
|
||||
}
|
||||
glgsg_cat.error()
|
||||
<< "Invalid TextureApplyProperty::Mode value" << endl;
|
||||
return GL_MODULATE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -222,6 +222,9 @@ protected:
|
|||
INLINE GLenum get_light_id(int index) const;
|
||||
INLINE GLenum get_clip_plane_id(int index) const;
|
||||
|
||||
INLINE void report_errors() const;
|
||||
void report_errors_loop(GLenum error_code) const;
|
||||
|
||||
void set_draw_buffer(const RenderBuffer &rb);
|
||||
void set_read_buffer(const RenderBuffer &rb);
|
||||
|
||||
|
|
|
|||
|
|
@ -285,7 +285,11 @@ get_local() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void Material::
|
||||
set_local(bool local) {
|
||||
_flags |= F_local;
|
||||
if (local) {
|
||||
_flags |= F_local;
|
||||
} else {
|
||||
_flags &= ~F_local;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -305,7 +309,11 @@ get_twoside() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void Material::
|
||||
set_twoside(bool twoside) {
|
||||
_flags = F_twoside;
|
||||
if (twoside) {
|
||||
_flags |= F_twoside;
|
||||
} else {
|
||||
_flags &= ~F_twoside;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -74,10 +74,22 @@ compare_to(const Material &other) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void Material::
|
||||
output(ostream &out) const {
|
||||
out << "a" << get_ambient()[0] << ",d" << get_diffuse()[0]
|
||||
<< ",s" << get_specular()[0] << ",e" << get_emission()[0]
|
||||
<< ",s" << get_shininess() << ",l" << get_local()
|
||||
<< ",t" << get_twoside();
|
||||
out << "material";
|
||||
if (has_ambient()) {
|
||||
out << " a(" << get_ambient() << ")";
|
||||
}
|
||||
if (has_diffuse()) {
|
||||
out << " d(" << get_diffuse() << ")";
|
||||
}
|
||||
if (has_specular()) {
|
||||
out << " s(" << get_specular() << ")";
|
||||
}
|
||||
if (has_emission()) {
|
||||
out << " e(" << get_emission() << ")";
|
||||
}
|
||||
out << " s" << get_shininess()
|
||||
<< " l" << get_local()
|
||||
<< " t" << get_twoside();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -87,10 +99,23 @@ output(ostream &out) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void Material::
|
||||
write(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level) << "ambient = " << get_ambient() << "\n";
|
||||
indent(out, indent_level) << "diffuse = " << get_diffuse() << "\n";
|
||||
indent(out, indent_level) << "specular = " << get_specular() << "\n";
|
||||
indent(out, indent_level) << "emission = " << get_emission() << "\n";
|
||||
bool any = false;
|
||||
if (has_ambient()) {
|
||||
indent(out, indent_level) << "ambient = " << get_ambient() << "\n";
|
||||
any = true;
|
||||
}
|
||||
if (has_diffuse()) {
|
||||
indent(out, indent_level) << "diffuse = " << get_diffuse() << "\n";
|
||||
any = true;
|
||||
}
|
||||
if (has_specular()) {
|
||||
indent(out, indent_level) << "specular = " << get_specular() << "\n";
|
||||
any = true;
|
||||
}
|
||||
if (has_emission()) {
|
||||
indent(out, indent_level) << "emission = " << get_emission() << "\n";
|
||||
any = true;
|
||||
}
|
||||
indent(out, indent_level) << "shininess = " << get_shininess() << "\n";
|
||||
indent(out, indent_level) << "local = " << get_local() << "\n";
|
||||
indent(out, indent_level) << "twoside = " << get_twoside() << "\n";
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ CLwoSurface(LwoToEggConverter *converter, const LwoSurface *surface) :
|
|||
_surface(surface)
|
||||
{
|
||||
_flags = 0;
|
||||
_color.set(1.0, 1.0, 1.0);
|
||||
_checked_material = false;
|
||||
_checked_texture = false;
|
||||
_map_uvs = NULL;
|
||||
_block = (CLwoSurfaceBlock *)NULL;
|
||||
|
|
@ -146,6 +148,10 @@ apply_properties(EggPrimitive *egg_prim, vector_PT_EggVertex &egg_vertices,
|
|||
}
|
||||
}
|
||||
|
||||
if (check_material()) {
|
||||
egg_prim->set_material(_egg_material);
|
||||
}
|
||||
|
||||
// We treat color and transparency separately, because Lightwave
|
||||
// does, and this will allow us to treat inherited surfaces a little
|
||||
// more robustly.
|
||||
|
|
@ -269,6 +275,50 @@ check_texture() {
|
|||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLwoSurface::check_material
|
||||
// Access: Public
|
||||
// Description: Checks whether the surface demands a material or not.
|
||||
// Returns true if so, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLwoSurface::
|
||||
check_material() {
|
||||
if (_checked_material) {
|
||||
return (_egg_material != (EggMaterial *)NULL);
|
||||
}
|
||||
_checked_material = true;
|
||||
_egg_material = (EggMaterial *)NULL;
|
||||
|
||||
if (!_converter->_make_materials) {
|
||||
// If we aren't making materials, then don't make a material.
|
||||
return false;
|
||||
}
|
||||
|
||||
_egg_material = new EggMaterial(get_name());
|
||||
|
||||
RGBColorf color = _color;
|
||||
if (check_texture()) {
|
||||
// Texturing overrides the color.
|
||||
color.set(1.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
if ((_flags & F_diffuse) != 0) {
|
||||
RGBColorf diffuse = color * _diffuse;
|
||||
_egg_material->set_diff(diffuse);
|
||||
}
|
||||
if ((_flags & F_luminosity) != 0) {
|
||||
RGBColorf luminosity = color * _luminosity;
|
||||
_egg_material->set_emit(luminosity);
|
||||
}
|
||||
if ((_flags & F_specular) != 0) {
|
||||
RGBColorf specular = color * _specular;
|
||||
_egg_material->set_spec(specular);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLwoSurface::generate_uvs
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <lwoSurface.h>
|
||||
#include <luse.h>
|
||||
#include <eggTexture.h>
|
||||
#include <eggMaterial.h>
|
||||
#include <vector_PT_EggVertex.h>
|
||||
|
||||
#include <map>
|
||||
|
|
@ -38,10 +39,12 @@ public:
|
|||
vector_PT_EggVertex &egg_vertices,
|
||||
float &smooth_angle);
|
||||
bool check_texture();
|
||||
bool check_material();
|
||||
|
||||
INLINE bool has_named_uvs() const;
|
||||
INLINE const string &get_uv_name() const;
|
||||
|
||||
|
||||
enum Flags {
|
||||
F_color = 0x0001,
|
||||
F_diffuse = 0x0002,
|
||||
|
|
@ -68,6 +71,9 @@ public:
|
|||
LwoToEggConverter *_converter;
|
||||
CPT(LwoSurface) _surface;
|
||||
|
||||
bool _checked_material;
|
||||
PT(EggMaterial) _egg_material;
|
||||
|
||||
bool _checked_texture;
|
||||
PT(EggTexture) _egg_texture;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
LwoToEggConverter::
|
||||
LwoToEggConverter() {
|
||||
_generic_layer = (CLwoLayer *)NULL;
|
||||
_make_materials = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ public:
|
|||
|
||||
CLwoSurface *get_surface(const string &name) const;
|
||||
|
||||
bool _make_materials;
|
||||
|
||||
private:
|
||||
void cleanup();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue