00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00034
00035 typedef struct _CGcontext *CGcontext;
00036 typedef struct _CGprogram *CGprogram;
00037 typedef struct _CGparameter *CGparameter;
00038 #endif
00039
00040
00041
00042
00043
00044
00045
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,
00074 bit_AutoShaderGlow = 1,
00075 bit_AutoShaderGloss = 2,
00076 bit_AutoShaderRamp = 3,
00077 bit_AutoShaderShadow = 4,
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
00269 struct ShaderPtrData {
00270 private:
00271 PT(ReferenceCount) _pta;
00272
00273 public:
00274 void *_ptr;
00275 ShaderPtrType _type;
00276 bool _updated;
00277 int _size;
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];
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
00373
00374
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
00436
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