Panda3D
 All Classes Functions Variables Enumerations
shader.h
1 // Filename: shader.h
2 // Created by: jyelon (01Sep05)
3 // Updated by: fperazzi, PandaSE(29Apr10) (added SAT_sampler2dArray)
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #ifndef SHADER_H
16 #define SHADER_H
17 
18 #include "pandabase.h"
19 #include "config_gobj.h"
20 #include "typedWritableReferenceCount.h"
21 #include "namable.h"
22 #include "graphicsStateGuardianBase.h"
23 #include "internalName.h"
24 #include "pta_int.h"
25 #include "pta_float.h"
26 #include "pta_double.h"
27 #include "pta_stdfloat.h"
28 #include "pta_LMatrix4.h"
29 #include "pta_LMatrix3.h"
30 #include "pta_LVecBase4.h"
31 #include "pta_LVecBase3.h"
32 #include "pta_LVecBase2.h"
33 #include "epvector.h"
34 
35 #ifdef HAVE_CG
36 // I don't want to include the Cg header file into panda as a
37 // whole. Instead, I'll just excerpt some opaque declarations.
38 typedef struct _CGcontext *CGcontext;
39 typedef struct _CGprogram *CGprogram;
40 typedef struct _CGparameter *CGparameter;
41 #endif
42 
43 ////////////////////////////////////////////////////////////////////
44 // Class : Shader
45 // Summary: The Shader class is meant to select the Shader Language,
46 // select the available profile, compile the shader, and
47 // finally compile and store the shader parameters
48 // in the appropriate structure.
49 ////////////////////////////////////////////////////////////////////
50 class EXPCL_PANDA_GOBJ Shader : public TypedWritableReferenceCount {
51 PUBLISHED:
52  enum ShaderLanguage {
53  SL_none,
54  SL_Cg,
55  SL_GLSL
56  };
57 
58  enum ShaderType {
59  ST_none = 0,
60  ST_vertex,
61  ST_fragment,
62  ST_geometry,
63  ST_tess_control,
64  ST_tess_evaluation,
65  ST_compute,
66  ST_COUNT
67  };
68 
69  enum AutoShaderSwitch {
70  AS_normal = 0x01,
71  AS_glow = 0x02,
72  AS_gloss = 0x04,
73  AS_ramp = 0x08,
74  AS_shadow = 0x10,
75  };
76 
77  enum AutoShaderBit {
78  bit_AutoShaderNormal = 0, // bit for AS_normal
79  bit_AutoShaderGlow = 1, // bit for AS_glow
80  bit_AutoShaderGloss = 2, // bit for AS_gloss
81  bit_AutoShaderRamp = 3, // bit for AS_ramp
82  bit_AutoShaderShadow = 4, // bit for AS_shadow
83  };
84 
85  static PT(Shader) load(const Filename &file, ShaderLanguage lang = SL_none);
86  static PT(Shader) make(const string &body, ShaderLanguage lang = SL_none);
87  static PT(Shader) load(ShaderLanguage lang,
88  const Filename &vertex, const Filename &fragment,
89  const Filename &geometry = "",
90  const Filename &tess_control = "",
91  const Filename &tess_evaluation = "");
92  static PT(Shader) load_compute(ShaderLanguage lang, const Filename &fn);
93  static PT(Shader) make(ShaderLanguage lang,
94  const string &vertex, const string &fragment,
95  const string &geometry = "",
96  const string &tess_control = "",
97  const string &tess_evaluation = "");
98  static PT(Shader) make_compute(ShaderLanguage lang, const string &body);
99 
100  INLINE Filename get_filename(const ShaderType &type = ST_none) const;
101  INLINE const string &get_text(const ShaderType &type = ST_none) const;
102  INLINE bool get_error_flag() const;
103  INLINE ShaderLanguage get_language() const;
104 
105  INLINE static ShaderUtilization get_shader_utilization();
106  INLINE static void set_shader_utilization(ShaderUtilization utl);
107  INLINE static bool have_shader_utilization();
108 
109  void prepare(PreparedGraphicsObjects *prepared_objects);
110  bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
111  bool release(PreparedGraphicsObjects *prepared_objects);
112  int release_all();
113 
114  ShaderContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
116 
117 public:
118  enum ShaderMatInput {
119  SMO_identity,
120 
121  SMO_window_size,
122  SMO_pixel_size,
123  SMO_texpad_x,
124  SMO_texpix_x,
125 
126  SMO_attr_material,
127  SMO_attr_color,
128  SMO_attr_colorscale,
129 
130  SMO_alight_x,
131  SMO_dlight_x,
132  SMO_plight_x,
133  SMO_slight_x,
134  SMO_satten_x,
135  SMO_texmat_x,
136  SMO_plane_x,
137  SMO_clipplane_x,
138 
139  SMO_mat_constant_x,
140  SMO_vec_constant_x,
141 
142  SMO_world_to_view,
143  SMO_view_to_world,
144 
145  SMO_model_to_view,
146  SMO_view_to_model,
147 
148  SMO_apiview_to_view,
149  SMO_view_to_apiview,
150 
151  SMO_clip_to_view,
152  SMO_view_to_clip,
153 
154  SMO_apiclip_to_view,
155  SMO_view_to_apiclip,
156 
157  SMO_view_x_to_view,
158  SMO_view_to_view_x,
159 
160  SMO_apiview_x_to_view,
161  SMO_view_to_apiview_x,
162 
163  SMO_clip_x_to_view,
164  SMO_view_to_clip_x,
165 
166  SMO_apiclip_x_to_view,
167  SMO_view_to_apiclip_x,
168 
169  SMO_attr_fog,
170  SMO_attr_fogcolor,
171 
172  SMO_frame_number,
173  SMO_frame_time,
174  SMO_frame_delta,
175 
176  SMO_mat_constant_x_attrib,
177  SMO_vec_constant_x_attrib,
178 
179  SMO_light_ambient,
180  SMO_light_source_i_attrib,
181 
182  SMO_light_product_i_ambient,
183  SMO_light_product_i_diffuse,
184  SMO_light_product_i_specular,
185 
186  // SMO_clipplane_x is world coords, GLSL needs eye coords
187  SMO_apiview_clipplane_i,
188 
189  SMO_model_to_apiview,
190  SMO_apiview_to_model,
191  SMO_apiview_to_apiclip,
192  SMO_apiclip_to_apiview,
193 
194  SMO_INVALID
195  };
196 
197  enum ShaderArgClass {
198  SAC_scalar,
199  SAC_vector,
200  SAC_matrix,
201  SAC_sampler,
202  SAC_array,
203  SAC_unknown,
204  };
205 
206  enum ShaderArgType {
207  SAT_scalar,
208  SAT_vec1,
209  SAT_vec2,
210  SAT_vec3,
211  SAT_vec4,
212  SAT_mat1x1,
213  SAT_mat1x2,
214  SAT_mat1x3,
215  SAT_mat1x4,
216  SAT_mat2x1,
217  SAT_mat2x2,
218  SAT_mat2x3,
219  SAT_mat2x4,
220  SAT_mat3x1,
221  SAT_mat3x2,
222  SAT_mat3x3,
223  SAT_mat3x4,
224  SAT_mat4x1,
225  SAT_mat4x2,
226  SAT_mat4x3,
227  SAT_mat4x4,
228  SAT_sampler1d,
229  SAT_sampler2d,
230  SAT_sampler3d,
231  SAT_sampler2dArray,
232  SAT_samplercube,
233  SAT_unknown
234 };
235 
236  enum ShaderArgDir {
237  SAD_in,
238  SAD_out,
239  SAD_inout,
240  SAD_unknown,
241  };
242 
243  enum ShaderMatPiece {
244  SMP_whole,
245  SMP_transpose,
246  SMP_row0,
247  SMP_row1,
248  SMP_row2,
249  SMP_row3,
250  SMP_col0,
251  SMP_col1,
252  SMP_col2,
253  SMP_col3,
254  SMP_row3x1,
255  SMP_row3x2,
256  SMP_row3x3,
257  SMP_upper3x3,
258  SMP_transpose3x3,
259  SMP_cell15,
260  };
261 
262  enum ShaderStateDep {
263  SSD_NONE = 0x000,
264  SSD_general = 0x001,
265  SSD_transform = 0x002,
266  SSD_color = 0x004,
267  SSD_colorscale = 0x008,
268  SSD_material = 0x010,
269  SSD_shaderinputs = 0x020,
270  SSD_fog = 0x040,
271  SSD_light = 0x080,
272  SSD_clip_planes = 0x100,
273  };
274 
275  enum ShaderBug {
276  SBUG_ati_draw_buffers,
277  };
278 
279  enum ShaderMatFunc {
280  SMF_compose,
281  SMF_transform_dlight,
282  SMF_transform_plight,
283  SMF_transform_slight,
284  SMF_first,
285  };
286 
287  struct ShaderArgId {
288  string _name;
289  ShaderType _type;
290  int _seqno;
291  };
292 
293  struct ShaderArgInfo {
294  ShaderArgId _id;
295  ShaderArgClass _class;
296  ShaderArgClass _subclass;
297  ShaderArgType _type;
298  ShaderArgDir _direction;
299  bool _varying;
300  NotifyCategory *_cat;
301  };
302 
303  enum ShaderPtrType {
304  SPT_float,
305  SPT_double,
306  SPT_int,
307  SPT_unknown
308  };
309 
310  // Container structure for data of parameters ShaderPtrSpec.
311  struct ShaderPtrData {
312  private:
313  PT(ReferenceCount) _pta;
314 
315  public:
316  void *_ptr;
317  ShaderPtrType _type;
318  bool _updated;
319  size_t _size; //number of elements vec3[4]=12
320 
321  public:
322  INLINE ShaderPtrData();
323  INLINE ShaderPtrData(const PTA_float &ptr);
324  INLINE ShaderPtrData(const PTA_LVecBase4f &ptr);
325  INLINE ShaderPtrData(const PTA_LVecBase3f &ptr);
326  INLINE ShaderPtrData(const PTA_LVecBase2f &ptr);
327  INLINE ShaderPtrData(const PTA_LMatrix4f &mat);
328  INLINE ShaderPtrData(const PTA_LMatrix3f &mat);
329  INLINE ShaderPtrData(const LVecBase4f &vec);
330  INLINE ShaderPtrData(const LVecBase3f &vec);
331  INLINE ShaderPtrData(const LVecBase2f &vec);
332  INLINE ShaderPtrData(const LMatrix4f &mat);
333  INLINE ShaderPtrData(const LMatrix3f &mat);
334 
335  INLINE ShaderPtrData(const PTA_double &ptr);
336  INLINE ShaderPtrData(const PTA_LVecBase4d &ptr);
337  INLINE ShaderPtrData(const PTA_LVecBase3d &ptr);
338  INLINE ShaderPtrData(const PTA_LVecBase2d &ptr);
339  INLINE ShaderPtrData(const PTA_LMatrix4d &mat);
340  INLINE ShaderPtrData(const PTA_LMatrix3d &mat);
341  INLINE ShaderPtrData(const LVecBase4d &vec);
342  INLINE ShaderPtrData(const LVecBase3d &vec);
343  INLINE ShaderPtrData(const LVecBase2d &vec);
344  INLINE ShaderPtrData(const LMatrix4d &mat);
345  INLINE ShaderPtrData(const LMatrix3d &mat);
346 
347  INLINE ShaderPtrData(const PTA_int &ptr);
348  INLINE ShaderPtrData(const PTA_LVecBase4i &ptr);
349  INLINE ShaderPtrData(const PTA_LVecBase3i &ptr);
350  INLINE ShaderPtrData(const PTA_LVecBase2i &ptr);
351  INLINE ShaderPtrData(const LVecBase4i &vec);
352  INLINE ShaderPtrData(const LVecBase3i &vec);
353  INLINE ShaderPtrData(const LVecBase2i &vec);
354 
355  INLINE void write_datagram(Datagram &dg) const;
356  INLINE void read_datagram(DatagramIterator &source);
357  };
358 
359  struct ShaderMatSpec {
360  LMatrix4 _cache[2];
361  LMatrix4 _value;
362  ShaderArgId _id;
363  ShaderMatFunc _func;
364  ShaderMatInput _part[2];
365  PT(InternalName) _arg[2];
366  int _dep[2];
367  int _index;
368  ShaderMatPiece _piece;
369  };
370 
371  struct ShaderTexSpec {
372  ShaderArgId _id;
373  PT(InternalName) _name;
374  int _stage;
375  int _desired_type;
376  PT(InternalName) _suffix;
377  };
378 
379  struct ShaderVarSpec {
380  ShaderArgId _id;
381  PT(InternalName) _name;
382  int _append_uv;
383  int _elements;
384  bool _integer;
385  };
386 
387  struct ShaderPtrSpec {
388  ShaderArgId _id;
389  int _dim[3]; //n_elements,rows,cols
390  int _dep[2];
391  PT(InternalName) _arg;
392  ShaderArgInfo _info;
393  ShaderPtrType _type;
394  };
395 
396  class ShaderCaps {
397  public:
398  void clear();
399  INLINE bool operator == (const ShaderCaps &other) const;
400  INLINE ShaderCaps();
401 
402  public:
403  bool _supports_glsl;
404 
405 #ifdef HAVE_CG
406  int _active_vprofile;
407  int _active_fprofile;
408  int _active_gprofile;
409  int _active_tprofile;
410 
411  int _ultimate_vprofile;
412  int _ultimate_fprofile;
413  int _ultimate_gprofile;
414  int _ultimate_tprofile;
415 
416  pset <ShaderBug> _bug_list;
417 #endif
418  };
419 
420  class ShaderFile : public ReferenceCount {
421  public:
422  INLINE ShaderFile() {};
423  INLINE ShaderFile(const string &shared);
424  INLINE ShaderFile(const string &vertex,
425  const string &fragment,
426  const string &geometry,
427  const string &tess_control,
428  const string &tess_evaluation);
429 
430  INLINE void write_datagram(Datagram &dg) const;
431  INLINE void read_datagram(DatagramIterator &source);
432 
433  INLINE bool operator < (const ShaderFile &other) const;
434 
435  public:
436  bool _separate;
437  string _shared;
438  string _vertex;
439  string _fragment;
440  string _geometry;
441  string _tess_control;
442  string _tess_evaluation;
443  string _compute;
444  };
445 
446 public:
447  // These routines help split the shader into sections,
448  // for those shader implementations that need to do so.
449  // Don't use them when you use separate shader programs.
450  void parse_init();
451  void parse_line(string &result, bool rt, bool lt);
452  void parse_upto(string &result, string pattern, bool include);
453  void parse_rest(string &result);
454  bool parse_eof();
455 
456  void cp_report_error(ShaderArgInfo &arg, const string &msg);
457  bool cp_errchk_parameter_words(ShaderArgInfo &arg, int len);
458  bool cp_errchk_parameter_in(ShaderArgInfo &arg);
459  bool cp_errchk_parameter_ptr(ShaderArgInfo &p);
460  bool cp_errchk_parameter_varying(ShaderArgInfo &arg);
461  bool cp_errchk_parameter_uniform(ShaderArgInfo &arg);
462  bool cp_errchk_parameter_float(ShaderArgInfo &arg, int lo, int hi);
463  bool cp_errchk_parameter_sampler(ShaderArgInfo &arg);
464  bool cp_parse_eol(ShaderArgInfo &arg,
465  vector_string &pieces, int &next);
466  bool cp_parse_delimiter(ShaderArgInfo &arg,
467  vector_string &pieces, int &next);
468  string cp_parse_non_delimiter(vector_string &pieces, int &next);
469  bool cp_parse_coord_sys(ShaderArgInfo &arg,
470  vector_string &pieces, int &next,
471  ShaderMatSpec &spec, bool fromflag);
472  int cp_dependency(ShaderMatInput inp);
473  void cp_optimize_mat_spec(ShaderMatSpec &spec);
474 
475 #ifdef HAVE_CG
476  void cg_recurse_parameters(CGparameter parameter,
477  const ShaderType &type,
478  bool &success);
479 #endif
480 
481  bool compile_parameter(const ShaderArgId &arg_id,
482  const ShaderArgClass &arg_class,
483  const ShaderArgClass &arg_subclass,
484  const ShaderArgType &arg_type,
485  const ShaderArgDir &arg_direction,
486  bool arg_varying,
487  int *arg_dim,
488  NotifyCategory *arg_cat);
489 
490  void clear_parameters();
491 
492 private:
493 #ifdef HAVE_CG
494  ShaderArgClass cg_parameter_class(CGparameter p);
495  ShaderArgType cg_parameter_type(CGparameter p);
496  ShaderArgDir cg_parameter_dir(CGparameter p);
497 
498  CGprogram cg_compile_entry_point(const char *entry, const ShaderCaps &caps,
499  CGcontext context, ShaderType type);
500 
501  bool cg_analyze_entry_point(CGprogram prog, ShaderType type);
502 
503  bool cg_analyze_shader(const ShaderCaps &caps);
504  bool cg_compile_shader(const ShaderCaps &caps, CGcontext context);
505  void cg_release_resources();
506  void cg_report_errors();
507 
508  // Determines the appropriate cg profile settings and stores them in the active shader caps
509  // based on any profile settings stored in the shader's header
510  void cg_get_profile_from_header(ShaderCaps &caps);
511 
512  ShaderCaps _cg_last_caps;
513  static CGcontext _cg_context;
514  CGprogram _cg_vprogram;
515  CGprogram _cg_fprogram;
516  CGprogram _cg_gprogram;
517 
518  int _cg_vprofile;
519  int _cg_fprofile;
520  int _cg_gprofile;
521 
522  CGprogram cg_program_from_shadertype(ShaderType type);
523 
524 public:
525  bool cg_compile_for(const ShaderCaps &caps, CGcontext context,
526  CGprogram &combined_program, pvector<CGparameter> &map);
527 
528 #endif
529 
530 public:
531  pvector <ShaderPtrSpec> _ptr_spec;
532  epvector <ShaderMatSpec> _mat_spec;
533  pvector <ShaderTexSpec> _tex_spec;
534  pvector <ShaderVarSpec> _var_spec;
535 
536  bool _error_flag;
537  ShaderFile _text;
538 
539 protected:
540  ShaderFile _filename;
541  int _parse;
542  bool _loaded;
543  ShaderLanguage _language;
544  pvector<Filename> _included_files;
545 
546  // Stores full paths, and includes the fullpaths of the shaders
547  // themselves as well as the includes.
548  pvector<Filename> _source_files;
549  time_t _last_modified;
550 
551  static ShaderCaps _default_caps;
552  static ShaderUtilization _shader_utilization;
553  static int _shaders_generated;
554 
556 
557  static ShaderTable _load_table;
558  static ShaderTable _make_table;
559 
560  friend class ShaderContext;
561  friend class PreparedGraphicsObjects;
562 
564  Contexts _contexts;
565 
566 private:
567  void clear_prepared(PreparedGraphicsObjects *prepared_objects);
568 
569  Shader(ShaderLanguage lang);
570 
571  bool read(const ShaderFile &sfile);
572  bool do_read_source(string &into, const Filename &fn);
573  bool r_preprocess_source(ostream &out, const Filename &fn,
574  const Filename &source_dir,
575  set<Filename> &open_files, int depth = 0);
576 
577  bool check_modified() const;
578 
579 public:
580  ~Shader();
581 
582  INLINE Filename get_filename_from_index(int index, ShaderType type) const;
583 
584 public:
585  static void register_with_read_factory();
586  virtual void write_datagram(BamWriter *manager, Datagram &dg);
587 
588 protected:
589  static TypedWritable *make_from_bam(const FactoryParams &params);
590  void fillin(DatagramIterator &scan, BamReader *manager);
591 
592 public:
593  static TypeHandle get_class_type() {
594  return _type_handle;
595  }
596  static void init_type() {
597  TypedWritableReferenceCount::init_type();
598  register_type(_type_handle, "Shader",
599  TypedWritableReferenceCount::get_class_type());
600  }
601  virtual TypeHandle get_type() const {
602  return get_class_type();
603  }
604  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
605 
606 private:
607  static TypeHandle _type_handle;
608 };
609 
610 #include "shader.I"
611 
612 #endif
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
This is our own Panda specialization on the default STL map.
Definition: pmap.h:52
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:4716
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
This is the base class for all two-component vectors and points.
Definition: lvecBase2.h:1241
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
Definition: shader.h:50
This is the base class for all two-component vectors and points.
Definition: lvecBase2.h:2328
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:1661
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
A table of objects that are saved within the graphics context for reference by handle later...
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:3162
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class&#39;s make_from_bam() method to read in all...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
The ShaderContext is meant to contain the compiled version of a shader string.
Definition: shaderContext.h:35
A particular category of error messages.
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:39
This is a 3-by-3 transform matrix.
Definition: lmatrix.h:4375
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
This is the base class for all two-component vectors and points.
Definition: lvecBase2.h:105
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:1455
A base class for things which need to inherit from both TypedWritable and from ReferenceCount.
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:2756
A base class for all things that want to be reference-counted.
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
This is our own Panda specialization on the default STL set.
Definition: pset.h:52
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
This is a 3-by-3 transform matrix.
Definition: lmatrix.h:110
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43