00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pandabase.h"
00020 #include "shaderAttrib.h"
00021 #include "graphicsStateGuardianBase.h"
00022 #include "bamReader.h"
00023 #include "bamWriter.h"
00024 #include "datagram.h"
00025 #include "datagramIterator.h"
00026
00027 TypeHandle ShaderAttrib::_type_handle;
00028 int ShaderAttrib::_attrib_slot;
00029
00030
00031
00032
00033
00034
00035
00036
00037 CPT(RenderAttrib) ShaderAttrib::
00038 make_off() {
00039 static CPT(RenderAttrib) _off_attrib;
00040 if (_off_attrib == 0) {
00041 ShaderAttrib *attrib = new ShaderAttrib;
00042 attrib->_has_shader = true;
00043 _off_attrib = return_new(attrib);
00044 }
00045 return _off_attrib;
00046 }
00047
00048
00049
00050
00051
00052
00053
00054 CPT(RenderAttrib) ShaderAttrib::
00055 make() {
00056 static CPT(RenderAttrib) _null_attrib;
00057 if (_null_attrib == 0) {
00058 ShaderAttrib *attrib = new ShaderAttrib;
00059 _null_attrib = return_new(attrib);
00060 }
00061 return _null_attrib;
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071 CPT(RenderAttrib) ShaderAttrib::
00072 make_default() {
00073 return return_new(new ShaderAttrib);
00074 }
00075
00076
00077
00078
00079
00080
00081 CPT(RenderAttrib) ShaderAttrib::
00082 set_shader(const Shader *s, int priority) const {
00083 ShaderAttrib *result = new ShaderAttrib(*this);
00084 result->_shader = s;
00085 result->_shader_priority = priority;
00086 result->_auto_shader = false;
00087 result->_has_shader = true;
00088 return return_new(result);
00089 }
00090
00091
00092
00093
00094
00095
00096 CPT(RenderAttrib) ShaderAttrib::
00097 set_shader_off(int priority) const {
00098 ShaderAttrib *result = new ShaderAttrib(*this);
00099 result->_shader = NULL;
00100 result->_shader_priority = priority;
00101 result->_auto_shader = false;
00102 result->_auto_normal_on = false;
00103 result->_auto_glow_on = false;
00104 result->_auto_gloss_on = false;
00105 result->_auto_ramp_on = false;
00106 result->_auto_shadow_on = false;
00107
00108 result->_has_shader = true;
00109 return return_new(result);
00110 }
00111
00112
00113
00114
00115
00116
00117 CPT(RenderAttrib) ShaderAttrib::
00118 set_shader_auto(int priority) const {
00119 ShaderAttrib *result = new ShaderAttrib(*this);
00120 result->_shader = NULL;
00121 result->_shader_priority = priority;
00122 result->_auto_shader = true;
00123 result->_has_shader = true;
00124 result->_auto_normal_on = true;
00125 result->_auto_glow_on = true;
00126 result->_auto_gloss_on = true;
00127 result->_auto_ramp_on = true;
00128 result->_auto_shadow_on = true;
00129 return return_new(result);
00130 }
00131
00132
00133
00134
00135
00136
00137
00138 CPT(RenderAttrib) ShaderAttrib::
00139 set_shader_auto(BitMask32 shader_switch, int priority) const {
00140
00141 ShaderAttrib *result = new ShaderAttrib(*this);
00142 result->_shader = NULL;
00143 result->_shader_priority = priority;
00144 result->_auto_shader = true;
00145 result->_has_shader = true;
00146 result->_auto_normal_on = shader_switch.get_bit(Shader::bit_AutoShaderNormal);
00147 result->_auto_glow_on = shader_switch.get_bit(Shader::bit_AutoShaderGlow);
00148 result->_auto_gloss_on = shader_switch.get_bit(Shader::bit_AutoShaderGloss);
00149 result->_auto_ramp_on = shader_switch.get_bit(Shader::bit_AutoShaderRamp);
00150 result->_auto_shadow_on = shader_switch.get_bit(Shader::bit_AutoShaderShadow);
00151
00152 return return_new(result);
00153 }
00154
00155
00156
00157
00158
00159
00160 CPT(RenderAttrib) ShaderAttrib::
00161 clear_shader() const {
00162 ShaderAttrib *result = new ShaderAttrib(*this);
00163 result->_shader = NULL;
00164 result->_shader_priority = 0;
00165 result->_auto_shader = false;
00166 result->_has_shader = false;
00167 result->_auto_normal_on = false;
00168 result->_auto_glow_on = false;
00169 result->_auto_gloss_on = false;
00170 result->_auto_ramp_on = false;
00171 result->_auto_shadow_on = false;
00172 return return_new(result);
00173 }
00174
00175
00176
00177
00178
00179
00180 CPT(RenderAttrib) ShaderAttrib::
00181 set_flag(int flag, bool value) const {
00182 ShaderAttrib *result = new ShaderAttrib(*this);
00183 int bit = 1<<flag;
00184 if (value) {
00185 result->_flags |= bit;
00186 } else {
00187 result->_flags &= ~bit;
00188 }
00189 result->_has_flags |= bit;
00190 return return_new(result);
00191 }
00192
00193
00194
00195
00196
00197
00198 CPT(RenderAttrib) ShaderAttrib::
00199 clear_flag(int flag) const {
00200 ShaderAttrib *result = new ShaderAttrib(*this);
00201 int bit = 1<<flag;
00202 result->_flags &= ~bit;
00203 result->_has_flags &= ~bit;
00204 return return_new(result);
00205 }
00206
00207
00208
00209
00210
00211
00212 CPT(RenderAttrib) ShaderAttrib::
00213 set_shader_input(const ShaderInput *input) const {
00214 ShaderAttrib *result = new ShaderAttrib(*this);
00215 Inputs::iterator i = result->_inputs.find(input->get_name());
00216 if (i == result->_inputs.end()) {
00217 result->_inputs.insert(Inputs::value_type(input->get_name(),input));
00218 } else {
00219 i->second = input;
00220 }
00221 return return_new(result);
00222 }
00223
00224
00225
00226
00227
00228
00229 CPT(RenderAttrib) ShaderAttrib::
00230 set_shader_input(const InternalName *id, const PTA_float &v, int priority) const {
00231 return set_shader_input(new ShaderInput(id,v,priority));
00232 }
00233
00234
00235
00236
00237
00238
00239 CPT(RenderAttrib) ShaderAttrib::
00240 set_shader_input(const InternalName *id, const PTA_double &v, int priority) const {
00241 return set_shader_input(new ShaderInput(id,v,priority));
00242 }
00243
00244
00245
00246
00247
00248
00249 CPT(RenderAttrib) ShaderAttrib::
00250 set_shader_input(const InternalName *id, const PTA_LVecBase4 &v, int priority) const {
00251 return set_shader_input(new ShaderInput(id,v,priority));
00252 }
00253
00254
00255
00256
00257
00258
00259 CPT(RenderAttrib) ShaderAttrib::
00260 set_shader_input(const InternalName *id, const PTA_LVecBase3 &v, int priority) const {
00261 return set_shader_input(new ShaderInput(id,v,priority));
00262 }
00263
00264
00265
00266
00267
00268
00269
00270 CPT(RenderAttrib) ShaderAttrib::
00271 set_shader_input(const InternalName *id, const PTA_LVecBase2 &v, int priority) const {
00272 return set_shader_input(new ShaderInput(id,v,priority));
00273 }
00274
00275
00276
00277
00278
00279
00280 CPT(RenderAttrib) ShaderAttrib::
00281 set_shader_input(const InternalName *id, const LVecBase4 &v, int priority) const {
00282 return set_shader_input(new ShaderInput(id,v,priority));
00283 }
00284
00285
00286
00287
00288
00289
00290 CPT(RenderAttrib) ShaderAttrib::
00291 set_shader_input(const InternalName *id, const LVecBase3 &v, int priority) const {
00292 return set_shader_input(new ShaderInput(id,v,priority));
00293 }
00294
00295
00296
00297
00298
00299
00300 CPT(RenderAttrib) ShaderAttrib::
00301 set_shader_input(const InternalName *id, const LVecBase2 &v, int priority) const {
00302 return set_shader_input(new ShaderInput(id,v,priority));
00303 }
00304
00305
00306
00307
00308
00309
00310 CPT(RenderAttrib) ShaderAttrib::
00311 set_shader_input(const InternalName *id, const PTA_LMatrix4 &v, int priority) const {
00312 return set_shader_input(new ShaderInput(id,v,priority));
00313 }
00314
00315
00316
00317
00318
00319
00320 CPT(RenderAttrib) ShaderAttrib::
00321 set_shader_input(const InternalName *id, const PTA_LMatrix3 &v, int priority) const {
00322 return set_shader_input(new ShaderInput(id,v,priority));
00323 }
00324
00325
00326
00327
00328
00329
00330 CPT(RenderAttrib) ShaderAttrib::
00331 set_shader_input(const InternalName *id, const LMatrix4 &v, int priority) const {
00332 return set_shader_input(new ShaderInput(id,v,priority));
00333 }
00334
00335
00336
00337
00338
00339
00340 CPT(RenderAttrib) ShaderAttrib::
00341 set_shader_input(const InternalName *id, const LMatrix3 &v, int priority) const {
00342 return set_shader_input(new ShaderInput(id,v,priority));
00343 }
00344
00345
00346
00347
00348
00349
00350 CPT(RenderAttrib) ShaderAttrib::
00351 set_shader_input(const InternalName *id, Texture *tex, int priority) const {
00352 return set_shader_input(new ShaderInput(id,tex,priority));
00353 }
00354
00355
00356
00357
00358
00359
00360 CPT(RenderAttrib) ShaderAttrib::
00361 set_shader_input(const InternalName *id, const NodePath &np, int priority) const {
00362 return set_shader_input(new ShaderInput(id,np,priority));
00363 }
00364
00365
00366
00367
00368
00369
00370 CPT(RenderAttrib) ShaderAttrib::
00371 set_shader_input(const InternalName *id, double n1, double n2, double n3, double n4, int priority) const {
00372 return set_shader_input(new ShaderInput(id, LVecBase4(n1,n2,n3,n4), priority));
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 CPT(RenderAttrib) ShaderAttrib::
00384 set_instance_count(int instance_count) const {
00385 ShaderAttrib *result = new ShaderAttrib(*this);
00386 result->_instance_count = instance_count;
00387 return return_new(result);
00388 }
00389
00390
00391
00392
00393
00394
00395 CPT(RenderAttrib) ShaderAttrib::
00396 clear_shader_input(const InternalName *id) const {
00397 ShaderAttrib *result = new ShaderAttrib(*this);
00398 result->_inputs.erase(id);
00399 return return_new(result);
00400 }
00401
00402
00403
00404
00405
00406
00407 CPT(RenderAttrib) ShaderAttrib::
00408 clear_shader_input(const string &id) const {
00409 return clear_shader_input(InternalName::make(id));
00410 }
00411
00412
00413
00414
00415
00416
00417 CPT(RenderAttrib) ShaderAttrib::
00418 clear_all_shader_inputs() const {
00419 ShaderAttrib *result = new ShaderAttrib(*this);
00420 result->_inputs.clear();
00421 return return_new(result);
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431 const ShaderInput *ShaderAttrib::
00432 get_shader_input(const InternalName *id) const {
00433 Inputs::const_iterator i = _inputs.find(id);
00434 if (i == _inputs.end()) {
00435 return ShaderInput::get_blank();
00436 } else {
00437 return (*i).second;
00438 }
00439 }
00440
00441
00442
00443
00444
00445
00446
00447
00448 const ShaderInput *ShaderAttrib::
00449 get_shader_input(const string &id) const {
00450 return get_shader_input(InternalName::make(id));
00451 }
00452
00453
00454
00455
00456
00457
00458
00459 const NodePath &ShaderAttrib::
00460 get_shader_input_nodepath(const InternalName *id) const {
00461 static NodePath resfail;
00462 Inputs::const_iterator i = _inputs.find(id);
00463 if (i == _inputs.end()) {
00464 ostringstream strm;
00465 strm << "Shader input " << id->get_name() << " is not present.\n";
00466 nassert_raise(strm.str());
00467 return resfail;
00468 } else {
00469 const ShaderInput *p = (*i).second;
00470 if (p->get_value_type() != ShaderInput::M_nodepath) {
00471 ostringstream strm;
00472 strm << "Shader input " << id->get_name() << " is not a nodepath.\n";
00473 nassert_raise(strm.str());
00474 return resfail;
00475 }
00476 return p->get_nodepath();
00477 }
00478
00479
00480 return resfail;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489 const LVecBase4 &ShaderAttrib::
00490 get_shader_input_vector(InternalName *id) const {
00491 static LVecBase4 resfail(0,0,0,0);
00492 Inputs::const_iterator i = _inputs.find(id);
00493 if (i == _inputs.end()) {
00494 ostringstream strm;
00495 strm << "Shader input " << id->get_name() << " is not present.\n";
00496 nassert_raise(strm.str());
00497 return resfail;
00498 } else {
00499 const ShaderInput *p = (*i).second;
00500 if (p->get_value_type() != ShaderInput::M_numeric) {
00501 ostringstream strm;
00502 strm << "Shader input " << id->get_name() << " is not a vector.\n";
00503 nassert_raise(strm.str());
00504 return resfail;
00505 }
00506 return p->get_vector();
00507 }
00508 }
00509
00510
00511
00512
00513
00514
00515
00516
00517 const Shader::ShaderPtrData *ShaderAttrib::
00518 get_shader_input_ptr(const InternalName *id) const {
00519 Inputs::const_iterator i = _inputs.find(id);
00520 if (i == _inputs.end()) {
00521 ostringstream strm;
00522 strm << "Shader input " << id->get_name() << " is not present.\n";
00523 nassert_raise(strm.str());
00524 return NULL;
00525 } else {
00526 const ShaderInput *p = (*i).second;
00527 if (p->get_value_type() != ShaderInput::M_numeric) {
00528 ostringstream strm;
00529 strm << "Shader input " << id->get_name() << " is not a PTA(float/double) type.\n";
00530 nassert_raise(strm.str());
00531 return NULL;
00532 }
00533 return &(p->get_ptr());
00534 }
00535 }
00536
00537
00538
00539
00540
00541
00542
00543 Texture *ShaderAttrib::
00544 get_shader_input_texture(const InternalName *id) const {
00545 Inputs::const_iterator i = _inputs.find(id);
00546 if (i == _inputs.end()) {
00547 ostringstream strm;
00548 strm << "Shader input " << id->get_name() << " is not present.\n";
00549 nassert_raise(strm.str());
00550 return NULL;
00551 } else {
00552 const ShaderInput *p = (*i).second;
00553 if (p->get_value_type() != ShaderInput::M_texture) {
00554 ostringstream strm;
00555 strm << "Shader input " << id->get_name() << " is not a texture.\n";
00556 nassert_raise(strm.str());
00557 return NULL;
00558 }
00559 return p->get_texture();
00560 }
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 const Shader *ShaderAttrib::
00572 get_shader() const {
00573 return _shader;
00574 }
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 int ShaderAttrib::
00592 compare_to_impl(const RenderAttrib *other) const {
00593 const ShaderAttrib *that;
00594 DCAST_INTO_R(that, other, 0);
00595
00596 if (this->_shader != that->_shader) {
00597 return (this->_shader < that->_shader) ? -1 : 1;
00598 }
00599 if (this->_shader_priority != that->_shader_priority) {
00600 return (this->_shader_priority < that->_shader_priority) ? -1 : 1;
00601 }
00602 if (this->_auto_shader != that->_auto_shader) {
00603 return (this->_auto_shader < that->_auto_shader) ? -1 : 1;
00604 }
00605 if (this->_has_shader != that->_has_shader) {
00606 return (this->_has_shader < that->_has_shader) ? -1 : 1;
00607 }
00608 if (this->_flags != that->_flags) {
00609 return (this->_flags < that->_flags) ? -1 : 1;
00610 }
00611 if (this->_has_flags != that->_has_flags) {
00612 return (this->_has_flags < that->_has_flags) ? -1 : 1;
00613 }
00614 if (this->_instance_count != that->_instance_count) {
00615 return (this->_instance_count < that->_instance_count) ? -1 : 1;
00616 }
00617 if (this->_auto_normal_on != that->_auto_normal_on) {
00618 return (this->_auto_normal_on < that->_auto_normal_on) ? -1 : 1;
00619 }
00620 if (this->_auto_glow_on != that->_auto_glow_on) {
00621 return (this->_auto_glow_on < that->_auto_glow_on) ? -1 : 1;
00622 }
00623 if (this->_auto_gloss_on != that->_auto_gloss_on) {
00624 return (this->_auto_gloss_on < that->_auto_gloss_on) ? -1 : 1;
00625 }
00626 if (this->_auto_ramp_on != that->_auto_ramp_on) {
00627 return (this->_auto_ramp_on < that->_auto_ramp_on) ? -1 : 1;
00628 }
00629 if (this->_auto_shadow_on != that->_auto_shadow_on) {
00630 return (this->_auto_shadow_on < that->_auto_shadow_on) ? -1 : 1;
00631 }
00632
00633 Inputs::const_iterator i1 = this->_inputs.begin();
00634 Inputs::const_iterator i2 = that->_inputs.begin();
00635 while ((i1 != this->_inputs.end()) && (i2 != that->_inputs.end())) {
00636 if (i1->second != i2->second) {
00637 return (i1->second < i2->second) ? -1 : 1;
00638 }
00639 ++i1;
00640 ++i2;
00641 }
00642 if (i1 != this->_inputs.end()) {
00643 return 1;
00644 }
00645 if (i2 != that->_inputs.end()) {
00646 return -1;
00647 }
00648
00649 return 0;
00650 }
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662 size_t ShaderAttrib::
00663 get_hash_impl() const {
00664 size_t hash = 0;
00665 hash = pointer_hash::add_hash(hash, _shader);
00666 hash = int_hash::add_hash(hash, _shader_priority);
00667 hash = int_hash::add_hash(hash, (int)_auto_shader);
00668 hash = int_hash::add_hash(hash, (int)_has_shader);
00669 hash = int_hash::add_hash(hash, _flags);
00670 hash = int_hash::add_hash(hash, _has_flags);
00671 hash = int_hash::add_hash(hash, _instance_count);
00672 hash = int_hash::add_hash(hash, (int)_auto_normal_on);
00673 hash = int_hash::add_hash(hash, (int)_auto_glow_on);
00674 hash = int_hash::add_hash(hash, (int)_auto_gloss_on);
00675 hash = int_hash::add_hash(hash, (int)_auto_shadow_on);
00676
00677 Inputs::const_iterator ii;
00678 for (ii = _inputs.begin(); ii != _inputs.end(); ++ii) {
00679 hash = pointer_hash::add_hash(hash, (*ii).first);
00680 hash = pointer_hash::add_hash(hash, (*ii).second);
00681 }
00682
00683 return hash;
00684 }
00685
00686
00687
00688
00689
00690
00691 CPT(RenderAttrib) ShaderAttrib::
00692 compose_impl(const RenderAttrib *other) const {
00693 ShaderAttrib *attr = new ShaderAttrib(*this);
00694 const ShaderAttrib *over;
00695 DCAST_INTO_R(over, other, 0);
00696
00697 if (over->_has_shader) {
00698 if ((attr->_has_shader == false) ||
00699 (over->_shader_priority >= attr->_shader_priority)) {
00700 attr->_shader = over->_shader;
00701 attr->_shader_priority = over->_shader_priority;
00702 attr->_auto_shader = over->_auto_shader;
00703 attr->_has_shader = over->_has_shader;
00704 attr->_auto_normal_on = over->_auto_normal_on;
00705 attr->_auto_glow_on = over->_auto_glow_on;
00706 attr->_auto_gloss_on = over->_auto_gloss_on;
00707 attr->_auto_ramp_on = over->_auto_ramp_on;
00708 attr->_auto_shadow_on = over->_auto_shadow_on;
00709 }
00710 }
00711
00712 Inputs::const_iterator iover;
00713 for (iover=over->_inputs.begin(); iover!=over->_inputs.end(); ++iover) {
00714 const InternalName *id = (*iover).first;
00715 const ShaderInput *dover = (*iover).second;
00716 Inputs::iterator iattr = attr->_inputs.find(id);
00717 if (iattr == attr->_inputs.end()) {
00718 attr->_inputs.insert(Inputs::value_type(id,dover));
00719 } else {
00720 const ShaderInput *dattr = (*iattr).second;
00721 if (dattr->get_priority() <= dover->get_priority()) {
00722 iattr->second = iover->second;
00723 }
00724 }
00725 }
00726
00727 attr->_instance_count = over->_instance_count;
00728
00729 attr->_flags &= ~(over->_has_flags);
00730 attr->_flags |= over->_flags;
00731 attr->_has_flags |= (over->_has_flags);
00732 return return_new(attr);
00733 }
00734
00735
00736
00737
00738
00739
00740 CPT(RenderAttrib) ShaderAttrib::
00741 get_auto_shader_attrib_impl(const RenderState *state) const {
00742
00743
00744
00745 ShaderAttrib *attrib = new ShaderAttrib;
00746 attrib->_auto_shader = _auto_shader;
00747 attrib->_has_shader = _has_shader;
00748 attrib->_auto_normal_on = _auto_normal_on;
00749 attrib->_auto_glow_on = _auto_glow_on;
00750 attrib->_auto_gloss_on = _auto_gloss_on;
00751 attrib->_auto_ramp_on = _auto_ramp_on;
00752 attrib->_auto_shadow_on = _auto_shadow_on;
00753 return return_new(attrib);
00754 }
00755
00756
00757
00758
00759
00760
00761 void ShaderAttrib::
00762 register_with_read_factory() {
00763
00764 }
00765