Panda3D

shader.h

00001 // Filename: shader.h
00002 // Created by: jyelon (01Sep05)
00003 // Updated by: fperazzi, PandaSE(29Apr10) (added SAT_sampler2dArray)
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 SHADER_H
00016 #define SHADER_H
00017 
00018 #include "pandabase.h"
00019 #include "typedReferenceCount.h"
00020 #include "namable.h"
00021 #include "graphicsStateGuardianBase.h"
00022 #include "internalName.h"
00023 #include "pta_float.h"
00024 #include "pta_double.h"
00025 #include "pta_stdfloat.h"
00026 #include "pta_LMatrix4.h"
00027 #include "pta_LMatrix3.h"
00028 #include "pta_LVecBase4.h"
00029 #include "pta_LVecBase3.h"
00030 #include "pta_LVecBase2.h"
00031 
00032 #ifdef HAVE_CG
00033 // I don't want to include the Cg header file into panda as a 
00034 // whole.  Instead, I'll just excerpt some opaque declarations.
00035 typedef struct _CGcontext   *CGcontext;
00036 typedef struct _CGprogram   *CGprogram;
00037 typedef struct _CGparameter *CGparameter;
00038 #endif
00039 
00040 ////////////////////////////////////////////////////////////////////
00041 //       Class : Shader
00042 //      Summary: The Shader class is meant to select the Shader Language,
00043 //               select the available profile, compile the shader, and 
00044 //               finally compile and store the shader parameters  
00045 //               in the appropriate structure.
00046 ////////////////////////////////////////////////////////////////////
00047 class EXPCL_PANDA_GOBJ Shader: public TypedReferenceCount {
00048 
00049 PUBLISHED:
00050   
00051   enum ShaderLanguage {
00052     SL_none,
00053     SL_Cg,
00054     SL_GLSL
00055   };
00056 
00057   enum ShaderType {
00058     ST_none = 0,
00059     ST_vertex,
00060     ST_fragment,
00061     ST_geometry,
00062   };
00063 
00064   enum AutoShaderSwitch {
00065     AS_normal = 0x01,
00066     AS_glow   = 0x02,
00067     AS_gloss  = 0x04,
00068     AS_ramp   = 0x08,
00069     AS_shadow = 0x10,
00070   };
00071 
00072   enum AutoShaderBit {
00073     bit_AutoShaderNormal = 0, // bit for AS_normal
00074     bit_AutoShaderGlow   = 1, // bit for AS_glow
00075     bit_AutoShaderGloss  = 2, // bit for AS_gloss
00076     bit_AutoShaderRamp   = 3, // bit for AS_ramp
00077     bit_AutoShaderShadow = 4, // bit for AS_shadow
00078   };
00079 
00080   static PT(Shader) load(const Filename &file, const ShaderLanguage &lang = SL_none);
00081   static PT(Shader) make(const string &body, const ShaderLanguage &lang = SL_none);
00082   static PT(Shader) load(const ShaderLanguage &lang, const Filename &vertex, const Filename &fragment, const Filename &geometry = "");
00083   static PT(Shader) make(const ShaderLanguage &lang, const string &vertex, const string &fragment, const string &geometry = "");
00084 
00085   INLINE const Filename get_filename(const ShaderType &type = ST_none) const;
00086   INLINE const string &get_text(const ShaderType &type = ST_none) const;
00087   INLINE const bool get_error_flag() const;
00088   INLINE const ShaderLanguage get_language() const;
00089 
00090   INLINE static ShaderUtilization get_shader_utilization();
00091   INLINE static void set_shader_utilization(ShaderUtilization utl);
00092   INLINE static bool have_shader_utilization();
00093 
00094   void prepare(PreparedGraphicsObjects *prepared_objects);
00095   bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
00096   bool release(PreparedGraphicsObjects *prepared_objects);
00097   int release_all();
00098 
00099   ShaderContext *prepare_now(PreparedGraphicsObjects *prepared_objects, 
00100                              GraphicsStateGuardianBase *gsg);
00101 
00102 public:
00103 
00104   enum ShaderMatInput {
00105     SMO_identity,
00106 
00107     SMO_window_size,
00108     SMO_pixel_size,
00109     SMO_texpad_x,
00110     SMO_texpix_x,
00111     
00112     SMO_attr_material,
00113     SMO_attr_color,
00114     SMO_attr_colorscale,
00115     
00116     SMO_alight_x,
00117     SMO_dlight_x,
00118     SMO_plight_x,
00119     SMO_slight_x,
00120     SMO_satten_x,
00121     SMO_texmat_x,
00122     SMO_plane_x,
00123     SMO_clipplane_x,
00124     
00125     SMO_mat_constant_x,
00126     SMO_vec_constant_x,
00127 
00128     SMO_world_to_view,
00129     SMO_view_to_world,
00130 
00131     SMO_model_to_view,
00132     SMO_view_to_model,
00133 
00134     SMO_apiview_to_view,
00135     SMO_view_to_apiview,
00136 
00137     SMO_clip_to_view,
00138     SMO_view_to_clip,
00139 
00140     SMO_apiclip_to_view,
00141     SMO_view_to_apiclip,
00142     
00143     SMO_view_x_to_view,
00144     SMO_view_to_view_x,
00145 
00146     SMO_apiview_x_to_view,
00147     SMO_view_to_apiview_x,
00148 
00149     SMO_clip_x_to_view,
00150     SMO_view_to_clip_x,
00151 
00152     SMO_apiclip_x_to_view,
00153     SMO_view_to_apiclip_x,
00154 
00155     SMO_attr_fog,
00156     SMO_attr_fogcolor,
00157     
00158     SMO_INVALID
00159   };
00160   
00161   enum ShaderArgClass { 
00162     SAC_scalar,
00163     SAC_vector,
00164     SAC_matrix,
00165     SAC_sampler,
00166     SAC_array,
00167     SAC_unknown,
00168   };
00169   
00170   enum ShaderArgType { 
00171     SAT_scalar,     
00172     SAT_vec1,       
00173     SAT_vec2,       
00174     SAT_vec3,       
00175     SAT_vec4,       
00176     SAT_mat1x1,   
00177     SAT_mat1x2,  
00178     SAT_mat1x3, 
00179     SAT_mat1x4,
00180     SAT_mat2x1,
00181     SAT_mat2x2,   
00182     SAT_mat2x3,  
00183     SAT_mat2x4, 
00184     SAT_mat3x1, 
00185     SAT_mat3x2, 
00186     SAT_mat3x3,   
00187     SAT_mat3x4,  
00188     SAT_mat4x1,  
00189     SAT_mat4x2,  
00190     SAT_mat4x3,  
00191     SAT_mat4x4,
00192     SAT_sampler1d,
00193     SAT_sampler2d,
00194     SAT_sampler3d,
00195     SAT_sampler2dArray,
00196     SAT_samplercube,
00197     SAT_unknown
00198 };
00199 
00200   enum ShaderArgDir {
00201     SAD_in,
00202     SAD_out,
00203     SAD_inout,
00204     SAD_unknown,
00205   };
00206 
00207   enum ShaderMatPiece {
00208     SMP_whole,
00209     SMP_transpose,
00210     SMP_row0,
00211     SMP_row1,
00212     SMP_row2,
00213     SMP_row3,
00214     SMP_col0,
00215     SMP_col1,
00216     SMP_col2,
00217     SMP_col3,
00218     SMP_row3x1,
00219     SMP_row3x2,
00220     SMP_row3x3,
00221   };
00222   
00223   enum ShaderStateDep {
00224     SSD_NONE          =  0,
00225     SSD_general       =  1,
00226     SSD_transform     =  2,
00227     SSD_color         =  4,
00228     SSD_colorscale    =  8,
00229     SSD_material      = 16,
00230     SSD_shaderinputs  = 32,
00231     SSD_fog           = 64,
00232   };
00233 
00234   enum ShaderBug {
00235     SBUG_ati_draw_buffers,
00236   };
00237   
00238   enum ShaderMatFunc {
00239     SMF_compose,
00240     SMF_transform_dlight,
00241     SMF_transform_plight,
00242     SMF_transform_slight,
00243     SMF_first,
00244   };
00245  
00246   struct ShaderArgId {
00247     string     _name;
00248     ShaderType _type;
00249     int        _seqno;
00250   }; 
00251   
00252   struct ShaderArgInfo {  
00253     ShaderArgId       _id;
00254     ShaderArgClass    _class;
00255     ShaderArgClass    _subclass;
00256     ShaderArgType     _type;      
00257     ShaderArgDir      _direction;
00258     bool              _varying;
00259     NotifyCategory   *_cat;
00260   };
00261  
00262   enum ShaderPtrType {
00263     SPT_float,
00264     SPT_double,
00265     SPT_unknown
00266   };  
00267   
00268   // Container structure for data of parameters ShaderPtrSpec.
00269   struct ShaderPtrData {
00270   private:
00271     PT(ReferenceCount) _pta;
00272 
00273   public:
00274     void *_ptr; 
00275     ShaderPtrType _type;
00276     bool _updated;
00277     int _size; //number of elements vec3[4]=12
00278 
00279   public:
00280     INLINE ShaderPtrData();
00281     INLINE ShaderPtrData(const PTA_float &ptr);
00282     INLINE ShaderPtrData(const PTA_LVecBase4f &ptr);
00283     INLINE ShaderPtrData(const PTA_LVecBase3f &ptr);
00284     INLINE ShaderPtrData(const PTA_LVecBase2f &ptr);
00285     INLINE ShaderPtrData(const PTA_LMatrix4f &mat);
00286     INLINE ShaderPtrData(const PTA_LMatrix3f &mat);
00287     INLINE ShaderPtrData(const LVecBase4f &vec);
00288     INLINE ShaderPtrData(const LVecBase3f &vec);
00289     INLINE ShaderPtrData(const LVecBase2f &vec);
00290     INLINE ShaderPtrData(const LMatrix4f &mat);
00291     INLINE ShaderPtrData(const LMatrix3f &mat);
00292 
00293     INLINE ShaderPtrData(const PTA_double &ptr);
00294     INLINE ShaderPtrData(const PTA_LVecBase4d &ptr);
00295     INLINE ShaderPtrData(const PTA_LVecBase3d &ptr);
00296     INLINE ShaderPtrData(const PTA_LVecBase2d &ptr);
00297     INLINE ShaderPtrData(const PTA_LMatrix4d &mat);
00298     INLINE ShaderPtrData(const PTA_LMatrix3d &mat);
00299     INLINE ShaderPtrData(const LVecBase4d &vec);
00300     INLINE ShaderPtrData(const LVecBase3d &vec);
00301     INLINE ShaderPtrData(const LVecBase2d &vec);
00302     INLINE ShaderPtrData(const LMatrix4d &mat);
00303     INLINE ShaderPtrData(const LMatrix3d &mat);
00304   };
00305 
00306   struct ShaderMatSpec {
00307     ShaderArgId       _id;
00308     ShaderMatFunc     _func;
00309     ShaderMatInput    _part[2];
00310     PT(InternalName)  _arg[2];
00311     int               _dep[2];
00312     LMatrix4          _cache[2];
00313     LMatrix4          _value;
00314     ShaderMatPiece    _piece;
00315   };
00316 
00317   struct ShaderTexSpec {
00318     ShaderArgId       _id;
00319     PT(InternalName)  _name;
00320     int               _stage;
00321     int               _desired_type;
00322     PT(InternalName)  _suffix;
00323   };
00324 
00325   struct ShaderVarSpec {
00326     ShaderArgId       _id;
00327     PT(InternalName)  _name;
00328     int               _append_uv;
00329   };
00330   
00331   struct ShaderPtrSpec { 
00332     ShaderArgId       _id;
00333     int               _dim[3]; //n_elements,rows,cols
00334     int               _dep[2];
00335     PT(InternalName)  _arg;
00336     ShaderArgInfo     _info;
00337   };
00338 
00339   struct ShaderCaps {
00340     bool _supports_glsl;
00341 
00342 #ifdef HAVE_CG
00343     int _active_vprofile;
00344     int _active_fprofile;
00345     int _active_gprofile;
00346 
00347     int _ultimate_vprofile;
00348     int _ultimate_fprofile;
00349     int _ultimate_gprofile;
00350 
00351     pset <ShaderBug> _bug_list;
00352 #endif
00353     void clear();
00354     INLINE bool operator == (const ShaderCaps &other) const;
00355     INLINE ShaderCaps();
00356   };
00357 
00358   struct ShaderFile : public ReferenceCount {
00359     ShaderFile(string shared) { _separate = false; _shared = shared; }
00360     ShaderFile(string vertex, string fragment, string geometry = "") {
00361       _separate = true;     _vertex   = vertex;
00362       _fragment = fragment; _geometry = geometry;
00363     }
00364     bool _separate;
00365     string _shared;
00366     string _vertex;
00367     string _fragment;
00368     string _geometry;
00369   };
00370 
00371  private:
00372   // These routines help split the shader into sections,
00373   // for those shader implementations that need to do so.
00374   // Don't use them when you use separate shader programs.
00375   void parse_init();
00376   void parse_line(string &result, bool rt, bool lt);
00377   void parse_upto(string &result, string pattern, bool include);
00378   void parse_rest(string &result);
00379   bool parse_eof();
00380   
00381   void cp_report_error(ShaderArgInfo &arg, const string &msg);
00382   bool cp_errchk_parameter_words(ShaderArgInfo &arg, int len);
00383   bool cp_errchk_parameter_in(ShaderArgInfo &arg);
00384   bool cp_errchk_parameter_ptr(ShaderArgInfo &p); 
00385   bool cp_errchk_parameter_varying(ShaderArgInfo &arg);
00386   bool cp_errchk_parameter_uniform(ShaderArgInfo &arg);
00387   bool cp_errchk_parameter_float(ShaderArgInfo &arg, int lo, int hi);
00388   bool cp_errchk_parameter_sampler(ShaderArgInfo &arg);
00389   bool cp_parse_eol(ShaderArgInfo &arg,
00390                     vector_string &pieces, int &next);
00391   bool cp_parse_delimiter(ShaderArgInfo &arg, 
00392                           vector_string &pieces, int &next);
00393   string cp_parse_non_delimiter(vector_string &pieces, int &next);
00394   bool cp_parse_coord_sys(ShaderArgInfo &arg,
00395                           vector_string &pieces, int &next,
00396                           ShaderMatSpec &spec, bool fromflag);
00397   int cp_dependency(ShaderMatInput inp);
00398   void cp_optimize_mat_spec(ShaderMatSpec &spec);
00399 
00400 #ifdef HAVE_CG
00401   void cg_recurse_parameters(CGparameter parameter, 
00402                           const ShaderType &type, 
00403                           bool &success);
00404 #endif
00405   
00406   bool compile_parameter(const ShaderArgId        &arg_id, 
00407                          const ShaderArgClass     &arg_class,
00408                          const ShaderArgClass     &arg_subclass,
00409                          const ShaderArgType      &arg_type,
00410                          const ShaderArgDir       &arg_direction,
00411                          bool                      arg_varying,
00412                          int                      *arg_dim,
00413                          NotifyCategory           *arg_cat);
00414 
00415   void clear_parameters();
00416 
00417  public:
00418   pvector<int> _glsl_parameter_map;
00419 
00420 #ifdef HAVE_CG
00421  private:
00422   ShaderArgClass    cg_parameter_class(CGparameter p); 
00423   ShaderArgType     cg_parameter_type(CGparameter p);
00424   ShaderArgDir      cg_parameter_dir(CGparameter p);
00425 
00426   CGprogram     cg_compile_entry_point(const char *entry, const ShaderCaps &caps, ShaderType type = ST_vertex);
00427 
00428   bool          cg_analyze_entry_point(CGprogram prog, ShaderType type);
00429 
00430   bool          cg_analyze_shader(const ShaderCaps &caps);
00431   bool          cg_compile_shader(const ShaderCaps &caps);
00432   void          cg_release_resources();
00433   void          cg_report_errors();
00434   
00435   // Determines the appropriate cg profile settings and stores them in the active shader caps
00436   // based on any profile settings stored in the shader's header
00437   void          cg_get_profile_from_header(ShaderCaps &caps);
00438 
00439   ShaderCaps _cg_last_caps;
00440   CGcontext  _cg_context;
00441   CGprogram  _cg_vprogram;
00442   CGprogram  _cg_fprogram;
00443   CGprogram  _cg_gprogram;
00444 
00445   int        _cg_vprofile;
00446   int        _cg_fprofile;
00447   int        _cg_gprofile;
00448 
00449   CGprogram     cg_program_from_shadertype(ShaderType type);
00450 
00451  public:
00452 
00453   bool          cg_compile_for(const ShaderCaps &caps,
00454                                CGcontext &ctx,
00455                                CGprogram &vprogram,
00456                                CGprogram &fprogram,
00457                                CGprogram &gprogram,
00458                                pvector<CGparameter> &map);
00459   
00460 #endif
00461 
00462  public:
00463   pvector <ShaderPtrSpec> _ptr_spec; 
00464   epvector <ShaderMatSpec> _mat_spec;
00465   pvector <ShaderTexSpec> _tex_spec;
00466   pvector <ShaderVarSpec> _var_spec;
00467   
00468   bool           _error_flag;
00469   CPT(ShaderFile) _text;
00470 
00471  protected:
00472   CPT(ShaderFile) _filename; 
00473   int            _parse;
00474   bool           _loaded;
00475   ShaderLanguage _language;
00476   
00477   static ShaderCaps _default_caps;
00478   static ShaderUtilization _shader_utilization;
00479   static int _shaders_generated;
00480 
00481   typedef pmap < CPT(ShaderFile), Shader * > ShaderTable;
00482 
00483   static ShaderTable _load_table;
00484   static ShaderTable _make_table;
00485 
00486   friend class ShaderContext;
00487   friend class PreparedGraphicsObjects;
00488 
00489   typedef pmap <PreparedGraphicsObjects *, ShaderContext *> Contexts;
00490   Contexts _contexts;
00491 
00492  private:  
00493   void clear_prepared(PreparedGraphicsObjects *prepared_objects);
00494 
00495  public:
00496   Shader(CPT(ShaderFile) name, CPT(ShaderFile) text, const ShaderLanguage &lang = SL_none);
00497   static void register_with_read_factory();
00498   
00499   ~Shader();
00500   
00501  public:
00502   static TypeHandle get_class_type() {
00503     return _type_handle;
00504   }
00505   static void init_type() {
00506     TypedReferenceCount::init_type();
00507     register_type(_type_handle, "Shader",
00508                   TypedReferenceCount::get_class_type());
00509   }
00510   virtual TypeHandle get_type() const {
00511     return get_class_type();
00512   }
00513   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00514 
00515  private:
00516   static TypeHandle _type_handle;
00517 };
00518 
00519 #include "shader.I"
00520 
00521 #endif
 All Classes Functions Variables Enumerations