Panda3D
|
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