Panda3D
 All Classes Functions Variables Enumerations
geomMunger.h
00001 // Filename: geomMunger.h
00002 // Created by:  drose (10Mar05)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #ifndef GEOMMUNGER_H
00016 #define GEOMMUNGER_H
00017 
00018 #include "pandabase.h"
00019 #include "typedReferenceCount.h"
00020 #include "geomVertexAnimationSpec.h"
00021 #include "geomVertexFormat.h"
00022 #include "geomVertexData.h"
00023 #include "geomCacheEntry.h"
00024 #include "indirectCompareTo.h"
00025 #include "pStatCollector.h"
00026 #include "lightMutex.h"
00027 #include "lightReMutex.h"
00028 #include "pointerTo.h"
00029 #include "pmap.h"
00030 #include "pset.h"
00031 
00032 class GraphicsStateGuardianBase;
00033 class RenderState;
00034 class Geom;
00035 
00036 ////////////////////////////////////////////////////////////////////
00037 //       Class : GeomMunger
00038 // Description : Objects of this class are used to convert vertex data
00039 //               from a Geom into a format suitable for passing to the
00040 //               rendering backend.  Typically, the rendering backend
00041 //               will create a specialization of this class to handle
00042 //               its particular needs (e.g. DXGeomMunger).  This class
00043 //               is necessary because DirectX and OpenGL have somewhat
00044 //               different requirements for vertex format.
00045 //
00046 //               This also performs runtime application of state
00047 //               changes to the vertex data; for instance, by scaling
00048 //               all of the color values in response to a
00049 //               ColorScaleAttrib.
00050 //
00051 //               A GeomMunger must be registered before it can be
00052 //               used, and once registered, the object is constant and
00053 //               cannot be changed.  All registered GeomMungers that
00054 //               perform the same operation will have the same
00055 //               pointer.
00056 ////////////////////////////////////////////////////////////////////
00057 class EXPCL_PANDA_GOBJ GeomMunger : public TypedReferenceCount, public GeomEnums {
00058 public:
00059   GeomMunger(GraphicsStateGuardianBase *gsg);
00060   GeomMunger(const GeomMunger &copy);
00061   void operator = (const GeomMunger &copy);
00062   virtual ~GeomMunger();
00063 
00064   INLINE GraphicsStateGuardianBase *get_gsg() const;
00065 
00066   INLINE bool is_registered() const;
00067   INLINE static PT(GeomMunger) register_munger(GeomMunger *munger, Thread *current_thread);
00068   INLINE static void unregister_mungers_for_gsg(GraphicsStateGuardianBase *gsg);
00069 
00070   INLINE CPT(GeomVertexFormat) munge_format(const GeomVertexFormat *format,
00071                                             const GeomVertexAnimationSpec &animation) const;
00072 
00073   INLINE CPT(GeomVertexData) munge_data(const GeomVertexData *data) const;
00074   void remove_data(const GeomVertexData *data);
00075 
00076   bool munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data,
00077                   bool force, Thread *current_thread);
00078 
00079   INLINE CPT(GeomVertexFormat) premunge_format(const GeomVertexFormat *format) const;
00080   INLINE CPT(GeomVertexData) premunge_data(const GeomVertexData *data) const;
00081   INLINE void premunge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data) const;
00082 
00083 public:
00084   INLINE int compare_to(const GeomMunger &other) const;
00085   INLINE int geom_compare_to(const GeomMunger &other) const;
00086 
00087 protected:
00088   INLINE void unregister_myself();
00089 
00090   CPT(GeomVertexFormat) do_munge_format(const GeomVertexFormat *format,
00091                                         const GeomVertexAnimationSpec &animation);
00092 
00093   virtual CPT(GeomVertexFormat) munge_format_impl(const GeomVertexFormat *orig,
00094                                                   const GeomVertexAnimationSpec &animation);
00095   virtual CPT(GeomVertexData) munge_data_impl(const GeomVertexData *data);
00096   virtual void munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &data,
00097                                Thread *current_thread);
00098 
00099 
00100   CPT(GeomVertexFormat) do_premunge_format(const GeomVertexFormat *format);
00101   virtual CPT(GeomVertexFormat) premunge_format_impl(const GeomVertexFormat *orig);
00102   virtual CPT(GeomVertexData) premunge_data_impl(const GeomVertexData *data);
00103   virtual void premunge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &data);
00104 
00105   virtual int compare_to_impl(const GeomMunger *other) const;
00106   virtual int geom_compare_to_impl(const GeomMunger *other) const;
00107 
00108 private:
00109   class Registry;
00110   INLINE static Registry *get_registry();
00111   static void make_registry();
00112 
00113   void do_register(Thread *current_thread);
00114   void do_unregister();
00115 
00116 private:
00117   class CacheEntry : public GeomCacheEntry {
00118   public:
00119     virtual void output(ostream &out) const;
00120 
00121     PT(GeomMunger) _munger;
00122   };
00123 
00124   typedef pmap<CPT(GeomVertexFormat), CPT(GeomVertexFormat) > Formats;
00125   typedef pmap<GeomVertexAnimationSpec, Formats> FormatsByAnimation;
00126   FormatsByAnimation _formats_by_animation;
00127   Formats _premunge_formats;
00128 
00129   // This mutex protects the above.
00130   LightMutex _formats_lock;
00131 
00132   GraphicsStateGuardianBase *_gsg;
00133 
00134   bool _is_registered;
00135   typedef pset<GeomMunger *, IndirectCompareTo<GeomMunger> > Mungers;
00136   class EXPCL_PANDA_GOBJ Registry {
00137   public:
00138     Registry();
00139     PT(GeomMunger) register_munger(GeomMunger *munger, Thread *current_thread);
00140     void unregister_munger(GeomMunger *munger);
00141     void unregister_mungers_for_gsg(GraphicsStateGuardianBase *gsg);
00142 
00143     Mungers _mungers;
00144     LightReMutex _registry_lock;
00145   };
00146 
00147   // We store the iterator into the above registry, while we are
00148   // registered.  This makes it easier to remove our own entry,
00149   // especially when the destructor is called.  Since it's a virtual
00150   // destructor, we can't reliably look up our pointer in the map once
00151   // we have reached the base class destructor (since the object has
00152   // changed types by then, and the sorting in the map depends partly
00153   // on type).
00154   Mungers::iterator _registered_key;
00155 
00156   static Registry *_registry;
00157 
00158   static PStatCollector _munge_pcollector;
00159 
00160 public:
00161   static TypeHandle get_class_type() {
00162     return _type_handle;
00163   }
00164   static void init_type() {
00165     TypedReferenceCount::init_type();
00166     register_type(_type_handle, "GeomMunger",
00167                   TypedReferenceCount::get_class_type());
00168   }
00169   virtual TypeHandle get_type() const {
00170     return get_class_type();
00171   }
00172   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00173 
00174 private:
00175   static TypeHandle _type_handle;
00176 
00177   friend class Geom;
00178 };
00179 
00180 #include "geomMunger.I"
00181 
00182 #endif
00183 
 All Classes Functions Variables Enumerations