374 lines
13 KiB
C++
374 lines
13 KiB
C++
// Filename: renderState.h
|
|
// Created by: drose (21Feb02)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
|
//
|
|
// All use of this software is subject to the terms of the Panda 3d
|
|
// Software license. You should have received a copy of this license
|
|
// along with this source code; you will also find a current copy of
|
|
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
|
//
|
|
// To contact the maintainers of this program write to
|
|
// panda3d-general@lists.sourceforge.net .
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef RENDERSTATE_H
|
|
#define RENDERSTATE_H
|
|
|
|
#include "pandabase.h"
|
|
|
|
#include "renderAttrib.h"
|
|
#include "nodeCachedReferenceCount.h"
|
|
#include "pointerTo.h"
|
|
#include "ordered_vector.h"
|
|
#include "updateSeq.h"
|
|
#include "pStatCollector.h"
|
|
#include "renderModeAttrib.h"
|
|
#include "texMatrixAttrib.h"
|
|
#include "geomMunger.h"
|
|
#include "weakPointerTo.h"
|
|
#include "shaderExpansion.h"
|
|
#include "reMutex.h"
|
|
#include "pmutex.h"
|
|
#include "deletedChain.h"
|
|
|
|
class GraphicsStateGuardianBase;
|
|
class FogAttrib;
|
|
class CullBinAttrib;
|
|
class TransparencyAttrib;
|
|
class ColorAttrib;
|
|
class ColorScaleAttrib;
|
|
class TextureAttrib;
|
|
class TexGenAttrib;
|
|
class ClipPlaneAttrib;
|
|
class ShaderAttrib;
|
|
class FactoryParams;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Class : RenderState
|
|
// Description : This represents a unique collection of RenderAttrib
|
|
// objects that correspond to a particular renderable
|
|
// state.
|
|
//
|
|
// You should not attempt to create or modify a
|
|
// RenderState object directly. Instead, call one of
|
|
// the make() functions to create one for you. And
|
|
// instead of modifying a RenderState object, create a
|
|
// new one.
|
|
////////////////////////////////////////////////////////////////////
|
|
class EXPCL_PANDA RenderState : public NodeCachedReferenceCount {
|
|
protected:
|
|
RenderState();
|
|
|
|
private:
|
|
RenderState(const RenderState ©);
|
|
void operator = (const RenderState ©);
|
|
|
|
public:
|
|
virtual ~RenderState();
|
|
ALLOC_DELETED_CHAIN(RenderState);
|
|
|
|
PUBLISHED:
|
|
bool operator < (const RenderState &other) const;
|
|
size_t get_hash() const;
|
|
|
|
INLINE bool is_empty() const;
|
|
INLINE int get_num_attribs() const;
|
|
INLINE const RenderAttrib *get_attrib(int n) const;
|
|
INLINE int get_override(int n) const;
|
|
|
|
INLINE bool has_cull_callback() const;
|
|
bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
|
|
|
|
int find_attrib(TypeHandle type) const;
|
|
|
|
static CPT(RenderState) make_empty();
|
|
static CPT(RenderState) make(const RenderAttrib *attrib, int override = 0);
|
|
static CPT(RenderState) make(const RenderAttrib *attrib1,
|
|
const RenderAttrib *attrib2, int override = 0);
|
|
static CPT(RenderState) make(const RenderAttrib *attrib1,
|
|
const RenderAttrib *attrib2,
|
|
const RenderAttrib *attrib3, int override = 0);
|
|
static CPT(RenderState) make(const RenderAttrib *attrib1,
|
|
const RenderAttrib *attrib2,
|
|
const RenderAttrib *attrib3,
|
|
const RenderAttrib *attrib4, int override = 0);
|
|
static CPT(RenderState) make(const RenderAttrib * const *attrib,
|
|
int num_attribs, int override = 0);
|
|
static CPT(RenderState) make(const AttribSlots *slots, int override = 0);
|
|
|
|
CPT(RenderState) compose(const RenderState *other) const;
|
|
CPT(RenderState) invert_compose(const RenderState *other) const;
|
|
|
|
CPT(RenderState) add_attrib(const RenderAttrib *attrib, int override = 0) const;
|
|
CPT(RenderState) remove_attrib(TypeHandle type) const;
|
|
|
|
CPT(RenderState) adjust_all_priorities(int adjustment) const;
|
|
|
|
const RenderAttrib *get_attrib(TypeHandle type) const;
|
|
int get_override(TypeHandle type) const;
|
|
|
|
bool unref() const;
|
|
|
|
INLINE void cache_ref() const;
|
|
INLINE bool cache_unref() const;
|
|
INLINE void node_ref() const;
|
|
INLINE bool node_unref() const;
|
|
|
|
void output(ostream &out) const;
|
|
void write(ostream &out, int indent_level) const;
|
|
|
|
static int get_max_priority();
|
|
|
|
static int get_num_states();
|
|
static int get_num_unused_states();
|
|
static int clear_cache();
|
|
static void list_cycles(ostream &out);
|
|
static void list_states(ostream &out);
|
|
static bool validate_states();
|
|
|
|
PUBLISHED:
|
|
// These methods are intended for use by low-level code, but they're
|
|
// also handy enough to expose to high-level users.
|
|
INLINE int get_draw_order() const;
|
|
INLINE const FogAttrib *get_fog() const;
|
|
INLINE const CullBinAttrib *get_bin() const;
|
|
INLINE const TransparencyAttrib *get_transparency() const;
|
|
INLINE int get_bin_index() const;
|
|
INLINE const ColorAttrib *get_color() const;
|
|
INLINE const ColorScaleAttrib *get_color_scale() const;
|
|
INLINE const TextureAttrib *get_texture() const;
|
|
INLINE const TexGenAttrib *get_tex_gen() const;
|
|
INLINE const TexMatrixAttrib *get_tex_matrix() const;
|
|
INLINE const RenderModeAttrib *get_render_mode() const;
|
|
INLINE const ClipPlaneAttrib *get_clip_plane() const;
|
|
INLINE const ShaderAttrib *get_shader() const;
|
|
|
|
int get_geom_rendering(int geom_rendering) const;
|
|
|
|
public:
|
|
void store_into_slots(AttribSlots *slots) const;
|
|
|
|
static void bin_removed(int bin_index);
|
|
INLINE ShaderExpansion *get_shader_expansion() const;
|
|
INLINE void set_shader_expansion(ShaderExpansion *exp);
|
|
|
|
INLINE static void flush_level();
|
|
|
|
private:
|
|
class CompositionCycleDescEntry {
|
|
public:
|
|
INLINE CompositionCycleDescEntry(const RenderState *obj,
|
|
const RenderState *result,
|
|
bool inverted);
|
|
|
|
const RenderState *_obj;
|
|
const RenderState *_result;
|
|
bool _inverted;
|
|
};
|
|
typedef pvector<CompositionCycleDescEntry> CompositionCycleDesc;
|
|
|
|
static CPT(RenderState) return_new(RenderState *state);
|
|
CPT(RenderState) do_compose(const RenderState *other) const;
|
|
CPT(RenderState) do_invert_compose(const RenderState *other) const;
|
|
static bool r_detect_cycles(const RenderState *start_state,
|
|
const RenderState *current_state,
|
|
int length, UpdateSeq this_seq,
|
|
CompositionCycleDesc *cycle_desc);
|
|
|
|
void remove_cache_pointers();
|
|
|
|
void determine_bin_index();
|
|
void determine_fog();
|
|
INLINE void determine_bin();
|
|
void do_determine_bin();
|
|
INLINE void determine_transparency();
|
|
void do_determine_transparency();
|
|
void determine_color();
|
|
void determine_color_scale();
|
|
void determine_texture();
|
|
void determine_tex_gen();
|
|
void determine_tex_matrix();
|
|
void determine_render_mode();
|
|
void determine_clip_plane();
|
|
void determine_shader();
|
|
void determine_cull_callback();
|
|
|
|
INLINE void set_destructing();
|
|
INLINE bool is_destructing() const;
|
|
|
|
INLINE void consider_update_pstats(int old_referenced_bits) const;
|
|
static void update_pstats(int old_referenced_bits, int new_referenced_bits);
|
|
|
|
public:
|
|
static void init_states();
|
|
|
|
private:
|
|
// This mutex protects _states. It also protects any modification
|
|
// to the cache, which is encoded in _composition_cache and
|
|
// _invert_composition_cache.
|
|
static ReMutex *_states_lock;
|
|
typedef phash_set<const RenderState *, indirect_less_hash<const RenderState *> > States;
|
|
static States *_states;
|
|
static CPT(RenderState) _empty_state;
|
|
|
|
// This iterator records the entry corresponding to this RenderState
|
|
// object in the above global set. We keep the iterator around so
|
|
// we can remove it when the RenderState destructs.
|
|
States::iterator _saved_entry;
|
|
|
|
// This data structure manages the job of caching the composition of
|
|
// two RenderStates. It's complicated because we have to be sure to
|
|
// remove the entry if *either* of the input RenderStates destructs.
|
|
// To implement this, we always record Composition entries in pairs,
|
|
// one in each of the two involved RenderState objects.
|
|
class Composition {
|
|
public:
|
|
INLINE Composition();
|
|
INLINE Composition(const Composition ©);
|
|
|
|
// _result is reference counted if and only if it is not the same
|
|
// pointer as this.
|
|
const RenderState *_result;
|
|
};
|
|
|
|
// The first element of the map is the object we compose with. This
|
|
// is not reference counted within this map; instead we store a
|
|
// companion pointer in the other object, and remove the references
|
|
// explicitly when either object destructs.
|
|
typedef phash_map<const RenderState *, Composition, pointer_hash> CompositionCache;
|
|
CompositionCache _composition_cache;
|
|
CompositionCache _invert_composition_cache;
|
|
|
|
// This is here to provide a quick cache of GSG + RenderState ->
|
|
// GeomMunger for the cull phase. It is here because it is faster
|
|
// to look up the GSG in the RenderState pointer than vice-versa,
|
|
// since there are likely to be far fewer GSG's than RenderStates.
|
|
// The code to manage this map lives in
|
|
// GraphicsStateGuardian::get_geom_munger().
|
|
typedef pmap<WCPT(GraphicsStateGuardianBase), PT(GeomMunger) > Mungers;
|
|
Mungers _mungers;
|
|
Mungers::const_iterator _last_mi;
|
|
|
|
// This is used to mark nodes as we visit them to detect cycles.
|
|
UpdateSeq _cycle_detect;
|
|
static UpdateSeq _last_cycle_detect;
|
|
|
|
static PStatCollector _cache_update_pcollector;
|
|
static PStatCollector _state_compose_pcollector;
|
|
static PStatCollector _state_invert_pcollector;
|
|
|
|
static PStatCollector _node_counter;
|
|
static PStatCollector _cache_counter;
|
|
|
|
private:
|
|
// This is the actual data within the RenderState: a set of
|
|
// RenderAttribs.
|
|
class Attribute {
|
|
public:
|
|
INLINE Attribute(const RenderAttrib *attrib, int override);
|
|
INLINE Attribute(int override);
|
|
INLINE Attribute(TypeHandle type);
|
|
INLINE Attribute(const Attribute ©);
|
|
INLINE void operator = (const Attribute ©);
|
|
INLINE bool operator < (const Attribute &other) const;
|
|
INLINE int compare_to(const Attribute &other) const;
|
|
|
|
TypeHandle _type;
|
|
CPT(RenderAttrib) _attrib;
|
|
int _override;
|
|
};
|
|
typedef ov_set<Attribute> Attributes;
|
|
Attributes _attributes;
|
|
|
|
// We cache the index to the associated CullBin, if there happens to
|
|
// be a CullBinAttrib in the state.
|
|
int _bin_index;
|
|
int _draw_order;
|
|
|
|
// If this renderstate contains a Shader, then the macroexpansion
|
|
// of the shader needs to be cached (to avoid having to regenerate
|
|
// it each time this RenderState is applied).
|
|
PT(ShaderExpansion) _shader_expansion;
|
|
|
|
// We also cache the pointer to some critical attribs stored in the
|
|
// state, if they exist.
|
|
const FogAttrib *_fog;
|
|
const CullBinAttrib *_bin;
|
|
const TransparencyAttrib *_transparency;
|
|
const ColorAttrib *_color;
|
|
const ColorScaleAttrib *_color_scale;
|
|
const TextureAttrib *_texture;
|
|
const TexGenAttrib *_tex_gen;
|
|
const TexMatrixAttrib *_tex_matrix;
|
|
const RenderModeAttrib *_render_mode;
|
|
const ClipPlaneAttrib *_clip_plane;
|
|
const ShaderAttrib *_shader;
|
|
|
|
enum Flags {
|
|
F_checked_bin_index = 0x0001,
|
|
F_checked_fog = 0x0002,
|
|
F_checked_bin = 0x0004,
|
|
F_checked_transparency = 0x0008,
|
|
F_checked_color = 0x0010,
|
|
F_checked_color_scale = 0x0020,
|
|
F_checked_texture = 0x0040,
|
|
F_checked_tex_gen = 0x0080,
|
|
F_checked_tex_matrix = 0x0100,
|
|
F_checked_render_mode = 0x0200,
|
|
F_checked_clip_plane = 0x0400,
|
|
F_checked_shader = 0x0800,
|
|
F_checked_cull_callback = 0x1000,
|
|
F_has_cull_callback = 0x2000,
|
|
F_is_destructing = 0x8000,
|
|
};
|
|
unsigned short _flags;
|
|
|
|
// This mutex protects _flags, and all of the above computed values.
|
|
Mutex _lock;
|
|
|
|
public:
|
|
static void register_with_read_factory();
|
|
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
|
virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
|
|
static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager);
|
|
virtual void finalize(BamReader *manager);
|
|
|
|
protected:
|
|
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
|
void fillin(DatagramIterator &scan, BamReader *manager);
|
|
|
|
public:
|
|
static TypeHandle get_class_type() {
|
|
return _type_handle;
|
|
}
|
|
static void init_type() {
|
|
NodeCachedReferenceCount::init_type();
|
|
register_type(_type_handle, "RenderState",
|
|
NodeCachedReferenceCount::get_class_type());
|
|
}
|
|
virtual TypeHandle get_type() const {
|
|
return get_class_type();
|
|
}
|
|
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
|
|
|
private:
|
|
static TypeHandle _type_handle;
|
|
|
|
friend class GraphicsStateGuardian;
|
|
};
|
|
|
|
INLINE ostream &operator << (ostream &out, const RenderState &state) {
|
|
state.output(out);
|
|
return out;
|
|
}
|
|
|
|
#include "renderState.I"
|
|
|
|
#endif
|
|
|