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