Panda3D

shader.h

00001 // Filename: shader.h
00002 // Created by:  jyelon (01Sep05)
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 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 
00024 #ifdef HAVE_CG
00025 // I don't want to include the Cg header file into panda as a 
00026 // whole.  Instead, I'll just excerpt some opaque declarations.
00027 typedef struct _CGcontext *CGcontext;
00028 typedef struct _CGprogram *CGprogram;
00029 typedef struct _CGparameter *CGparameter;
00030 #endif
00031 
00032 ////////////////////////////////////////////////////////////////////
00033 //       Class : Shader
00034 //      Summary: 
00035 ////////////////////////////////////////////////////////////////////
00036 
00037 class EXPCL_PANDA_GOBJ Shader: public TypedReferenceCount {
00038 
00039 PUBLISHED:
00040   
00041   enum ShaderLanguage {
00042     SL_none,
00043     SL_Cg,
00044     SL_GLSL
00045   };
00046   enum ShaderType {
00047     ST_none = 0,
00048     ST_vertex,
00049     ST_fragment,
00050     ST_geometry,
00051   };
00052 
00053   static PT(Shader) load(const Filename &file, const ShaderLanguage &lang = SL_none);
00054   static PT(Shader) make(const string &body, const ShaderLanguage &lang = SL_none);
00055   static PT(Shader) load(const ShaderLanguage &lang, const Filename &vertex, const Filename &fragment, const Filename &geometry = "");
00056   static PT(Shader) make(const ShaderLanguage &lang, const string &vertex, const string &fragment, const string &geometry = "");
00057 
00058   INLINE const Filename get_filename(const ShaderType &type = ST_none) const;
00059   INLINE const string   get_text(const ShaderType &type = ST_none) const;
00060   INLINE const bool get_error_flag() const;
00061   INLINE const ShaderLanguage get_language() const;
00062 
00063   INLINE static ShaderUtilization get_shader_utilization();
00064   INLINE static void set_shader_utilization(ShaderUtilization utl);
00065   INLINE static bool have_shader_utilization();
00066 
00067   void prepare(PreparedGraphicsObjects *prepared_objects);
00068   bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
00069   bool release(PreparedGraphicsObjects *prepared_objects);
00070   int release_all();
00071 
00072   ShaderContext *prepare_now(PreparedGraphicsObjects *prepared_objects, 
00073                              GraphicsStateGuardianBase *gsg);
00074 
00075 public:
00076 
00077   enum ShaderMatInput {
00078     SMO_identity,
00079 
00080     SMO_window_size,
00081     SMO_pixel_size,
00082     SMO_texpad_x,
00083     SMO_texpix_x,
00084     
00085     SMO_attr_material,
00086     SMO_attr_color,
00087     SMO_attr_colorscale,
00088     
00089     SMO_alight_x,
00090     SMO_dlight_x,
00091     SMO_plight_x,
00092     SMO_slight_x,
00093     SMO_satten_x,
00094     SMO_texmat_x,
00095     SMO_plane_x,
00096     SMO_clipplane_x,
00097     
00098     SMO_mat_constant_x,
00099     SMO_vec_constant_x,
00100     
00101     SMO_world_to_view,
00102     SMO_view_to_world,
00103 
00104     SMO_model_to_view,
00105     SMO_view_to_model,
00106 
00107     SMO_apiview_to_view,
00108     SMO_view_to_apiview,
00109 
00110     SMO_clip_to_view,
00111     SMO_view_to_clip,
00112 
00113     SMO_apiclip_to_view,
00114     SMO_view_to_apiclip,
00115     
00116     SMO_view_x_to_view,
00117     SMO_view_to_view_x,
00118 
00119     SMO_apiview_x_to_view,
00120     SMO_view_to_apiview_x,
00121 
00122     SMO_clip_x_to_view,
00123     SMO_view_to_clip_x,
00124 
00125     SMO_apiclip_x_to_view,
00126     SMO_view_to_apiclip_x,
00127     
00128     SMO_INVALID
00129   };
00130 
00131   enum ShaderArgType {
00132     SAT_float1,
00133     SAT_float2,
00134     SAT_float3,
00135     SAT_float4,
00136     SAT_float4x4,
00137     SAT_sampler1d,
00138     SAT_sampler2d,
00139     SAT_sampler3d,
00140     SAT_samplercube,
00141     SAT_unknown,
00142   };
00143 
00144   enum ShaderArgDir {
00145     SAD_in,
00146     SAD_out,
00147     SAD_inout,
00148     SAD_unknown,
00149   };
00150 
00151   enum ShaderMatPiece {
00152     SMP_whole,
00153     SMP_transpose,
00154     SMP_row0,
00155     SMP_row1,
00156     SMP_row2,
00157     SMP_row3,
00158     SMP_col0,
00159     SMP_col1,
00160     SMP_col2,
00161     SMP_col3,
00162     SMP_row3x1,
00163     SMP_row3x2,
00164     SMP_row3x3,
00165   };
00166   
00167   enum ShaderStateDep {
00168     SSD_NONE          =  0,
00169     SSD_general       =  1,
00170     SSD_transform     =  2,
00171     SSD_color         =  4,
00172     SSD_colorscale    =  8,
00173     SSD_material      = 16,
00174     SSD_shaderinputs  = 32,
00175   };
00176 
00177   enum ShaderBug {
00178     SBUG_ati_draw_buffers,
00179   };
00180   
00181   enum ShaderMatFunc {
00182     SMF_compose,
00183     SMF_transform_dlight,
00184     SMF_transform_plight,
00185     SMF_transform_slight,
00186     SMF_first,
00187   };
00188 
00189   struct ShaderArgId {
00190     string     _name;
00191     ShaderType _type;
00192     int        _seqno;
00193   };
00194   
00195   struct ShaderMatSpec {
00196     ShaderArgId       _id;
00197     ShaderMatFunc     _func;
00198     ShaderMatInput    _part[2];
00199     PT(InternalName)  _arg[2];
00200     int               _dep[2];
00201     LMatrix4f         _cache[2];
00202     LMatrix4f         _value;
00203     ShaderMatPiece    _piece;
00204   };
00205 
00206   struct ShaderTexSpec {
00207     ShaderArgId       _id;
00208     PT(InternalName)  _name;
00209     int               _stage;
00210     int               _desired_type;
00211     PT(InternalName)  _suffix;
00212   };
00213 
00214   struct ShaderVarSpec {
00215     ShaderArgId       _id;
00216     PT(InternalName)  _name;
00217     int               _append_uv;
00218   };
00219 
00220   struct ShaderArgInfo {
00221     ShaderArgId       _id;
00222     ShaderArgType     _type;
00223     ShaderArgDir      _direction;
00224     bool              _varying;
00225     NotifyCategory   *_cat;
00226   };
00227 
00228   struct ShaderCaps {
00229     bool _supports_glsl;
00230 
00231 #ifdef HAVE_CG
00232     int _active_vprofile;
00233     int _active_fprofile;
00234     int _active_gprofile;
00235 
00236     int _ultimate_vprofile;
00237     int _ultimate_fprofile;
00238     int _ultimate_gprofile;
00239 
00240     pset <ShaderBug> _bug_list;
00241 #endif
00242     void clear();
00243     INLINE bool operator == (const ShaderCaps &other) const;
00244     INLINE ShaderCaps();
00245   };
00246 
00247   struct ShaderFile : public ReferenceCount {
00248     ShaderFile(string shared) { _separate = false; _shared = shared; }
00249     ShaderFile(string vertex, string fragment, string geometry = "") {
00250       _separate = true;     _vertex   = vertex;
00251       _fragment = fragment; _geometry = geometry;
00252     }
00253     bool _separate;
00254     string _shared;
00255     string _vertex;
00256     string _fragment;
00257     string _geometry;
00258   };
00259 
00260  private:
00261   // These routines help split the shader into sections,
00262   // for those shader implementations that need to do so.
00263   // Don't use them when you use separate shader programs.
00264   void parse_init();
00265   void parse_line(string &result, bool rt, bool lt);
00266   void parse_upto(string &result, string pattern, bool include);
00267   void parse_rest(string &result);
00268   bool parse_eof();
00269   
00270   void cp_report_error(ShaderArgInfo &arg, const string &msg);
00271   bool cp_errchk_parameter_words(ShaderArgInfo &arg, int len);
00272   bool cp_errchk_parameter_in(ShaderArgInfo &arg);
00273   bool cp_errchk_parameter_varying(ShaderArgInfo &arg);
00274   bool cp_errchk_parameter_uniform(ShaderArgInfo &arg);
00275   bool cp_errchk_parameter_float(ShaderArgInfo &arg, int lo, int hi);
00276   bool cp_errchk_parameter_sampler(ShaderArgInfo &arg);
00277   bool cp_parse_eol(ShaderArgInfo &arg,
00278                     vector_string &pieces, int &next);
00279   bool cp_parse_delimiter(ShaderArgInfo &arg, 
00280                           vector_string &pieces, int &next);
00281   string cp_parse_non_delimiter(vector_string &pieces, int &next);
00282   bool cp_parse_coord_sys(ShaderArgInfo &arg,
00283                           vector_string &pieces, int &next,
00284                           ShaderMatSpec &spec, bool fromflag);
00285   int cp_dependency(ShaderMatInput inp);
00286   void cp_optimize_mat_spec(ShaderMatSpec &spec);
00287   
00288   bool compile_parameter(const ShaderArgId    &arg_id,
00289                          ShaderArgType         arg_type,
00290                          ShaderArgDir          arg_direction,
00291                          bool                  arg_varying,
00292                          NotifyCategory       *arg_cat);
00293 
00294   void clear_parameters();
00295 
00296  public:
00297   pvector<int> _glsl_parameter_map;
00298 
00299 #ifdef HAVE_CG
00300  private:
00301   ShaderArgType cg_parameter_type(CGparameter p);
00302   ShaderArgDir  cg_parameter_dir(CGparameter p);
00303 
00304   CGprogram     cg_compile_entry_point(const char *entry, const ShaderCaps &caps, ShaderType type = ST_vertex);
00305 
00306   bool          cg_analyze_entry_point(CGprogram prog, ShaderType type);
00307 
00308   bool          cg_analyze_shader(const ShaderCaps &caps);
00309   bool          cg_compile_shader(const ShaderCaps &caps);
00310   void          cg_release_resources();
00311   void          cg_report_errors();
00312   
00313   // Determines the appropriate cg profile settings and stores them in the active shader caps
00314   // based on any profile settings stored in the shader's header
00315   void          cg_get_profile_from_header(ShaderCaps& caps);
00316 
00317   ShaderCaps _cg_last_caps;
00318   CGcontext  _cg_context;
00319   CGprogram  _cg_vprogram;
00320   CGprogram  _cg_fprogram;
00321   CGprogram  _cg_gprogram;
00322 
00323   int        _cg_vprofile;
00324   int        _cg_fprofile;
00325   int        _cg_gprofile;
00326 
00327   CGprogram     cg_program_from_shadertype(ShaderType type);
00328 
00329  public:
00330 
00331   bool          cg_compile_for(const ShaderCaps &caps,
00332                                CGcontext &ctx,
00333                                CGprogram &vprogram,
00334                                CGprogram &fprogram,
00335                                CGprogram &gprogram,
00336                                pvector<CGparameter> &map);
00337   
00338 #endif
00339 
00340  public:
00341   pvector <ShaderMatSpec> _mat_spec;
00342   pvector <ShaderTexSpec> _tex_spec;
00343   pvector <ShaderVarSpec> _var_spec;
00344   
00345   bool           _error_flag;
00346   CPT(ShaderFile) _text;
00347 
00348  protected:
00349   CPT(ShaderFile)_filename;
00350   int            _parse;
00351   bool           _loaded;
00352   ShaderLanguage _language;
00353   
00354   static ShaderCaps _default_caps;
00355   static ShaderUtilization _shader_utilization;
00356   static int _shaders_generated;
00357 
00358   typedef pmap < CPT(ShaderFile), Shader * > ShaderTable;
00359 
00360   static ShaderTable _load_table;
00361   static ShaderTable _make_table;
00362 
00363   friend class ShaderContext;
00364   friend class PreparedGraphicsObjects;
00365 
00366   typedef pmap <PreparedGraphicsObjects *, ShaderContext *> Contexts;
00367   Contexts _contexts;
00368 
00369  private:  
00370   void clear_prepared(PreparedGraphicsObjects *prepared_objects);
00371 
00372  public:
00373   Shader(CPT(ShaderFile) name, CPT(ShaderFile) text, const ShaderLanguage &lang = SL_none);
00374   static void register_with_read_factory();
00375   
00376   ~Shader();
00377   
00378  public:
00379   static TypeHandle get_class_type() {
00380     return _type_handle;
00381   }
00382   static void init_type() {
00383     TypedReferenceCount::init_type();
00384     register_type(_type_handle, "Shader",
00385                   TypedReferenceCount::get_class_type());
00386   }
00387   virtual TypeHandle get_type() const {
00388     return get_class_type();
00389   }
00390   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00391 
00392  private:
00393   static TypeHandle _type_handle;
00394 };
00395 
00396 #include "shader.I"
00397 
00398 #endif
 All Classes Functions Variables Enumerations