283 lines
7.9 KiB
Text
283 lines
7.9 KiB
Text
|
/**
|
||
|
* PANDA 3D SOFTWARE
|
||
|
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||
|
*
|
||
|
* All use of this software is subject to the terms of the revised BSD
|
||
|
* license. You should have received a copy of this license along
|
||
|
* with this source code in a file named "LICENSE."
|
||
|
*
|
||
|
* @file textureAttrib.I
|
||
|
* @author drose
|
||
|
* @date 2002-02-21
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Use TextureAttrib::make() to construct a new TextureAttrib object.
|
||
|
*/
|
||
|
INLINE TextureAttrib::
|
||
|
TextureAttrib() {
|
||
|
_next_implicit_sort = 0;
|
||
|
_off_all_stages = false;
|
||
|
_sort_seq = UpdateSeq::old();
|
||
|
_filtered_seq = UpdateSeq::old();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Use TextureAttrib::make() to construct a new TextureAttrib object. The
|
||
|
* copy constructor is only defined to facilitate methods like add_on_stage().
|
||
|
*/
|
||
|
INLINE TextureAttrib::
|
||
|
TextureAttrib(const TextureAttrib ©) :
|
||
|
_on_stages(copy._on_stages),
|
||
|
_render_stages(copy._render_stages),
|
||
|
_render_ff_stages(copy._render_ff_stages),
|
||
|
_next_implicit_sort(copy._next_implicit_sort),
|
||
|
_off_stages(copy._off_stages),
|
||
|
_off_all_stages(copy._off_all_stages),
|
||
|
_sort_seq(copy._sort_seq),
|
||
|
_filtered_seq(UpdateSeq::old())
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns true if the TextureAttrib is an 'off' TextureAttrib, indicating
|
||
|
* that it should disable texturing.
|
||
|
*
|
||
|
* If multitexture is in effect, a TextureAttrib may not be strictly "on" or
|
||
|
* "off"; therefore, to get a more precise answer to this question, you should
|
||
|
* consider using has_all_off() or get_num_off_stages() or has_off_stage()
|
||
|
* instead.
|
||
|
*/
|
||
|
INLINE bool TextureAttrib::
|
||
|
is_off() const {
|
||
|
return (_on_stages.empty());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* If the TextureAttrib is not an 'off' TextureAttrib, returns the base-level
|
||
|
* texture that is associated. Otherwise, return NULL.
|
||
|
*/
|
||
|
INLINE Texture *TextureAttrib::
|
||
|
get_texture() const {
|
||
|
if (_on_stages.empty()) {
|
||
|
return nullptr;
|
||
|
}
|
||
|
check_sorted();
|
||
|
return get_on_texture(filter_to_max(1)->get_on_stage(0));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the number of stages that are turned on by the attribute.
|
||
|
*/
|
||
|
INLINE int TextureAttrib::
|
||
|
get_num_on_stages() const {
|
||
|
check_sorted();
|
||
|
return _render_stages.size();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the nth stage turned on by the attribute, sorted in render order.
|
||
|
*/
|
||
|
INLINE TextureStage *TextureAttrib::
|
||
|
get_on_stage(int n) const {
|
||
|
nassertr(n >= 0 && n < (int)_render_stages.size(), nullptr);
|
||
|
return _render_stages[n]->_stage;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the number of on-stages that are relevant to the classic fixed
|
||
|
* function pipeline. This excludes texture stages such as normal maps.
|
||
|
*/
|
||
|
INLINE int TextureAttrib::
|
||
|
get_num_on_ff_stages() const {
|
||
|
check_sorted();
|
||
|
return _render_ff_stages.size();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the nth stage turned on by the attribute, sorted in render order,
|
||
|
* including only those relevant to the classic fixed function pipeline. This
|
||
|
* excludes texture stages such as normal maps.
|
||
|
*/
|
||
|
INLINE TextureStage *TextureAttrib::
|
||
|
get_on_ff_stage(int n) const {
|
||
|
nassertr(n >= 0 && n < (int)_render_ff_stages.size(), nullptr);
|
||
|
return _render_ff_stages[n]->_stage;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* For each TextureStage listed in get_on_ff_stage(), this returns a unique
|
||
|
* index number for the texture coordinate name used by that TextureStage. It
|
||
|
* is guaranteed to remain the same index number for each texcoord name (for a
|
||
|
* given set of TextureStages), even if the texture render order changes.
|
||
|
*/
|
||
|
INLINE int TextureAttrib::
|
||
|
get_ff_tc_index(int n) const {
|
||
|
nassertr(n >= 0 && n < (int)_render_ff_stages.size(), -1);
|
||
|
return _render_ff_stages[n]->_ff_tc_index;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns true if the indicated stage is turned on by the attrib, false
|
||
|
* otherwise.
|
||
|
*/
|
||
|
INLINE bool TextureAttrib::
|
||
|
has_on_stage(TextureStage *stage) const {
|
||
|
return _on_stages.find(StageNode(stage)) != _on_stages.end();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the texture associated with the indicated stage, or NULL if no
|
||
|
* texture is associated.
|
||
|
*/
|
||
|
INLINE Texture *TextureAttrib::
|
||
|
get_on_texture(TextureStage *stage) const {
|
||
|
Stages::const_iterator si;
|
||
|
si = _on_stages.find(StageNode(stage));
|
||
|
if (si != _on_stages.end()) {
|
||
|
return (*si)._texture;
|
||
|
}
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the sampler associated with the indicated stage, or the one
|
||
|
* associated with its texture if no custom stage has been specified. It is
|
||
|
* an error to call this if the stage does not exist.
|
||
|
*/
|
||
|
INLINE const SamplerState &TextureAttrib::
|
||
|
get_on_sampler(TextureStage *stage) const {
|
||
|
Stages::const_iterator si;
|
||
|
si = _on_stages.find(StageNode(stage));
|
||
|
nassertr_always(si != _on_stages.end(), SamplerState::get_default());
|
||
|
|
||
|
return si->_has_sampler ? si->_sampler
|
||
|
: si->_texture->get_default_sampler();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the override value associated with the indicated stage.
|
||
|
*/
|
||
|
INLINE int TextureAttrib::
|
||
|
get_on_stage_override(TextureStage *stage) const {
|
||
|
Stages::const_iterator si;
|
||
|
si = _on_stages.find(StageNode(stage));
|
||
|
if (si != _on_stages.end()) {
|
||
|
return (*si)._override;
|
||
|
}
|
||
|
nassert_raise("Specified TextureStage not included in attrib");
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the number of stages that are turned off by the attribute.
|
||
|
*/
|
||
|
INLINE int TextureAttrib::
|
||
|
get_num_off_stages() const {
|
||
|
return _off_stages.size();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the nth stage turned off by the attribute, sorted in arbitrary
|
||
|
* (pointer) order.
|
||
|
*/
|
||
|
INLINE TextureStage *TextureAttrib::
|
||
|
get_off_stage(int n) const {
|
||
|
nassertr(n >= 0 && n < (int)_off_stages.size(), nullptr);
|
||
|
return _off_stages[n]._stage;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns true if the indicated stage is turned off by the attrib, false
|
||
|
* otherwise.
|
||
|
*/
|
||
|
INLINE bool TextureAttrib::
|
||
|
has_off_stage(TextureStage *stage) const {
|
||
|
return _off_stages.find(StageNode(stage)) != _off_stages.end() ||
|
||
|
(_off_all_stages && !has_on_stage(stage));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns true if this attrib turns off all stages (although it may also turn
|
||
|
* some on).
|
||
|
*/
|
||
|
INLINE bool TextureAttrib::
|
||
|
has_all_off() const {
|
||
|
return _off_all_stages;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns true if this is an identity attrib: it does not change the set of
|
||
|
* stages in use.
|
||
|
*/
|
||
|
INLINE bool TextureAttrib::
|
||
|
is_identity() const {
|
||
|
return _on_stages.empty() && _off_stages.empty() && !_off_all_stages;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Confirms whether the _on_stages list is still sorted. It will become
|
||
|
* unsorted if someone calls TextureStage::set_sort().
|
||
|
*
|
||
|
* If the list requires sorting, transparently sorts it before returning.
|
||
|
*/
|
||
|
INLINE void TextureAttrib::
|
||
|
check_sorted() const {
|
||
|
if (_sort_seq != TextureStage::get_sort_seq()) {
|
||
|
((TextureAttrib *)this)->sort_on_stages();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*/
|
||
|
INLINE TextureAttrib::StageNode::
|
||
|
StageNode(const TextureStage *stage, unsigned int implicit_sort, int override) :
|
||
|
// Yeah, we cast away the constness here. Just too much trouble to deal
|
||
|
// with it properly.
|
||
|
_stage((TextureStage *)stage),
|
||
|
_implicit_sort(implicit_sort),
|
||
|
_override(override),
|
||
|
_has_sampler(false)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* This STL function object is used to sort a list of texture stages in
|
||
|
* reverse order by priority, and within priority, within order by sort.
|
||
|
*/
|
||
|
INLINE bool TextureAttrib::CompareTextureStagePriorities::
|
||
|
operator () (const TextureAttrib::StageNode *a,
|
||
|
const TextureAttrib::StageNode *b) const {
|
||
|
if (a->_stage->get_priority() != b->_stage->get_priority()) {
|
||
|
return a->_stage->get_priority() > b->_stage->get_priority();
|
||
|
}
|
||
|
if (a->_stage->get_sort() != b->_stage->get_sort()) {
|
||
|
return a->_stage->get_sort() < b->_stage->get_sort();
|
||
|
}
|
||
|
return a->_implicit_sort < b->_implicit_sort;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* This STL function object is used to sort a list of texture stages in order
|
||
|
* by sort.
|
||
|
*/
|
||
|
INLINE bool TextureAttrib::CompareTextureStageSort::
|
||
|
operator () (const TextureAttrib::StageNode *a,
|
||
|
const TextureAttrib::StageNode *b) const {
|
||
|
if (a->_stage->get_sort() != b->_stage->get_sort()) {
|
||
|
return a->_stage->get_sort() < b->_stage->get_sort();
|
||
|
}
|
||
|
return a->_implicit_sort < b->_implicit_sort;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* This STL function object is used to sort a list of texture stages in order
|
||
|
* by pointer.
|
||
|
*/
|
||
|
INLINE bool TextureAttrib::CompareTextureStagePointer::
|
||
|
operator () (const TextureAttrib::StageNode &a,
|
||
|
const TextureAttrib::StageNode &b) const {
|
||
|
return a._stage < b._stage;
|
||
|
}
|