Browse Source

Better shader caching, GLSL "#pragma include" support, better error reporting

rdb 11 years ago
parent
commit
13fb8079ec

+ 2 - 2
direct/src/filter/CommonFilters.py

@@ -199,7 +199,7 @@ class CommonFilters:
                 self.ssao[0].setShaderInput("depth", self.textures["depth"])
                 self.ssao[0].setShaderInput("normal", self.textures["aux"])
                 self.ssao[0].setShaderInput("random", loader.loadTexture("maps/random.rgb"))
-                self.ssao[0].setShader(Shader.make(SSAO_BODY % configuration["AmbientOcclusion"].numsamples))
+                self.ssao[0].setShader(Shader.make(SSAO_BODY % configuration["AmbientOcclusion"].numsamples, Shader.SL_Cg))
                 self.ssao[1].setShaderInput("src", ssao0)
                 self.ssao[1].setShader(self.loadShader("filter-blurx.sha"))
                 self.ssao[2].setShaderInput("src", ssao1)
@@ -339,7 +339,7 @@ class CommonFilters:
                 text += "  o_color = float4(1, 1, 1, 1) - o_color;\n"
             text += "}\n"
             
-            self.finalQuad.setShader(Shader.make(text))
+            self.finalQuad.setShader(Shader.make(text, Shader.SL_Cg))
             for tex in self.textures:
                 self.finalQuad.setShaderInput("tx"+tex, self.textures[tex])
             

+ 16 - 0
panda/src/gobj/config_gobj.cxx

@@ -541,6 +541,22 @@ ConfigVariableString cg_glsl_version
           "glslv, glslf or glslg profiles.  Use this when you are having "
           "problems with these profiles.  Example values are 120 or 150."));
 
+ConfigVariableBool glsl_preprocess
+("glsl-preprocess", true,
+ PRC_DESC("If this is enabled, Panda looks for lines starting with "
+          "#pragma include when loading a GLSL shader and processes "
+          "it appropriately.  This can be useful if you have code that "
+          "is shared between multiple shaders.  Set this to false if "
+          "you have no need for this feature or if you do your own "
+          "preprocessing of GLSL shaders."));
+
+ConfigVariableInt glsl_include_recursion_limit
+("glsl-include-recursion-limit", 10,
+ PRC_DESC("This sets a limit on how many nested #pragma include "
+          "directives that Panda will follow when glsl-preprocess is "
+          "enabled.  This is used to prevent infinite recursion when "
+          "two shader files include each other."));
+
 ConfigureFn(config_gobj) {
   AnimateVerticesRequest::init_type();
   BufferContext::init_type();

+ 2 - 0
panda/src/gobj/config_gobj.h

@@ -104,5 +104,7 @@ extern EXPCL_PANDA_GOBJ ConfigVariableInt lens_geom_segments;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool stereo_lens_old_convergence;
 
 extern EXPCL_PANDA_GOBJ ConfigVariableString cg_glsl_version;
+extern EXPCL_PANDA_GOBJ ConfigVariableBool glsl_preprocess;
+extern EXPCL_PANDA_GOBJ ConfigVariableInt glsl_include_recursion_limit;
 
 #endif

+ 118 - 55
panda/src/gobj/shader.I

@@ -21,31 +21,35 @@
 ////////////////////////////////////////////////////////////////////
 INLINE Filename Shader::
 get_filename(const ShaderType &type) const {
-  if (_filename->_separate && type == ST_none) {
+  if (_filename._separate && type != ST_none) {
     switch (type) {
       case ST_vertex:
-        return _filename->_vertex;
+        return _filename._vertex;
         break;
       case ST_fragment:
-        return _filename->_fragment;
+        return _filename._fragment;
         break;
       case ST_geometry:
-        return _filename->_geometry;
+        return _filename._geometry;
         break;
       case ST_tess_control:
-        return _text->_tess_control;
+        return _filename._tess_control;
         break;
       case ST_tess_evaluation:
-        return _text->_tess_evaluation;
+        return _filename._tess_evaluation;
         break;
       case ST_compute:
-        return _text->_compute;
+        return _filename._compute;
         break;
       default:
-        return _filename->_shared;
+        return _filename._shared;
     }
+  } else if (!_filename._shared.empty()) {
+    return _filename._shared;
+
   } else {
-    return _filename->_shared;
+    // Um, better than nothing?
+    return _filename._vertex;
   }
 }
 
@@ -56,32 +60,32 @@ get_filename(const ShaderType &type) const {
 ////////////////////////////////////////////////////////////////////
 INLINE const string &Shader::
 get_text(const ShaderType &type) const {
-  if (_text->_separate) {
-    nassertr(type != ST_none || !_text->_shared.empty(), _text->_shared);
+  if (_text._separate) {
+    nassertr(type != ST_none || !_text._shared.empty(), _text._shared);
     switch (type) {
       case ST_vertex:
-        return _text->_vertex;
+        return _text._vertex;
         break;
       case ST_fragment:
-        return _text->_fragment;
+        return _text._fragment;
         break;
       case ST_geometry:
-        return _text->_geometry;
+        return _text._geometry;
         break;
       case ST_tess_control:
-        return _text->_tess_control;
+        return _text._tess_control;
         break;
       case ST_tess_evaluation:
-        return _text->_tess_evaluation;
+        return _text._tess_evaluation;
         break;
       case ST_compute:
-        return _text->_compute;
+        return _text._compute;
         break;
       default:
-        return _text->_shared;
+        return _text._shared;
     }
   } else {
-    return _text->_shared;
+    return _text._shared;
   }
 }
 
@@ -115,7 +119,7 @@ set_shader_utilization(ShaderUtilization sut) {
 //  Description: This flag returns SUT_none, SUT_basic, or
 //               SUT_advanced and controls the automatic generation
 //               of shaders.  It is initialized from the config
-//               variable of the same name, but it can be 
+//               variable of the same name, but it can be
 //               subsequently adjusted.
 ////////////////////////////////////////////////////////////////////
 INLINE ShaderUtilization Shader::
@@ -154,7 +158,7 @@ get_language() const {
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderCapabilities Constructor
 //  Access: Public
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderCaps::
 ShaderCaps() {
@@ -164,7 +168,7 @@ ShaderCaps() {
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderCapabilities::operator ==
 //  Access: Public
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE bool Shader::ShaderCaps::
 operator == (const ShaderCaps &other) const {
@@ -184,10 +188,10 @@ operator == (const ShaderCaps &other) const {
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
-ShaderPtrData() : 
+ShaderPtrData() :
   _ptr(NULL),
   _type(SPT_unknown),
   _updated(true),
@@ -198,7 +202,7 @@ ShaderPtrData() :
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_float &ptr):
@@ -213,7 +217,7 @@ ShaderPtrData(const PTA_float &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_LMatrix4f &ptr):
@@ -228,7 +232,7 @@ ShaderPtrData(const PTA_LMatrix4f &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_LMatrix3f &ptr):
@@ -243,7 +247,7 @@ ShaderPtrData(const PTA_LMatrix3f &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_LVecBase4f &ptr):
@@ -258,7 +262,7 @@ ShaderPtrData(const PTA_LVecBase4f &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_LVecBase3f &ptr):
@@ -273,7 +277,7 @@ ShaderPtrData(const PTA_LVecBase3f &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_LVecBase2f &ptr):
@@ -288,7 +292,7 @@ ShaderPtrData(const PTA_LVecBase2f &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const LVecBase4f &vec) :
@@ -306,7 +310,7 @@ ShaderPtrData(const LVecBase4f &vec) :
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const LVecBase3f &vec) :
@@ -324,7 +328,7 @@ ShaderPtrData(const LVecBase3f &vec) :
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const LVecBase2f &vec) :
@@ -342,7 +346,7 @@ ShaderPtrData(const LVecBase2f &vec) :
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const LMatrix4f &mat) :
@@ -360,7 +364,7 @@ ShaderPtrData(const LMatrix4f &mat) :
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const LMatrix3f &mat) :
@@ -378,7 +382,7 @@ ShaderPtrData(const LMatrix3f &mat) :
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_double &ptr):
@@ -393,7 +397,7 @@ ShaderPtrData(const PTA_double &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_LMatrix4d &ptr):
@@ -408,7 +412,7 @@ ShaderPtrData(const PTA_LMatrix4d &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_LMatrix3d &ptr):
@@ -423,7 +427,7 @@ ShaderPtrData(const PTA_LMatrix3d &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_LVecBase4d &ptr):
@@ -438,7 +442,7 @@ ShaderPtrData(const PTA_LVecBase4d &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_LVecBase3d &ptr):
@@ -453,7 +457,7 @@ ShaderPtrData(const PTA_LVecBase3d &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_LVecBase2d &ptr):
@@ -468,7 +472,7 @@ ShaderPtrData(const PTA_LVecBase2d &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const LVecBase4d &vec) :
@@ -486,7 +490,7 @@ ShaderPtrData(const LVecBase4d &vec) :
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const LVecBase3d &vec) :
@@ -504,7 +508,7 @@ ShaderPtrData(const LVecBase3d &vec) :
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const LVecBase2d &vec) :
@@ -522,7 +526,7 @@ ShaderPtrData(const LVecBase2d &vec) :
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const LMatrix4d &mat) :
@@ -540,7 +544,7 @@ ShaderPtrData(const LMatrix4d &mat) :
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const LMatrix3d &mat) :
@@ -558,7 +562,7 @@ ShaderPtrData(const LMatrix3d &mat) :
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_int &ptr):
@@ -573,7 +577,7 @@ ShaderPtrData(const PTA_int &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_LVecBase4i &ptr):
@@ -588,7 +592,7 @@ ShaderPtrData(const PTA_LVecBase4i &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_LVecBase3i &ptr):
@@ -603,7 +607,7 @@ ShaderPtrData(const PTA_LVecBase3i &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const PTA_LVecBase2i &ptr):
@@ -618,7 +622,7 @@ ShaderPtrData(const PTA_LVecBase2i &ptr):
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const LVecBase4i &vec) :
@@ -636,7 +640,7 @@ ShaderPtrData(const LVecBase4i &vec) :
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const LVecBase3i &vec) :
@@ -654,7 +658,7 @@ ShaderPtrData(const LVecBase3i &vec) :
 ////////////////////////////////////////////////////////////////////
 //  Function: Shader::ShaderPtrData Constructor
 //  Access:
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderPtrData::
 ShaderPtrData(const LVecBase2i &vec) :
@@ -753,8 +757,8 @@ ShaderFile(const string &shared) :
 //  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE Shader::ShaderFile::
-ShaderFile(const string &vertex, 
-           const string &fragment, 
+ShaderFile(const string &vertex,
+           const string &fragment,
            const string &geometry,
            const string &tess_control,
            const string &tess_evaluation) :
@@ -811,3 +815,62 @@ read_datagram(DatagramIterator &scan) {
     _shared = scan.get_string();
   }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: Shader::ShaderFile::operator <
+//       Access: Public
+//  Description: Ordering operator
+////////////////////////////////////////////////////////////////////
+INLINE bool Shader::ShaderFile::
+operator < (const Shader::ShaderFile &other) const {
+  if (_separate != other._separate) {
+    return (!_separate && other._separate);
+  }
+  if (_shared != other._shared) {
+    return (_shared < other._shared);
+  }
+  if (_vertex != other._vertex) {
+    return (_vertex < other._vertex);
+  }
+  if (_fragment != other._fragment) {
+    return (_fragment < other._fragment);
+  }
+  if (_geometry != other._geometry) {
+    return (_geometry < other._geometry);
+  }
+  if (_tess_control != other._tess_control) {
+    return (_tess_control < other._tess_control);
+  }
+  if (_tess_evaluation != other._tess_evaluation) {
+    return (_tess_evaluation < other._tess_evaluation);
+  }
+  if (_compute != other._compute) {
+    return (_compute < other._compute);
+  }
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Shader::get_filename_from_index
+//       Access: Public
+//  Description: Returns the filename of the included shader with
+//               the given source file index (as recorded in the
+//               #line statement in r_preprocess_source).  We use
+//               this to associate error messages with included files.
+////////////////////////////////////////////////////////////////////
+INLINE Filename Shader::
+get_filename_from_index(int index, ShaderType type) const {
+  if (index == 0) {
+    Filename fn = get_filename(type);
+    if (!fn.empty()) {
+      return fn;
+    }
+  } else if (glsl_preprocess && index > 2048 &&
+             (index - 2048) < _included_files.size()) {
+    return _included_files[index - 2048];
+  }
+  // Must be a mistake.  Quietly put back the integer.
+  char str[32];
+  sprintf(str, "%d", index);
+  return Filename(str);
+}

File diff suppressed because it is too large
+ 495 - 198
panda/src/gobj/shader.cxx


+ 32 - 16
panda/src/gobj/shader.h

@@ -81,20 +81,20 @@ PUBLISHED:
     bit_AutoShaderShadow = 4, // bit for AS_shadow
   };
 
-  static PT(Shader) load(const Filename &file, const ShaderLanguage &lang = SL_none);
-  static PT(Shader) make(const string &body, const ShaderLanguage &lang = SL_none);
-  static PT(Shader) load(const ShaderLanguage &lang, 
-                         const Filename &vertex, const Filename &fragment, 
+  static PT(Shader) load(const Filename &file, ShaderLanguage lang = SL_none);
+  static PT(Shader) make(const string &body, ShaderLanguage lang = SL_none);
+  static PT(Shader) load(ShaderLanguage lang,
+                         const Filename &vertex, const Filename &fragment,
                          const Filename &geometry = "",
                          const Filename &tess_control = "",
                          const Filename &tess_evaluation = "");
-  static PT(Shader) load_compute(const ShaderLanguage &lang, const Filename &fn);
-  static PT(Shader) make(const ShaderLanguage &lang, 
-                         const string &vertex, const string &fragment, 
+  static PT(Shader) load_compute(ShaderLanguage lang, const Filename &fn);
+  static PT(Shader) make(ShaderLanguage lang,
+                         const string &vertex, const string &fragment,
                          const string &geometry = "",
                          const string &tess_control = "",
                          const string &tess_evaluation = "");
-  static PT(Shader) make_compute(const ShaderLanguage &lang, const string &body);
+  static PT(Shader) make_compute(ShaderLanguage lang, const string &body);
 
   INLINE Filename get_filename(const ShaderType &type = ST_none) const;
   INLINE const string &get_text(const ShaderType &type = ST_none) const;
@@ -110,7 +110,7 @@ PUBLISHED:
   bool release(PreparedGraphicsObjects *prepared_objects);
   int release_all();
 
-  ShaderContext *prepare_now(PreparedGraphicsObjects *prepared_objects, 
+  ShaderContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
                              GraphicsStateGuardianBase *gsg);
 
 public:
@@ -407,6 +407,8 @@ public:
     INLINE void write_datagram(Datagram &dg) const;
     INLINE void read_datagram(DatagramIterator &source);
 
+    INLINE bool operator < (const ShaderFile &other) const;
+
   public:
     bool _separate;
     string _shared;
@@ -464,8 +466,8 @@ public:
 
   void clear_parameters();
 
-#ifdef HAVE_CG
 private:
+#ifdef HAVE_CG
   ShaderArgClass cg_parameter_class(CGparameter p);
   ShaderArgType cg_parameter_type(CGparameter p);
   ShaderArgDir cg_parameter_dir(CGparameter p);
@@ -496,7 +498,6 @@ private:
   CGprogram cg_program_from_shadertype(ShaderType type);
 
 public:
-
   bool cg_compile_for(const ShaderCaps &caps, CGcontext &ctx,
                       CGprogram &vprogram, CGprogram &fprogram,
                       CGprogram &gprogram, pvector<CGparameter> &map);
@@ -510,19 +511,25 @@ public:
   pvector <ShaderVarSpec> _var_spec;
 
   bool _error_flag;
-  CPT(ShaderFile) _text;
+  ShaderFile _text;
 
 protected:
-  CPT(ShaderFile) _filename;
+  ShaderFile _filename;
   int _parse;
   bool _loaded;
   ShaderLanguage _language;
+  pvector<Filename> _included_files;
+
+  // Stores full paths, and includes the fullpaths of the shaders
+  // themselves as well as the includes.
+  pvector<Filename> _source_files;
+  time_t _last_modified;
 
   static ShaderCaps _default_caps;
   static ShaderUtilization _shader_utilization;
   static int _shaders_generated;
 
-  typedef pmap < CPT(ShaderFile), Shader * > ShaderTable;
+  typedef pmap<ShaderFile, PT(Shader)> ShaderTable;
 
   static ShaderTable _load_table;
   static ShaderTable _make_table;
@@ -536,12 +543,21 @@ protected:
 private:
   void clear_prepared(PreparedGraphicsObjects *prepared_objects);
 
-  Shader();
+  Shader(ShaderLanguage lang);
+
+  bool read(const ShaderFile &sfile);
+  bool do_read_source(string &into, const Filename &fn);
+  bool r_preprocess_source(ostream &out, const Filename &fn,
+                           const Filename &source_dir,
+                           set<Filename> &open_files, int depth = 0);
+
+  bool check_modified() const;
 
 public:
-  Shader(CPT(ShaderFile) name, CPT(ShaderFile) text, const ShaderLanguage &lang = SL_none);
   ~Shader();
 
+  INLINE Filename get_filename_from_index(int index, ShaderType type) const;
+
 public:
   static void register_with_read_factory();
   virtual void write_datagram(BamWriter *manager, Datagram &dg);

+ 19 - 15
panda/src/pgraph/shaderPool.cxx

@@ -74,25 +74,29 @@ ns_load_shader(const Filename &orig_filename) {
     }
   }
 
-/*
-  shader_cat.info()
+  // The shader was not found in the pool.
+  gobj_cat.info()
     << "Loading shader " << filename << "\n";
-*/
-
-  CPT(Shader) shader;
-
-  shader = (CPT(Shader)) NULL;
-  string extension = filename.get_extension();
-
-  if (extension.empty() || extension == "cg" || extension == "hlsl") {
-    // this does nothing for now
-  }
 
-  if (shader == (CPT(Shader)) NULL) {
-    shader = Shader::load (filename);
+  Shader::ShaderLanguage lang = Shader::SL_none;
+
+  // Do some guesswork to see if we can figure out the shader language
+  // from the file extension.  This is really just guesswork - there are
+  // no standardized extensions for shaders, especially for GLSL.
+  // These are the ones that appear to be closest to "standard".
+  string ext = downcase(filename.get_extension());
+  if (ext == "cg" || ext == "sha") {
+    // "sha" is for historical reasons.
+    lang = Shader::SL_Cg;
+
+  } else if (ext == "glsl" || ext == "vert" || ext == "frag" ||
+             ext == "geom" || ext == "tesc" || ext == "tese" ||
+             ext == "comp") {
+    lang = Shader::SL_GLSL;
   }
 
-  if (shader == (CPT(Shader)) NULL) {
+  PT(Shader) shader = Shader::load(filename, lang);
+  if (shader == (Shader *)NULL) {
     // This shader was not found or could not be read.
     return NULL;
   }

+ 1 - 1
panda/src/pgraphnodes/shaderGenerator.cxx

@@ -509,7 +509,7 @@ clear_analysis() {
 ////////////////////////////////////////////////////////////////////
 CPT(RenderAttrib) ShaderGenerator::
 create_shader_attrib(const string &txt) {
-  PT(Shader) shader = Shader::make(txt);
+  PT(Shader) shader = Shader::make(txt, Shader::SL_Cg);
   CPT(RenderAttrib) shattr = ShaderAttrib::make();
   shattr = DCAST(ShaderAttrib, shattr)->set_shader(shader);
   if (_lighting) {

Some files were not shown because too many files changed in this diff