diff options
26 files changed, 960 insertions, 439 deletions
diff --git a/linden/indra/llinventory/llinventory.cpp b/linden/indra/llinventory/llinventory.cpp index 755a57c..1508b46 100644 --- a/linden/indra/llinventory/llinventory.cpp +++ b/linden/indra/llinventory/llinventory.cpp | |||
@@ -128,6 +128,8 @@ LLInventoryType::NType calc_ntype( | |||
128 | case WT_UNDERSHIRT: return LLInventoryType::NIT_UNDERSHIRT; | 128 | case WT_UNDERSHIRT: return LLInventoryType::NIT_UNDERSHIRT; |
129 | case WT_UNDERPANTS: return LLInventoryType::NIT_UNDERPANTS; | 129 | case WT_UNDERPANTS: return LLInventoryType::NIT_UNDERPANTS; |
130 | case WT_SKIRT: return LLInventoryType::NIT_SKIRT; | 130 | case WT_SKIRT: return LLInventoryType::NIT_SKIRT; |
131 | case WT_ALPHA: return LLInventoryType::NIT_ALPHA; | ||
132 | case WT_TATTOO: return LLInventoryType::NIT_TATTOO; | ||
131 | default: return LLInventoryType::NIT_CLOTHING; | 133 | default: return LLInventoryType::NIT_CLOTHING; |
132 | } | 134 | } |
133 | } | 135 | } |
diff --git a/linden/indra/llinventory/llinventorytype.h b/linden/indra/llinventory/llinventorytype.h index 961fa79..ee429c2 100644 --- a/linden/indra/llinventory/llinventorytype.h +++ b/linden/indra/llinventory/llinventorytype.h | |||
@@ -115,49 +115,51 @@ public: | |||
115 | NIT_UNDERSHIRT = 1 << 10, | 115 | NIT_UNDERSHIRT = 1 << 10, |
116 | NIT_UNDERPANTS = 1 << 11, | 116 | NIT_UNDERPANTS = 1 << 11, |
117 | NIT_SKIRT = 1 << 12, | 117 | NIT_SKIRT = 1 << 12, |
118 | NIT_CLOTHING = 0x0001ff0, | 118 | NIT_ALPHA = 1 << 13, |
119 | NIT_TATTOO = 1 << 14, | ||
120 | NIT_CLOTHING = 0x0007ff0, | ||
119 | 121 | ||
120 | /* Body Parts | Clothing */ | 122 | /* Body Parts | Clothing */ |
121 | NIT_WEARABLE = 0x0001fff, | 123 | NIT_WEARABLE = 0x0007fff, |
122 | 124 | ||
123 | /* Images */ | 125 | /* Images */ |
124 | NIT_TEXTURE = 1 << 13, | 126 | NIT_TEXTURE = 1 << 15, |
125 | NIT_SNAPSHOT = 1 << 14, | 127 | NIT_SNAPSHOT = 1 << 16, |
126 | NIT_IMAGE = 0x0006000, | 128 | NIT_IMAGE = 0x0018000, |
127 | 129 | ||
128 | /* Calling Cards */ | 130 | /* Calling Cards */ |
129 | NIT_CALLCARD_OFF = 1 << 15, | 131 | NIT_CALLCARD_OFF = 1 << 17, |
130 | NIT_CALLCARD_ON = 1 << 16, | 132 | NIT_CALLCARD_ON = 1 << 18, |
131 | NIT_CALLCARD = 0x0018000, | 133 | NIT_CALLCARD = 0x0060000, |
132 | 134 | ||
133 | /* Landmarks */ | 135 | /* Landmarks */ |
134 | NIT_LANDMARK_UNUSED = 1 << 17, | 136 | NIT_LANDMARK_UNUSED = 1 << 19, |
135 | NIT_LANDMARK_USED = 1 << 18, | 137 | NIT_LANDMARK_USED = 1 << 20, |
136 | NIT_LANDMARK = 0x0060000, | 138 | NIT_LANDMARK = 0x0180000, |
137 | 139 | ||
138 | /* Sounds */ | 140 | /* Sounds */ |
139 | NIT_SOUND = 1 << 19, | 141 | NIT_SOUND = 1 << 21, |
140 | 142 | ||
141 | /* Animations */ | 143 | /* Animations */ |
142 | NIT_ANIMATION = 1 << 20, | 144 | NIT_ANIMATION = 1 << 22, |
143 | 145 | ||
144 | /* Gestures */ | 146 | /* Gestures */ |
145 | NIT_GESTURE = 1 << 21, | 147 | NIT_GESTURE = 1 << 23, |
146 | 148 | ||
147 | /* Notecards */ | 149 | /* Notecards */ |
148 | NIT_NOTECARD = 1 << 22, | 150 | NIT_NOTECARD = 1 << 24, |
149 | 151 | ||
150 | /* Scripts */ | 152 | /* Scripts */ |
151 | NIT_SCRIPT_LSL2 = 1 << 23, | 153 | NIT_SCRIPT_LSL2 = 1 << 25, |
152 | 154 | ||
153 | /* Objects */ | 155 | /* Objects */ |
154 | NIT_OBJECT = 1 << 24, | 156 | NIT_OBJECT = 1 << 26, |
155 | 157 | ||
156 | /* Folders ("Categories" in the old type system) */ | 158 | /* Folders ("Categories" in the old type system) */ |
157 | NIT_FOLDER = 1 << 25, | 159 | NIT_FOLDER = 1 << 27, |
158 | 160 | ||
159 | /* Bitwise OR-ing of all the above */ | 161 | /* Bitwise OR-ing of all the above */ |
160 | NIT_ALL = 0x3ffffff, | 162 | NIT_ALL = 0xfffffff, |
161 | }; | 163 | }; |
162 | 164 | ||
163 | 165 | ||
diff --git a/linden/indra/llinventory/llwearabletype.h b/linden/indra/llinventory/llwearabletype.h index b0a40b2..7a5ecef 100644 --- a/linden/indra/llinventory/llwearabletype.h +++ b/linden/indra/llinventory/llwearabletype.h | |||
@@ -47,7 +47,9 @@ enum EWearableType // If you change this, update LLWearable::getTypeName(), get | |||
47 | WT_UNDERSHIRT = 10, | 47 | WT_UNDERSHIRT = 10, |
48 | WT_UNDERPANTS = 11, | 48 | WT_UNDERPANTS = 11, |
49 | WT_SKIRT = 12, | 49 | WT_SKIRT = 12, |
50 | WT_COUNT = 13, | 50 | WT_ALPHA = 13, |
51 | WT_TATTOO = 14, | ||
52 | WT_COUNT = 15, | ||
51 | WT_INVALID = 255 | 53 | WT_INVALID = 255 |
52 | }; | 54 | }; |
53 | 55 | ||
diff --git a/linden/indra/llrender/llrender.cpp b/linden/indra/llrender/llrender.cpp index 93ff822..b1fe153 100644 --- a/linden/indra/llrender/llrender.cpp +++ b/linden/indra/llrender/llrender.cpp | |||
@@ -799,6 +799,9 @@ void LLRender::setSceneBlendType(eBlendType type) | |||
799 | case BT_MULT: | 799 | case BT_MULT: |
800 | glBlendFunc(GL_DST_COLOR, GL_ZERO); | 800 | glBlendFunc(GL_DST_COLOR, GL_ZERO); |
801 | break; | 801 | break; |
802 | case BT_MULT_ALPHA: | ||
803 | glBlendFunc(GL_DST_ALPHA, GL_ZERO); | ||
804 | break; | ||
802 | case BT_MULT_X2: | 805 | case BT_MULT_X2: |
803 | glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); | 806 | glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); |
804 | break; | 807 | break; |
diff --git a/linden/indra/llrender/llrender.h b/linden/indra/llrender/llrender.h index ce84e74..da69de8 100644 --- a/linden/indra/llrender/llrender.h +++ b/linden/indra/llrender/llrender.h | |||
@@ -252,6 +252,7 @@ public: | |||
252 | BT_ADD, | 252 | BT_ADD, |
253 | BT_ADD_WITH_ALPHA, // Additive blend modulated by the fragment's alpha. | 253 | BT_ADD_WITH_ALPHA, // Additive blend modulated by the fragment's alpha. |
254 | BT_MULT, | 254 | BT_MULT, |
255 | BT_MULT_ALPHA, | ||
255 | BT_MULT_X2, | 256 | BT_MULT_X2, |
256 | BT_REPLACE | 257 | BT_REPLACE |
257 | } eBlendType; | 258 | } eBlendType; |
diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 5043264..670de2b 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml | |||
@@ -11336,6 +11336,17 @@ | |||
11336 | <key>Value</key> | 11336 | <key>Value</key> |
11337 | <string>5748decc-f629-461c-9a36-a35a221fe21f</string> | 11337 | <string>5748decc-f629-461c-9a36-a35a221fe21f</string> |
11338 | </map> | 11338 | </map> |
11339 | <key>UIImgDefaultAlphaUUID</key> | ||
11340 | <map> | ||
11341 | <key>Comment</key> | ||
11342 | <string /> | ||
11343 | <key>Persist</key> | ||
11344 | <integer>0</integer> | ||
11345 | <key>Type</key> | ||
11346 | <string>String</string> | ||
11347 | <key>Value</key> | ||
11348 | <string>5748decc-f629-461c-9a36-a35a221fe21f</string> | ||
11349 | </map> | ||
11339 | <key>UIImgDefaultUnderwearUUID</key> | 11350 | <key>UIImgDefaultUnderwearUUID</key> |
11340 | <map> | 11351 | <map> |
11341 | <key>Comment</key> | 11352 | <key>Comment</key> |
diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index 859f7f6..4753bc8 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp | |||
@@ -7091,7 +7091,9 @@ void LLAgent::createStandardWearables(BOOL female) | |||
7091 | FALSE, //WT_GLOVES | 7091 | FALSE, //WT_GLOVES |
7092 | TRUE, //WT_UNDERSHIRT | 7092 | TRUE, //WT_UNDERSHIRT |
7093 | TRUE, //WT_UNDERPANTS | 7093 | TRUE, //WT_UNDERPANTS |
7094 | FALSE //WT_SKIRT | 7094 | FALSE, //WT_SKIRT |
7095 | FALSE, //WT_ALPHA | ||
7096 | FALSE //WT_TATTOO | ||
7095 | }; | 7097 | }; |
7096 | 7098 | ||
7097 | for( S32 i=0; i < WT_COUNT; i++ ) | 7099 | for( S32 i=0; i < WT_COUNT; i++ ) |
@@ -7602,6 +7604,8 @@ void LLAgent::setWearableOutfit( | |||
7602 | wearables_to_remove[WT_UNDERPANTS] = (!gAgent.isTeen()) && remove && gRlvHandler.isRemovable(WT_UNDERPANTS); | 7604 | wearables_to_remove[WT_UNDERPANTS] = (!gAgent.isTeen()) && remove && gRlvHandler.isRemovable(WT_UNDERPANTS); |
7603 | wearables_to_remove[WT_SKIRT] = remove && gRlvHandler.isRemovable(WT_SKIRT); | 7605 | wearables_to_remove[WT_SKIRT] = remove && gRlvHandler.isRemovable(WT_SKIRT); |
7604 | // [/RLVa:KB] | 7606 | // [/RLVa:KB] |
7607 | wearables_to_remove[WT_ALPHA] = remove; | ||
7608 | wearables_to_remove[WT_TATTOO] = remove; | ||
7605 | 7609 | ||
7606 | S32 count = wearables.count(); | 7610 | S32 count = wearables.count(); |
7607 | llassert( items.count() == count ); | 7611 | llassert( items.count() == count ); |
@@ -7900,6 +7904,8 @@ void LLAgent::userRemoveAllClothesStep2( BOOL proceed, void* userdata ) | |||
7900 | gAgent.removeWearable( WT_UNDERSHIRT ); | 7904 | gAgent.removeWearable( WT_UNDERSHIRT ); |
7901 | gAgent.removeWearable( WT_UNDERPANTS ); | 7905 | gAgent.removeWearable( WT_UNDERPANTS ); |
7902 | gAgent.removeWearable( WT_SKIRT ); | 7906 | gAgent.removeWearable( WT_SKIRT ); |
7907 | gAgent.removeWearable( WT_ALPHA ); | ||
7908 | gAgent.removeWearable( WT_TATTOO ); | ||
7903 | } | 7909 | } |
7904 | } | 7910 | } |
7905 | 7911 | ||
diff --git a/linden/indra/newview/llfloatercustomize.cpp b/linden/indra/newview/llfloatercustomize.cpp index 4761491..74b58bd 100644 --- a/linden/indra/newview/llfloatercustomize.cpp +++ b/linden/indra/newview/llfloatercustomize.cpp | |||
@@ -355,7 +355,9 @@ enum ESubpart { | |||
355 | SUBPART_GLOVES, | 355 | SUBPART_GLOVES, |
356 | SUBPART_UNDERSHIRT, | 356 | SUBPART_UNDERSHIRT, |
357 | SUBPART_UNDERPANTS, | 357 | SUBPART_UNDERPANTS, |
358 | SUBPART_SKIRT | 358 | SUBPART_SKIRT, |
359 | SUBPART_ALPHA, | ||
360 | SUBPART_TATTOO | ||
359 | }; | 361 | }; |
360 | 362 | ||
361 | struct LLSubpart | 363 | struct LLSubpart |
@@ -384,6 +386,7 @@ public: | |||
384 | 386 | ||
385 | void addSubpart(const std::string& name, ESubpart id, LLSubpart* part ); | 387 | void addSubpart(const std::string& name, ESubpart id, LLSubpart* part ); |
386 | void addTextureDropTarget( ETextureIndex te, const std::string& name, const LLUUID& default_image_id, BOOL allow_no_texture ); | 388 | void addTextureDropTarget( ETextureIndex te, const std::string& name, const LLUUID& default_image_id, BOOL allow_no_texture ); |
389 | void addInvisibilityCheckbox(ETextureIndex te, const std::string& name); | ||
387 | void addColorSwatch( ETextureIndex te, const std::string& name ); | 390 | void addColorSwatch( ETextureIndex te, const std::string& name ); |
388 | 391 | ||
389 | const std::string& getLabel() { return LLWearable::typeToTypeLabel( mType ); } | 392 | const std::string& getLabel() { return LLWearable::typeToTypeLabel( mType ); } |
@@ -398,6 +401,11 @@ public: | |||
398 | 401 | ||
399 | void setUIPermissions(U32 perm_mask, BOOL is_complete); | 402 | void setUIPermissions(U32 perm_mask, BOOL is_complete); |
400 | 403 | ||
404 | void hideTextureControls(); | ||
405 | bool textureIsInvisible(ETextureIndex te); | ||
406 | void initPreviousTextureList(); | ||
407 | void initPreviousTextureListEntry(ETextureIndex te); | ||
408 | |||
401 | virtual void setVisible( BOOL visible ); | 409 | virtual void setVisible( BOOL visible ); |
402 | 410 | ||
403 | // Callbacks | 411 | // Callbacks |
@@ -412,6 +420,7 @@ public: | |||
412 | static void onBtnTakeOffDialog( S32 option, void* userdata ); | 420 | static void onBtnTakeOffDialog( S32 option, void* userdata ); |
413 | static void onBtnCreateNew( void* userdata ); | 421 | static void onBtnCreateNew( void* userdata ); |
414 | static void onTextureCommit( LLUICtrl* ctrl, void* userdata ); | 422 | static void onTextureCommit( LLUICtrl* ctrl, void* userdata ); |
423 | static void onInvisibilityCommit( LLUICtrl* ctrl, void* userdata ); | ||
415 | static void onColorCommit( LLUICtrl* ctrl, void* userdata ); | 424 | static void onColorCommit( LLUICtrl* ctrl, void* userdata ); |
416 | static void onCommitSexChange( LLUICtrl*, void* userdata ); | 425 | static void onCommitSexChange( LLUICtrl*, void* userdata ); |
417 | static bool onSelectAutoWearOption(const LLSD& notification, const LLSD& response); | 426 | static bool onSelectAutoWearOption(const LLSD& notification, const LLSD& response); |
@@ -422,8 +431,10 @@ private: | |||
422 | EWearableType mType; | 431 | EWearableType mType; |
423 | BOOL mCanTakeOff; | 432 | BOOL mCanTakeOff; |
424 | std::map<std::string, S32> mTextureList; | 433 | std::map<std::string, S32> mTextureList; |
434 | std::map<std::string, S32> mInvisibilityList; | ||
425 | std::map<std::string, S32> mColorList; | 435 | std::map<std::string, S32> mColorList; |
426 | std::map<ESubpart, LLSubpart*> mSubpartList; | 436 | std::map<ESubpart, LLSubpart*> mSubpartList; |
437 | std::map<S32, LLUUID> mPreviousTextureList; | ||
427 | ESubpart mCurrentSubpart; | 438 | ESubpart mCurrentSubpart; |
428 | }; | 439 | }; |
429 | 440 | ||
@@ -658,6 +669,71 @@ bool LLPanelEditWearable::onSelectAutoWearOption(const LLSD& notification, const | |||
658 | } | 669 | } |
659 | return false; | 670 | return false; |
660 | } | 671 | } |
672 | |||
673 | bool LLPanelEditWearable::textureIsInvisible(ETextureIndex te) | ||
674 | { | ||
675 | if (gAgent.getWearable(mType)) | ||
676 | { | ||
677 | LLVOAvatar *avatar = gAgent.getAvatarObject(); | ||
678 | if (avatar) | ||
679 | { | ||
680 | const LLTextureEntry* current_te = avatar->getTE(te); | ||
681 | return (current_te && current_te->getID() == IMG_INVISIBLE); | ||
682 | } | ||
683 | } | ||
684 | return false; | ||
685 | } | ||
686 | |||
687 | void LLPanelEditWearable::addInvisibilityCheckbox(ETextureIndex te, const std::string& name) | ||
688 | { | ||
689 | childSetCommitCallback(name, LLPanelEditWearable::onInvisibilityCommit, this); | ||
690 | |||
691 | mInvisibilityList[name] = te; | ||
692 | } | ||
693 | |||
694 | // static | ||
695 | void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, void* userdata) | ||
696 | { | ||
697 | LLPanelEditWearable* self = (LLPanelEditWearable*) userdata; | ||
698 | LLCheckBoxCtrl* checkbox_ctrl = (LLCheckBoxCtrl*) ctrl; | ||
699 | LLVOAvatar *avatar = gAgent.getAvatarObject(); | ||
700 | if (!avatar) | ||
701 | { | ||
702 | return; | ||
703 | } | ||
704 | |||
705 | ETextureIndex te = (ETextureIndex)(self->mInvisibilityList[ctrl->getName()]); | ||
706 | |||
707 | bool new_invis_state = checkbox_ctrl->get(); | ||
708 | if (new_invis_state) | ||
709 | { | ||
710 | LLViewerImage* image = gImageList.getImage(IMG_INVISIBLE); | ||
711 | const LLTextureEntry* current_te = avatar->getTE(te); | ||
712 | if (current_te) | ||
713 | { | ||
714 | self->mPreviousTextureList[(S32)te] = current_te->getID(); | ||
715 | } | ||
716 | avatar->setLocTexTE(te, image, TRUE); | ||
717 | avatar->wearableUpdated(self->mType, FALSE); | ||
718 | } | ||
719 | else | ||
720 | { | ||
721 | // Try to restore previous texture, if any. | ||
722 | LLUUID prev_id = self->mPreviousTextureList[(S32)te]; | ||
723 | if (prev_id.isNull() || (prev_id == IMG_INVISIBLE)) | ||
724 | { | ||
725 | prev_id = LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")); | ||
726 | } | ||
727 | if (prev_id.notNull()) | ||
728 | { | ||
729 | LLViewerImage* image = gImageList.getImage(prev_id); | ||
730 | avatar->setLocTexTE(te, image, TRUE); | ||
731 | avatar->wearableUpdated(self->mType, FALSE); | ||
732 | } | ||
733 | |||
734 | } | ||
735 | } | ||
736 | |||
661 | void LLPanelEditWearable::addColorSwatch( ETextureIndex te, const std::string& name ) | 737 | void LLPanelEditWearable::addColorSwatch( ETextureIndex te, const std::string& name ) |
662 | { | 738 | { |
663 | childSetCommitCallback(name, LLPanelEditWearable::onColorCommit, this); | 739 | childSetCommitCallback(name, LLPanelEditWearable::onColorCommit, this); |
@@ -683,11 +759,35 @@ void LLPanelEditWearable::onColorCommit( LLUICtrl* ctrl, void* userdata ) | |||
683 | avatar->setClothesColor( te, new_color, TRUE ); | 759 | avatar->setClothesColor( te, new_color, TRUE ); |
684 | 760 | ||
685 | LLVisualParamHint::requestHintUpdates(); | 761 | LLVisualParamHint::requestHintUpdates(); |
762 | avatar->wearableUpdated(self->mType, FALSE); | ||
686 | } | 763 | } |
687 | } | 764 | } |
688 | } | 765 | } |
689 | 766 | ||
690 | 767 | ||
768 | void LLPanelEditWearable::initPreviousTextureList() | ||
769 | { | ||
770 | initPreviousTextureListEntry(TEX_LOWER_ALPHA); | ||
771 | initPreviousTextureListEntry(TEX_UPPER_ALPHA); | ||
772 | initPreviousTextureListEntry(TEX_HEAD_ALPHA); | ||
773 | initPreviousTextureListEntry(TEX_EYES_ALPHA); | ||
774 | initPreviousTextureListEntry(TEX_LOWER_ALPHA); | ||
775 | } | ||
776 | |||
777 | void LLPanelEditWearable::initPreviousTextureListEntry(ETextureIndex te) | ||
778 | { | ||
779 | LLVOAvatar* avatar = gAgent.getAvatarObject(); | ||
780 | if (!avatar) | ||
781 | { | ||
782 | return; | ||
783 | } | ||
784 | const LLTextureEntry* current_te = avatar->getTE(te); | ||
785 | if (current_te) | ||
786 | { | ||
787 | mPreviousTextureList[te] = current_te->getID(); | ||
788 | } | ||
789 | } | ||
790 | |||
691 | void LLPanelEditWearable::addTextureDropTarget( ETextureIndex te, const std::string& name, | 791 | void LLPanelEditWearable::addTextureDropTarget( ETextureIndex te, const std::string& name, |
692 | const LLUUID& default_image_id, BOOL allow_no_texture ) | 792 | const LLUUID& default_image_id, BOOL allow_no_texture ) |
693 | { | 793 | { |
@@ -702,6 +802,19 @@ void LLPanelEditWearable::addTextureDropTarget( ETextureIndex te, const std::str | |||
702 | texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE);//PERM_COPY | PERM_TRANSFER); | 802 | texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE);//PERM_COPY | PERM_TRANSFER); |
703 | } | 803 | } |
704 | mTextureList[name] = te; | 804 | mTextureList[name] = te; |
805 | LLVOAvatar* avatar = gAgent.getAvatarObject(); | ||
806 | if (avatar) | ||
807 | { | ||
808 | LLWearable* wearable = gAgent.getWearable(mType); | ||
809 | if (wearable && mType == WT_ALPHA) | ||
810 | { | ||
811 | const LLTextureEntry* current_te = avatar->getTE(te); | ||
812 | if (current_te) | ||
813 | { | ||
814 | mPreviousTextureList[te] = current_te->getID(); | ||
815 | } | ||
816 | } | ||
817 | } | ||
705 | } | 818 | } |
706 | 819 | ||
707 | // static | 820 | // static |
@@ -717,11 +830,20 @@ void LLPanelEditWearable::onTextureCommit( LLUICtrl* ctrl, void* userdata ) | |||
717 | 830 | ||
718 | // Set the new version | 831 | // Set the new version |
719 | LLViewerImage* image = gImageList.getImage( texture_ctrl->getImageAssetID() ); | 832 | LLViewerImage* image = gImageList.getImage( texture_ctrl->getImageAssetID() ); |
720 | if( image->getID().isNull() ) | 833 | if (image->getID().isNull()) |
721 | { | 834 | { |
722 | image = gImageList.getImage(IMG_DEFAULT_AVATAR); | 835 | image = gImageList.getImage(IMG_DEFAULT_AVATAR); |
723 | } | 836 | } |
724 | avatar->setLocTexTE( te, image, TRUE ); | 837 | self->mTextureList[ctrl->getName()] = te; |
838 | if (gAgent.getWearable(self->mType)) | ||
839 | { | ||
840 | avatar->setLocTexTE(te, image, TRUE); | ||
841 | avatar->wearableUpdated(self->mType, FALSE); | ||
842 | } | ||
843 | if (self->mType == WT_ALPHA && image->getID() != IMG_INVISIBLE) | ||
844 | { | ||
845 | self->mPreviousTextureList[te] = image->getID(); | ||
846 | } | ||
725 | } | 847 | } |
726 | } | 848 | } |
727 | 849 | ||
@@ -743,6 +865,8 @@ ESubpart LLPanelEditWearable::getDefaultSubpart() | |||
743 | case WT_UNDERSHIRT: return SUBPART_UNDERSHIRT; | 865 | case WT_UNDERSHIRT: return SUBPART_UNDERSHIRT; |
744 | case WT_UNDERPANTS: return SUBPART_UNDERPANTS; | 866 | case WT_UNDERPANTS: return SUBPART_UNDERPANTS; |
745 | case WT_SKIRT: return SUBPART_SKIRT; | 867 | case WT_SKIRT: return SUBPART_SKIRT; |
868 | case WT_ALPHA: return SUBPART_ALPHA; | ||
869 | case WT_TATTOO: return SUBPART_TATTOO; | ||
746 | 870 | ||
747 | default: llassert(0); return SUBPART_SHAPE_WHOLE; | 871 | default: llassert(0); return SUBPART_SHAPE_WHOLE; |
748 | } | 872 | } |
@@ -816,16 +940,7 @@ void LLPanelEditWearable::draw() | |||
816 | childSetVisible("title_no_modify", TRUE); | 940 | childSetVisible("title_no_modify", TRUE); |
817 | childSetTextArg("title_no_modify", "[DESC]", std::string(LLWearable::typeToTypeLabel( mType ))); | 941 | childSetTextArg("title_no_modify", "[DESC]", std::string(LLWearable::typeToTypeLabel( mType ))); |
818 | 942 | ||
819 | for( std::map<std::string, S32>::iterator iter = mTextureList.begin(); | 943 | hideTextureControls(); |
820 | iter != mTextureList.end(); ++iter ) | ||
821 | { | ||
822 | childSetVisible(iter->first, FALSE ); | ||
823 | } | ||
824 | for( std::map<std::string, S32>::iterator iter = mColorList.begin(); | ||
825 | iter != mColorList.end(); ++iter ) | ||
826 | { | ||
827 | childSetVisible(iter->first, FALSE ); | ||
828 | } | ||
829 | } | 944 | } |
830 | else if(has_wearable && !is_complete) | 945 | else if(has_wearable && !is_complete) |
831 | { | 946 | { |
@@ -839,16 +954,7 @@ void LLPanelEditWearable::draw() | |||
839 | childSetVisible("path", TRUE); | 954 | childSetVisible("path", TRUE); |
840 | childSetTextArg("path", "[PATH]", path); | 955 | childSetTextArg("path", "[PATH]", path); |
841 | 956 | ||
842 | for( std::map<std::string, S32>::iterator iter = mTextureList.begin(); | 957 | hideTextureControls(); |
843 | iter != mTextureList.end(); ++iter ) | ||
844 | { | ||
845 | childSetVisible(iter->first, FALSE ); | ||
846 | } | ||
847 | for( std::map<std::string, S32>::iterator iter = mColorList.begin(); | ||
848 | iter != mColorList.end(); ++iter ) | ||
849 | { | ||
850 | childSetVisible(iter->first, FALSE ); | ||
851 | } | ||
852 | } | 958 | } |
853 | else if(has_wearable && is_modifiable) | 959 | else if(has_wearable && is_modifiable) |
854 | { | 960 | { |
@@ -908,6 +1014,20 @@ void LLPanelEditWearable::draw() | |||
908 | ctrl->set(avatar->getClothesColor( (ETextureIndex)te_index ) ); | 1014 | ctrl->set(avatar->getClothesColor( (ETextureIndex)te_index ) ); |
909 | } | 1015 | } |
910 | } | 1016 | } |
1017 | |||
1018 | for (std::map<std::string, S32>::iterator iter = mInvisibilityList.begin(); | ||
1019 | iter != mInvisibilityList.end(); ++iter) | ||
1020 | { | ||
1021 | std::string name = iter->first; | ||
1022 | ETextureIndex te = (ETextureIndex)iter->second; | ||
1023 | childSetVisible(name, is_copyable && is_modifiable && is_complete); | ||
1024 | childSetEnabled(name, is_copyable && is_modifiable && is_complete); | ||
1025 | LLCheckBoxCtrl* ctrl = getChild<LLCheckBoxCtrl>(name); | ||
1026 | if (ctrl) | ||
1027 | { | ||
1028 | ctrl->set(textureIsInvisible(te)); | ||
1029 | } | ||
1030 | } | ||
911 | } | 1031 | } |
912 | else | 1032 | else |
913 | { | 1033 | { |
@@ -915,16 +1035,7 @@ void LLPanelEditWearable::draw() | |||
915 | childSetVisible("title_not_worn", TRUE); | 1035 | childSetVisible("title_not_worn", TRUE); |
916 | childSetTextArg("title_not_worn", "[DESC]", std::string(LLWearable::typeToTypeLabel( mType ))); | 1036 | childSetTextArg("title_not_worn", "[DESC]", std::string(LLWearable::typeToTypeLabel( mType ))); |
917 | 1037 | ||
918 | for( std::map<std::string, S32>::iterator iter = mTextureList.begin(); | 1038 | hideTextureControls(); |
919 | iter != mTextureList.end(); ++iter ) | ||
920 | { | ||
921 | childSetVisible(iter->first, FALSE ); | ||
922 | } | ||
923 | for( std::map<std::string, S32>::iterator iter = mColorList.begin(); | ||
924 | iter != mColorList.end(); ++iter ) | ||
925 | { | ||
926 | childSetVisible(iter->first, FALSE ); | ||
927 | } | ||
928 | } | 1039 | } |
929 | 1040 | ||
930 | childSetVisible("icon", has_wearable && is_modifiable); | 1041 | childSetVisible("icon", has_wearable && is_modifiable); |
@@ -932,11 +1043,34 @@ void LLPanelEditWearable::draw() | |||
932 | LLPanel::draw(); | 1043 | LLPanel::draw(); |
933 | } | 1044 | } |
934 | 1045 | ||
1046 | void LLPanelEditWearable::hideTextureControls() | ||
1047 | { | ||
1048 | for (std::map<std::string, S32>::iterator iter = mTextureList.begin(); | ||
1049 | iter != mTextureList.end(); ++iter) | ||
1050 | { | ||
1051 | childSetVisible(iter->first, FALSE); | ||
1052 | } | ||
1053 | for (std::map<std::string, S32>::iterator iter = mColorList.begin(); | ||
1054 | iter != mColorList.end(); ++iter) | ||
1055 | { | ||
1056 | childSetVisible(iter->first, FALSE); | ||
1057 | } | ||
1058 | for (std::map<std::string, S32>::iterator iter = mInvisibilityList.begin(); | ||
1059 | iter != mInvisibilityList.end(); ++iter) | ||
1060 | { | ||
1061 | childSetVisible(iter->first, FALSE); | ||
1062 | } | ||
1063 | } | ||
1064 | |||
935 | void LLPanelEditWearable::setWearable(LLWearable* wearable, U32 perm_mask, BOOL is_complete) | 1065 | void LLPanelEditWearable::setWearable(LLWearable* wearable, U32 perm_mask, BOOL is_complete) |
936 | { | 1066 | { |
937 | if( wearable ) | 1067 | if( wearable ) |
938 | { | 1068 | { |
939 | setUIPermissions(perm_mask, is_complete); | 1069 | setUIPermissions(perm_mask, is_complete); |
1070 | if (mType == WT_ALPHA) | ||
1071 | { | ||
1072 | initPreviousTextureList(); | ||
1073 | } | ||
940 | } | 1074 | } |
941 | } | 1075 | } |
942 | 1076 | ||
@@ -1029,6 +1163,11 @@ void LLPanelEditWearable::setUIPermissions(U32 perm_mask, BOOL is_complete) | |||
1029 | { | 1163 | { |
1030 | childSetVisible(iter->first, is_modifiable && is_complete ); | 1164 | childSetVisible(iter->first, is_modifiable && is_complete ); |
1031 | } | 1165 | } |
1166 | for (std::map<std::string, S32>::iterator iter = mInvisibilityList.begin(); | ||
1167 | iter != mInvisibilityList.end(); ++iter) | ||
1168 | { | ||
1169 | childSetVisible(iter->first, is_copyable && is_modifiable && is_complete); | ||
1170 | } | ||
1032 | } | 1171 | } |
1033 | 1172 | ||
1034 | ///////////////////////////////////////////////////////////////////// | 1173 | ///////////////////////////////////////////////////////////////////// |
@@ -1475,6 +1614,8 @@ LLFloaterCustomize::LLFloaterCustomize() | |||
1475 | factory_map["Undershirt"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_UNDERSHIRT) ) ); | 1614 | factory_map["Undershirt"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_UNDERSHIRT) ) ); |
1476 | factory_map["Underpants"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_UNDERPANTS) ) ); | 1615 | factory_map["Underpants"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_UNDERPANTS) ) ); |
1477 | factory_map["Skirt"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_SKIRT) ) ); | 1616 | factory_map["Skirt"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_SKIRT) ) ); |
1617 | factory_map["Alpha"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_ALPHA))); | ||
1618 | factory_map["Tattoo"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_TATTOO))); | ||
1478 | 1619 | ||
1479 | LLUICtrlFactory::getInstance()->buildFloater(this, "floater_customize.xml", &factory_map); | 1620 | LLUICtrlFactory::getInstance()->buildFloater(this, "floater_customize.xml", &factory_map); |
1480 | } | 1621 | } |
@@ -1506,6 +1647,8 @@ BOOL LLFloaterCustomize::postBuild() | |||
1506 | childSetTabChangeCallback("customize tab container", "Undershirt", onTabChanged, (void*)WT_UNDERSHIRT, onTabPrecommit ); | 1647 | childSetTabChangeCallback("customize tab container", "Undershirt", onTabChanged, (void*)WT_UNDERSHIRT, onTabPrecommit ); |
1507 | childSetTabChangeCallback("customize tab container", "Underpants", onTabChanged, (void*)WT_UNDERPANTS, onTabPrecommit ); | 1648 | childSetTabChangeCallback("customize tab container", "Underpants", onTabChanged, (void*)WT_UNDERPANTS, onTabPrecommit ); |
1508 | childSetTabChangeCallback("customize tab container", "Skirt", onTabChanged, (void*)WT_SKIRT, onTabPrecommit ); | 1649 | childSetTabChangeCallback("customize tab container", "Skirt", onTabChanged, (void*)WT_SKIRT, onTabPrecommit ); |
1650 | childSetTabChangeCallback("customize tab container", "Alpha", onTabChanged, (void*)WT_ALPHA, onTabPrecommit); | ||
1651 | childSetTabChangeCallback("customize tab container", "Tattoo", onTabChanged, (void*)WT_TATTOO, onTabPrecommit); | ||
1509 | 1652 | ||
1510 | // Remove underwear panels for teens | 1653 | // Remove underwear panels for teens |
1511 | if (gAgent.isTeen()) | 1654 | if (gAgent.isTeen()) |
@@ -1532,6 +1675,7 @@ void LLFloaterCustomize::open() | |||
1532 | LLFloater::open(); | 1675 | LLFloater::open(); |
1533 | // childShowTab depends on gFloaterCustomize being defined and therefore must be called after the constructor. - Nyx | 1676 | // childShowTab depends on gFloaterCustomize being defined and therefore must be called after the constructor. - Nyx |
1534 | childShowTab("customize tab container", "Shape", true); | 1677 | childShowTab("customize tab container", "Shape", true); |
1678 | setCurrentWearableType(WT_SHAPE); | ||
1535 | } | 1679 | } |
1536 | 1680 | ||
1537 | //////////////////////////////////////////////////////////////////////////// | 1681 | //////////////////////////////////////////////////////////////////////////// |
@@ -2136,6 +2280,66 @@ void LLFloaterCustomize::initWearablePanels() | |||
2136 | 2280 | ||
2137 | panel->addColorSwatch( TEX_LOWER_UNDERPANTS, "Color/Tint" ); | 2281 | panel->addColorSwatch( TEX_LOWER_UNDERPANTS, "Color/Tint" ); |
2138 | } | 2282 | } |
2283 | |||
2284 | ///////////////////////////////////////// | ||
2285 | // Alpha | ||
2286 | panel = mWearablePanelList[WT_ALPHA]; | ||
2287 | |||
2288 | if (panel) | ||
2289 | { | ||
2290 | part = new LLSubpart(); | ||
2291 | part->mTargetJoint = "mPelvis"; | ||
2292 | part->mEditGroup = "alpha"; | ||
2293 | part->mTargetOffset.setVec(0.f, 0.f, 0.1f); | ||
2294 | part->mCameraOffset.setVec(-2.5f, 0.5f, 0.8f); | ||
2295 | panel->addSubpart(LLStringUtil::null, SUBPART_ALPHA, part); | ||
2296 | |||
2297 | panel->addTextureDropTarget(TEX_LOWER_ALPHA, "Lower Alpha", | ||
2298 | LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")), | ||
2299 | TRUE); | ||
2300 | panel->addTextureDropTarget(TEX_UPPER_ALPHA, "Upper Alpha", | ||
2301 | LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")), | ||
2302 | TRUE); | ||
2303 | panel->addTextureDropTarget(TEX_HEAD_ALPHA, "Head Alpha", | ||
2304 | LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")), | ||
2305 | TRUE); | ||
2306 | panel->addTextureDropTarget(TEX_EYES_ALPHA, "Eye Alpha", | ||
2307 | LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")), | ||
2308 | TRUE); | ||
2309 | panel->addTextureDropTarget(TEX_HAIR_ALPHA, "Hair Alpha", | ||
2310 | LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")), | ||
2311 | TRUE); | ||
2312 | |||
2313 | panel->addInvisibilityCheckbox(TEX_LOWER_ALPHA, "lower alpha texture invisible"); | ||
2314 | panel->addInvisibilityCheckbox(TEX_UPPER_ALPHA, "upper alpha texture invisible"); | ||
2315 | panel->addInvisibilityCheckbox(TEX_HEAD_ALPHA, "head alpha texture invisible"); | ||
2316 | panel->addInvisibilityCheckbox(TEX_EYES_ALPHA, "eye alpha texture invisible"); | ||
2317 | panel->addInvisibilityCheckbox(TEX_HAIR_ALPHA, "hair alpha texture invisible"); | ||
2318 | } | ||
2319 | |||
2320 | ///////////////////////////////////////// | ||
2321 | // Tattoo | ||
2322 | panel = mWearablePanelList[WT_TATTOO]; | ||
2323 | |||
2324 | if (panel) | ||
2325 | { | ||
2326 | part = new LLSubpart(); | ||
2327 | part->mTargetJoint = "mPelvis"; | ||
2328 | part->mEditGroup = "tattoo"; | ||
2329 | part->mTargetOffset.setVec(0.f, 0.f, 0.1f); | ||
2330 | part->mCameraOffset.setVec(-2.5f, 0.5f, 0.8f); | ||
2331 | panel->addSubpart(LLStringUtil::null, SUBPART_TATTOO, part); | ||
2332 | |||
2333 | panel->addTextureDropTarget(TEX_LOWER_TATTOO, "Lower Tattoo", | ||
2334 | LLUUID::null, | ||
2335 | TRUE); | ||
2336 | panel->addTextureDropTarget(TEX_UPPER_TATTOO, "Upper Tattoo", | ||
2337 | LLUUID::null, | ||
2338 | TRUE); | ||
2339 | panel->addTextureDropTarget(TEX_HEAD_TATTOO, "Head Tattoo", | ||
2340 | LLUUID::null, | ||
2341 | TRUE); | ||
2342 | } | ||
2139 | } | 2343 | } |
2140 | 2344 | ||
2141 | //////////////////////////////////////////////////////////////////////////// | 2345 | //////////////////////////////////////////////////////////////////////////// |
@@ -2204,7 +2408,8 @@ BOOL LLFloaterCustomize::isDirty() const | |||
2204 | // static | 2408 | // static |
2205 | void LLFloaterCustomize::onTabPrecommit( void* userdata, bool from_click ) | 2409 | void LLFloaterCustomize::onTabPrecommit( void* userdata, bool from_click ) |
2206 | { | 2410 | { |
2207 | if (gFloaterCustomize && gFloaterCustomize->getCurrentWearableType() != (EWearableType)(intptr_t) userdata) | 2411 | EWearableType type = (EWearableType)(intptr_t) userdata; |
2412 | if (type != WT_INVALID && gFloaterCustomize && gFloaterCustomize->getCurrentWearableType() != type) | ||
2208 | { | 2413 | { |
2209 | gFloaterCustomize->askToSaveIfDirty(onCommitChangeTab, userdata); | 2414 | gFloaterCustomize->askToSaveIfDirty(onCommitChangeTab, userdata); |
2210 | } | 2415 | } |
@@ -2219,7 +2424,10 @@ void LLFloaterCustomize::onTabPrecommit( void* userdata, bool from_click ) | |||
2219 | void LLFloaterCustomize::onTabChanged( void* userdata, bool from_click ) | 2424 | void LLFloaterCustomize::onTabChanged( void* userdata, bool from_click ) |
2220 | { | 2425 | { |
2221 | EWearableType wearable_type = (EWearableType) (intptr_t)userdata; | 2426 | EWearableType wearable_type = (EWearableType) (intptr_t)userdata; |
2222 | LLFloaterCustomize::setCurrentWearableType( wearable_type ); | 2427 | if (wearable_type != WT_INVALID) |
2428 | { | ||
2429 | LLFloaterCustomize::setCurrentWearableType(wearable_type); | ||
2430 | } | ||
2223 | } | 2431 | } |
2224 | 2432 | ||
2225 | void LLFloaterCustomize::onClose(bool app_quitting) | 2433 | void LLFloaterCustomize::onClose(bool app_quitting) |
diff --git a/linden/indra/newview/llinventoryactions.cpp b/linden/indra/newview/llinventoryactions.cpp index d7af8d1..319b5b2 100644 --- a/linden/indra/newview/llinventoryactions.cpp +++ b/linden/indra/newview/llinventoryactions.cpp | |||
@@ -428,6 +428,16 @@ void do_create(LLInventoryModel *model, LLInventoryPanel *ptr, std::string type, | |||
428 | LLUUID parent_id = self ? self->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING); | 428 | LLUUID parent_id = self ? self->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING); |
429 | LLFolderBridge::createWearable(parent_id, WT_UNDERPANTS); | 429 | LLFolderBridge::createWearable(parent_id, WT_UNDERPANTS); |
430 | } | 430 | } |
431 | else if ("alpha" == type) | ||
432 | { | ||
433 | LLUUID parent_id = self ? self->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING); | ||
434 | LLFolderBridge::createWearable(parent_id, WT_ALPHA); | ||
435 | } | ||
436 | else if ("tattoo" == type) | ||
437 | { | ||
438 | LLUUID parent_id = self ? self->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING); | ||
439 | LLFolderBridge::createWearable(parent_id, WT_TATTOO); | ||
440 | } | ||
431 | else if ("shape" == type) | 441 | else if ("shape" == type) |
432 | { | 442 | { |
433 | LLUUID parent_id = self ? self->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_BODYPART); | 443 | LLUUID parent_id = self ? self->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_BODYPART); |
diff --git a/linden/indra/newview/llinventorybridge.cpp b/linden/indra/newview/llinventorybridge.cpp index 42af09a..1f24d14 100644 --- a/linden/indra/newview/llinventorybridge.cpp +++ b/linden/indra/newview/llinventorybridge.cpp | |||
@@ -144,6 +144,8 @@ std::string ICON_NAME[ICON_NAME_COUNT] = | |||
144 | "inv_item_undershirt.tga", | 144 | "inv_item_undershirt.tga", |
145 | "inv_item_underpants.tga", | 145 | "inv_item_underpants.tga", |
146 | "inv_item_skirt.tga", | 146 | "inv_item_skirt.tga", |
147 | "inv_item_alpha.tga", | ||
148 | "inv_item_tattoo.tga", | ||
147 | 149 | ||
148 | "inv_item_animation.tga", | 150 | "inv_item_animation.tga", |
149 | "inv_item_gesture.tga", | 151 | "inv_item_gesture.tga", |
@@ -2208,6 +2210,16 @@ void LLFolderBridge::createNewUnderpants(void* user_data) | |||
2208 | LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_UNDERPANTS); | 2210 | LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_UNDERPANTS); |
2209 | } | 2211 | } |
2210 | 2212 | ||
2213 | void LLFolderBridge::createNewAlpha(void* user_data) | ||
2214 | { | ||
2215 | LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_ALPHA); | ||
2216 | } | ||
2217 | |||
2218 | void LLFolderBridge::createNewTattoo(void* user_data) | ||
2219 | { | ||
2220 | LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_TATTOO); | ||
2221 | } | ||
2222 | |||
2211 | void LLFolderBridge::createNewShape(void* user_data) | 2223 | void LLFolderBridge::createNewShape(void* user_data) |
2212 | { | 2224 | { |
2213 | LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SHAPE); | 2225 | LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SHAPE); |
diff --git a/linden/indra/newview/llinventorybridge.h b/linden/indra/newview/llinventorybridge.h index 3f4cfb0..53540b0 100644 --- a/linden/indra/newview/llinventorybridge.h +++ b/linden/indra/newview/llinventorybridge.h | |||
@@ -64,6 +64,8 @@ enum EInventoryIcon | |||
64 | CLOTHING_UNDERSHIRT_ICON_NAME, | 64 | CLOTHING_UNDERSHIRT_ICON_NAME, |
65 | CLOTHING_UNDERPANTS_ICON_NAME, | 65 | CLOTHING_UNDERPANTS_ICON_NAME, |
66 | CLOTHING_SKIRT_ICON_NAME, | 66 | CLOTHING_SKIRT_ICON_NAME, |
67 | CLOTHING_ALPHA_ICON_NAME, | ||
68 | CLOTHING_TATTOO_ICON_NAME, | ||
67 | 69 | ||
68 | ANIMATION_ICON_NAME, | 70 | ANIMATION_ICON_NAME, |
69 | GESTURE_ICON_NAME, | 71 | GESTURE_ICON_NAME, |
@@ -328,6 +330,8 @@ protected: | |||
328 | static void createNewGloves(void* user_data); | 330 | static void createNewGloves(void* user_data); |
329 | static void createNewUndershirt(void* user_data); | 331 | static void createNewUndershirt(void* user_data); |
330 | static void createNewUnderpants(void* user_data); | 332 | static void createNewUnderpants(void* user_data); |
333 | static void createNewAlpha(void* user_data); | ||
334 | static void createNewTattoo(void* user_data); | ||
331 | static void createNewShape(void* user_data); | 335 | static void createNewShape(void* user_data); |
332 | static void createNewSkin(void* user_data); | 336 | static void createNewSkin(void* user_data); |
333 | static void createNewHair(void* user_data); | 337 | static void createNewHair(void* user_data); |
diff --git a/linden/indra/newview/llinventoryview.cpp b/linden/indra/newview/llinventoryview.cpp index aee67b4..7be1542 100644 --- a/linden/indra/newview/llinventoryview.cpp +++ b/linden/indra/newview/llinventoryview.cpp | |||
@@ -1485,6 +1485,12 @@ std::string get_item_icon_name(LLInventoryType::NType inv_ntype, | |||
1485 | case LLInventoryType::NIT_SKIRT: | 1485 | case LLInventoryType::NIT_SKIRT: |
1486 | idx = CLOTHING_SKIRT_ICON_NAME; | 1486 | idx = CLOTHING_SKIRT_ICON_NAME; |
1487 | break; | 1487 | break; |
1488 | case LLInventoryType::NIT_ALPHA: | ||
1489 | idx = CLOTHING_ALPHA_ICON_NAME; | ||
1490 | break; | ||
1491 | case LLInventoryType::NIT_TATTOO: | ||
1492 | idx = CLOTHING_TATTOO_ICON_NAME; | ||
1493 | break; | ||
1488 | 1494 | ||
1489 | case LLInventoryType::NIT_CLOTHING: | 1495 | case LLInventoryType::NIT_CLOTHING: |
1490 | idx = CLOTHING_ICON_NAME; | 1496 | idx = CLOTHING_ICON_NAME; |
diff --git a/linden/indra/newview/lltexlayer.cpp b/linden/indra/newview/lltexlayer.cpp index 968c496..664f4fd 100644 --- a/linden/indra/newview/lltexlayer.cpp +++ b/linden/indra/newview/lltexlayer.cpp | |||
@@ -63,7 +63,6 @@ using namespace LLVOAvatarDefines; | |||
63 | 63 | ||
64 | // static | 64 | // static |
65 | S32 LLTexLayerSetBuffer::sGLByteCount = 0; | 65 | S32 LLTexLayerSetBuffer::sGLByteCount = 0; |
66 | S32 LLTexLayerSetBuffer::sGLBumpByteCount = 0; | ||
67 | 66 | ||
68 | //----------------------------------------------------------------------------- | 67 | //----------------------------------------------------------------------------- |
69 | // LLBakedUploadData() | 68 | // LLBakedUploadData() |
@@ -92,7 +91,7 @@ LLBakedUploadData::LLBakedUploadData( LLVOAvatar* avatar, | |||
92 | // LLTexLayerSetBuffer | 91 | // LLTexLayerSetBuffer |
93 | // The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one. | 92 | // The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one. |
94 | //----------------------------------------------------------------------------- | 93 | //----------------------------------------------------------------------------- |
95 | LLTexLayerSetBuffer::LLTexLayerSetBuffer( LLTexLayerSet* owner, S32 width, S32 height, BOOL has_bump ) | 94 | LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* owner, S32 width, S32 height) |
96 | : | 95 | : |
97 | // ORDER_LAST => must render these after the hints are created. | 96 | // ORDER_LAST => must render these after the hints are created. |
98 | LLDynamicTexture( width, height, 4, LLDynamicTexture::ORDER_LAST, TRUE ), | 97 | LLDynamicTexture( width, height, 4, LLDynamicTexture::ORDER_LAST, TRUE ), |
@@ -102,84 +101,39 @@ LLTexLayerSetBuffer::LLTexLayerSetBuffer( LLTexLayerSet* owner, S32 width, S32 h | |||
102 | mTexLayerSet( owner ) | 101 | mTexLayerSet( owner ) |
103 | { | 102 | { |
104 | LLTexLayerSetBuffer::sGLByteCount += getSize(); | 103 | LLTexLayerSetBuffer::sGLByteCount += getSize(); |
105 | mHasBump = has_bump ; | ||
106 | mBumpTex = NULL ; | ||
107 | |||
108 | createBumpTexture() ; | ||
109 | } | 104 | } |
110 | 105 | ||
111 | LLTexLayerSetBuffer::~LLTexLayerSetBuffer() | 106 | LLTexLayerSetBuffer::~LLTexLayerSetBuffer() |
112 | { | 107 | { |
113 | LLTexLayerSetBuffer::sGLByteCount -= getSize(); | 108 | LLTexLayerSetBuffer::sGLByteCount -= getSize(); |
114 | 109 | destroyGLTexture(); | |
115 | if( mBumpTex.notNull()) | 110 | for (S32 order = 0; order < ORDER_COUNT; order++) |
116 | { | 111 | { |
117 | mBumpTex = NULL ; | 112 | LLDynamicTexture::sInstances[order].erase(this); // will fail in all but one case. |
118 | LLTexLayerSetBuffer::sGLBumpByteCount -= mWidth * mHeight * 4; | 113 | } |
114 | if (mTexLayerSet->mComposite == this) | ||
115 | { | ||
116 | // Destroy the pointer on this now gone buffer. | ||
117 | mTexLayerSet->mComposite = NULL; | ||
119 | } | 118 | } |
120 | } | 119 | } |
120 | |||
121 | //virtual | 121 | //virtual |
122 | void LLTexLayerSetBuffer::restoreGLTexture() | 122 | void LLTexLayerSetBuffer::restoreGLTexture() |
123 | { | 123 | { |
124 | createBumpTexture() ; | ||
125 | LLDynamicTexture::restoreGLTexture() ; | 124 | LLDynamicTexture::restoreGLTexture() ; |
126 | } | 125 | } |
127 | 126 | ||
128 | //virtual | 127 | //virtual |
129 | void LLTexLayerSetBuffer::destroyGLTexture() | 128 | void LLTexLayerSetBuffer::destroyGLTexture() |
130 | { | 129 | { |
131 | if( mBumpTex.notNull() ) | ||
132 | { | ||
133 | mBumpTex = NULL ; | ||
134 | //LLImageGL::sGlobalTextureMemoryInBytes -= mWidth * mHeight * 4; | ||
135 | LLTexLayerSetBuffer::sGLBumpByteCount -= mWidth * mHeight * 4; | ||
136 | } | ||
137 | |||
138 | LLDynamicTexture::destroyGLTexture() ; | 130 | LLDynamicTexture::destroyGLTexture() ; |
139 | } | 131 | } |
140 | 132 | ||
141 | void LLTexLayerSetBuffer::createBumpTexture() | ||
142 | { | ||
143 | if( mHasBump ) | ||
144 | { | ||
145 | LLGLSUIDefault gls_ui; | ||
146 | mBumpTex = new LLImageGL(FALSE) ; | ||
147 | if(!mBumpTex->createGLTexture()) | ||
148 | { | ||
149 | mBumpTex = NULL ; | ||
150 | return ; | ||
151 | } | ||
152 | |||
153 | gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName()); | ||
154 | stop_glerror(); | ||
155 | |||
156 | gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); | ||
157 | |||
158 | gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); | ||
159 | |||
160 | LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA8, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, NULL); | ||
161 | stop_glerror(); | ||
162 | |||
163 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | ||
164 | |||
165 | LLImageGL::sGlobalTextureMemoryInBytes += mWidth * mHeight * 4; | ||
166 | LLTexLayerSetBuffer::sGLBumpByteCount += mWidth * mHeight * 4; | ||
167 | |||
168 | if(gAuditTexture) | ||
169 | { | ||
170 | mBumpTex->setCategory(LLViewerImageBoostLevel::TEXLAYER_BUMP) ; | ||
171 | mBumpTex->setTextureSize(mWidth * mHeight * 4) ; | ||
172 | mBumpTex->setComponents(4) ; | ||
173 | mBumpTex->incTextureCounter() ; | ||
174 | } | ||
175 | } | ||
176 | } | ||
177 | |||
178 | // static | 133 | // static |
179 | void LLTexLayerSetBuffer::dumpTotalByteCount() | 134 | void LLTexLayerSetBuffer::dumpTotalByteCount() |
180 | { | 135 | { |
181 | llinfos << "Composite System GL Buffers: " << (LLTexLayerSetBuffer::sGLByteCount/1024) << "KB" << llendl; | 136 | llinfos << "Composite System GL Buffers: " << (LLTexLayerSetBuffer::sGLByteCount/1024) << "KB" << llendl; |
182 | llinfos << "Composite System GL Bump Buffers: " << (LLTexLayerSetBuffer::sGLBumpByteCount/1024) << "KB" << llendl; | ||
183 | } | 137 | } |
184 | 138 | ||
185 | void LLTexLayerSetBuffer::requestUpdate() | 139 | void LLTexLayerSetBuffer::requestUpdate() |
@@ -233,8 +187,8 @@ void LLTexLayerSetBuffer::popProjection() | |||
233 | BOOL LLTexLayerSetBuffer::needsRender() | 187 | BOOL LLTexLayerSetBuffer::needsRender() |
234 | { | 188 | { |
235 | LLVOAvatar* avatar = mTexLayerSet->getAvatar(); | 189 | LLVOAvatar* avatar = mTexLayerSet->getAvatar(); |
236 | BOOL upload_now = mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal(); | 190 | BOOL upload_now = mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal() && gAgent.mNumPendingQueries == 0; |
237 | BOOL needs_update = gAgent.mNumPendingQueries == 0 && (mNeedsUpdate || upload_now) && !avatar->mAppearanceAnimating; | 191 | BOOL needs_update = (mNeedsUpdate || upload_now) && !avatar->mAppearanceAnimating; |
238 | if (needs_update) | 192 | if (needs_update) |
239 | { | 193 | { |
240 | BOOL invalid_skirt = avatar->getBakedTE(mTexLayerSet) == TEX_SKIRT_BAKED && !avatar->isWearingWearableType(WT_SKIRT); | 194 | BOOL invalid_skirt = avatar->getBakedTE(mTexLayerSet) == TEX_SKIRT_BAKED && !avatar->isWearingWearableType(WT_SKIRT); |
@@ -272,8 +226,6 @@ void LLTexLayerSetBuffer::postRender(BOOL success) | |||
272 | 226 | ||
273 | BOOL LLTexLayerSetBuffer::render() | 227 | BOOL LLTexLayerSetBuffer::render() |
274 | { | 228 | { |
275 | U8* baked_bump_data = NULL; | ||
276 | |||
277 | // Default color mask for tex layer render | 229 | // Default color mask for tex layer render |
278 | gGL.setColorMask(true, true); | 230 | gGL.setColorMask(true, true); |
279 | 231 | ||
@@ -282,34 +234,6 @@ BOOL LLTexLayerSetBuffer::render() | |||
282 | BOOL upload_now = (gAgent.mNumPendingQueries == 0 && mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal()); | 234 | BOOL upload_now = (gAgent.mNumPendingQueries == 0 && mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal()); |
283 | BOOL success = TRUE; | 235 | BOOL success = TRUE; |
284 | 236 | ||
285 | // Composite bump | ||
286 | if( mBumpTex.notNull() ) | ||
287 | { | ||
288 | // Composite the bump data | ||
289 | success &= mTexLayerSet->renderBump( mOrigin.mX, mOrigin.mY, mWidth, mHeight ); | ||
290 | stop_glerror(); | ||
291 | |||
292 | if (success) | ||
293 | { | ||
294 | LLGLSUIDefault gls_ui; | ||
295 | |||
296 | // read back into texture (this is done externally for the color data) | ||
297 | gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName()); | ||
298 | stop_glerror(); | ||
299 | |||
300 | glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mOrigin.mX, mOrigin.mY, mWidth, mHeight); | ||
301 | stop_glerror(); | ||
302 | |||
303 | // if we need to upload the data, read it back into a buffer | ||
304 | if( upload_now ) | ||
305 | { | ||
306 | baked_bump_data = new U8[ mWidth * mHeight * 4 ]; | ||
307 | glReadPixels(mOrigin.mX, mOrigin.mY, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_bump_data ); | ||
308 | stop_glerror(); | ||
309 | } | ||
310 | } | ||
311 | } | ||
312 | |||
313 | // Composite the color data | 237 | // Composite the color data |
314 | LLGLSUIDefault gls_ui; | 238 | LLGLSUIDefault gls_ui; |
315 | success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mWidth, mHeight ); | 239 | success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mWidth, mHeight ); |
@@ -319,13 +243,26 @@ BOOL LLTexLayerSetBuffer::render() | |||
319 | { | 243 | { |
320 | if (!success) | 244 | if (!success) |
321 | { | 245 | { |
322 | delete [] baked_bump_data; | ||
323 | llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegion() << llendl; | 246 | llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegion() << llendl; |
324 | mUploadPending = FALSE; | 247 | mUploadPending = FALSE; |
325 | } | 248 | } |
326 | else | 249 | else |
327 | { | 250 | { |
328 | readBackAndUpload(baked_bump_data); | 251 | if (mTexLayerSet->isVisible()) |
252 | { | ||
253 | readBackAndUpload(); | ||
254 | } | ||
255 | else | ||
256 | { | ||
257 | mUploadPending = FALSE; | ||
258 | mNeedsUpload = FALSE; | ||
259 | LLVOAvatar* avatar = mTexLayerSet->getAvatar(); | ||
260 | if (avatar) | ||
261 | { | ||
262 | avatar->setNewBakedTexture(avatar->getBakedTE(mTexLayerSet), IMG_INVISIBLE); | ||
263 | llinfos << "Invisible baked texture set for " << mTexLayerSet->getBodyRegion() << llendl; | ||
264 | } | ||
265 | } | ||
329 | } | 266 | } |
330 | } | 267 | } |
331 | 268 | ||
@@ -360,7 +297,7 @@ BOOL LLTexLayerSetBuffer::updateImmediate() | |||
360 | return result; | 297 | return result; |
361 | } | 298 | } |
362 | 299 | ||
363 | void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data) | 300 | void LLTexLayerSetBuffer::readBackAndUpload() |
364 | { | 301 | { |
365 | // pointers for storing data to upload | 302 | // pointers for storing data to upload |
366 | U8* baked_color_data = new U8[ mWidth * mHeight * 4 ]; | 303 | U8* baked_color_data = new U8[ mWidth * mHeight * 4 ]; |
@@ -390,79 +327,23 @@ void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data) | |||
390 | // writes into baked_color_data | 327 | // writes into baked_color_data |
391 | const char* comment_text = NULL; | 328 | const char* comment_text = NULL; |
392 | 329 | ||
393 | S32 baked_image_components = mBumpTex.notNull() ? 5 : 4; // red green blue [bump] clothing | 330 | S32 baked_image_components = 5; // red green blue bump clothing |
394 | LLPointer<LLImageRaw> baked_image = new LLImageRaw( mWidth, mHeight, baked_image_components ); | 331 | LLPointer<LLImageRaw> baked_image = new LLImageRaw( mWidth, mHeight, baked_image_components ); |
395 | U8* baked_image_data = baked_image->getData(); | 332 | U8* baked_image_data = baked_image->getData(); |
396 | 333 | ||
397 | if( mBumpTex.notNull() ) | 334 | comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // 5 channels: rgb, heightfield/alpha, mask |
398 | { | ||
399 | comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // 5 channels: rgb, heightfield/alpha, mask | ||
400 | 335 | ||
401 | // Hide the alpha for the eyelashes in a corner of the bump map | 336 | S32 i = 0; |
402 | if (mTexLayerSet->getBodyRegion() == "head") | 337 | for (S32 u = 0; u < mWidth; u++) |
403 | { | 338 | { |
404 | S32 i = 0; | 339 | for (S32 v = 0; v < mHeight; v++) |
405 | for( S32 u = 0; u < mWidth; u++ ) | ||
406 | { | ||
407 | for( S32 v = 0; v < mHeight; v++ ) | ||
408 | { | ||
409 | baked_image_data[5*i + 0] = baked_color_data[4*i + 0]; | ||
410 | baked_image_data[5*i + 1] = baked_color_data[4*i + 1]; | ||
411 | baked_image_data[5*i + 2] = baked_color_data[4*i + 2]; | ||
412 | baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes. | ||
413 | baked_image_data[5*i + 4] = baked_mask_data[i]; | ||
414 | i++; | ||
415 | } | ||
416 | } | ||
417 | } | ||
418 | else | ||
419 | { | 340 | { |
420 | S32 i = 0; | 341 | baked_image_data[5 * i + 0] = baked_color_data[4 * i + 0]; |
421 | for( S32 u = 0; u < mWidth; u++ ) | 342 | baked_image_data[5 * i + 1] = baked_color_data[4 * i + 1]; |
422 | { | 343 | baked_image_data[5 * i + 2] = baked_color_data[4 * i + 2]; |
423 | for( S32 v = 0; v < mHeight; v++ ) | 344 | baked_image_data[5 * i + 3] = baked_color_data[4 * i + 3]; // alpha should be correct for eyelashes. |
424 | { | 345 | baked_image_data[5 * i + 4] = baked_mask_data[i]; |
425 | baked_image_data[5*i + 0] = baked_color_data[4*i + 0]; | 346 | i++; |
426 | baked_image_data[5*i + 1] = baked_color_data[4*i + 1]; | ||
427 | baked_image_data[5*i + 2] = baked_color_data[4*i + 2]; | ||
428 | baked_image_data[5*i + 3] = 255; // reserve for alpha | ||
429 | baked_image_data[5*i + 4] = baked_mask_data[i]; | ||
430 | i++; | ||
431 | } | ||
432 | } | ||
433 | } | ||
434 | } | ||
435 | else | ||
436 | { | ||
437 | if (mTexLayerSet->getBodyRegion() == "skirt" || mTexLayerSet->getBodyRegion() == "hair") | ||
438 | { | ||
439 | S32 i = 0; | ||
440 | for( S32 u = 0; u < mWidth; u++ ) | ||
441 | { | ||
442 | for( S32 v = 0; v < mHeight; v++ ) | ||
443 | { | ||
444 | baked_image_data[4*i + 0] = baked_color_data[4*i + 0]; | ||
445 | baked_image_data[4*i + 1] = baked_color_data[4*i + 1]; | ||
446 | baked_image_data[4*i + 2] = baked_color_data[4*i + 2]; | ||
447 | baked_image_data[4*i + 3] = baked_color_data[4*i + 3]; // Use alpha, not bump | ||
448 | i++; | ||
449 | } | ||
450 | } | ||
451 | } | ||
452 | else | ||
453 | { | ||
454 | S32 i = 0; | ||
455 | for( S32 u = 0; u < mWidth; u++ ) | ||
456 | { | ||
457 | for( S32 v = 0; v < mHeight; v++ ) | ||
458 | { | ||
459 | baked_image_data[4*i + 0] = baked_color_data[4*i + 0]; | ||
460 | baked_image_data[4*i + 1] = baked_color_data[4*i + 1]; | ||
461 | baked_image_data[4*i + 2] = baked_color_data[4*i + 2]; | ||
462 | baked_image_data[4*i + 3] = 255; // eyes should have no mask - reserve for alpha | ||
463 | i++; | ||
464 | } | ||
465 | } | ||
466 | } | 347 | } |
467 | } | 348 | } |
468 | 349 | ||
@@ -543,7 +424,6 @@ void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data) | |||
543 | } | 424 | } |
544 | 425 | ||
545 | delete [] baked_color_data; | 426 | delete [] baked_color_data; |
546 | delete [] baked_bump_data; | ||
547 | } | 427 | } |
548 | 428 | ||
549 | 429 | ||
@@ -554,89 +434,64 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, void* user | |||
554 | 434 | ||
555 | LLVOAvatar* avatar = gAgent.getAvatarObject(); | 435 | LLVOAvatar* avatar = gAgent.getAvatarObject(); |
556 | 436 | ||
557 | if (0 == result && avatar && !avatar->isDead()) | 437 | if (0 == result && |
438 | avatar && !avatar->isDead() && | ||
439 | baked_upload_data->mAvatar == avatar && // Sanity check: only the user's avatar should be uploading textures. | ||
440 | baked_upload_data->mLayerSet->hasComposite()) | ||
558 | { | 441 | { |
559 | // Sanity check: only the user's avatar should be uploading textures. | 442 | LLTexLayerSetBuffer* layerset_buffer = baked_upload_data->mLayerSet->getComposite(); |
560 | if( baked_upload_data->mAvatar == avatar ) | 443 | |
444 | if (layerset_buffer->mUploadID.isNull()) | ||
445 | { | ||
446 | // The upload got canceled, we should be in the | ||
447 | // process of baking a new texture so request an | ||
448 | // upload with the new data | ||
449 | |||
450 | // BAP: does this really belong in this callback, as | ||
451 | // opposed to where the cancellation takes place? | ||
452 | // suspect this does nothing. | ||
453 | layerset_buffer->requestUpload(); | ||
454 | } | ||
455 | else if (baked_upload_data->mID == layerset_buffer->mUploadID) | ||
561 | { | 456 | { |
562 | // Composite may have changed since the pointer was stored - need to do some checking. | 457 | // This is the upload we're currently waiting for. |
563 | LLTexLayerSetBuffer* prev_layerset_buffer = baked_upload_data->mLayerSetBuffer; | 458 | layerset_buffer->mUploadID.setNull(); |
564 | // Can't just call getComposite() because this will trigger creation if none exists. | 459 | layerset_buffer->mUploadPending = FALSE; |
565 | LLTexLayerSetBuffer* curr_layerset_buffer = | ||
566 | baked_upload_data->mLayerSet->hasComposite()?baked_upload_data->mLayerSet->getComposite():NULL; | ||
567 | 460 | ||
568 | if (prev_layerset_buffer != curr_layerset_buffer) | 461 | if (result >= 0) |
569 | { | 462 | { |
570 | llinfos << "Baked texture out of date, composite no longer valid, ignored" << llendl; | 463 | ETextureIndex baked_te = avatar->getBakedTE(layerset_buffer->mTexLayerSet); |
464 | U64 now = LLFrameTimer::getTotalTime(); // Record starting time | ||
465 | llinfos << "Baked texture upload took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl; | ||
466 | avatar->setNewBakedTexture(baked_te, uuid); | ||
571 | } | 467 | } |
572 | else | 468 | else |
573 | { | 469 | { |
574 | curr_layerset_buffer->mUploadPending = FALSE; | 470 | // Avatar appearance is changing, ignore the upload results |
575 | 471 | llinfos << "Baked upload failed. Reason: " << result << llendl; | |
576 | if (curr_layerset_buffer->mUploadID.isNull()) | 472 | // *FIX: retry upload after n seconds, asset server could be busy |
577 | { | ||
578 | // The upload got canceled, we should be in the process of baking a new texture | ||
579 | // so request an upload with the new data | ||
580 | curr_layerset_buffer->requestUpload(); | ||
581 | } | ||
582 | else if( baked_upload_data->mID == curr_layerset_buffer->mUploadID ) | ||
583 | { | ||
584 | // This is the upload we're currently waiting for. | ||
585 | curr_layerset_buffer->mUploadID.setNull(); | ||
586 | |||
587 | if( result >= 0 ) | ||
588 | { | ||
589 | ETextureIndex baked_te = avatar->getBakedTE( curr_layerset_buffer->mTexLayerSet ); | ||
590 | U64 now = LLFrameTimer::getTotalTime(); // Record starting time | ||
591 | llinfos << "Baked texture upload took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl; | ||
592 | avatar->setNewBakedTexture( baked_te, uuid ); | ||
593 | } | ||
594 | else | ||
595 | { | ||
596 | llinfos << "Baked upload failed. Reason: " << result << llendl; | ||
597 | // *FIX: retry upload after n seconds, asset server could be busy | ||
598 | } | ||
599 | } | ||
600 | else | ||
601 | { | ||
602 | llinfos << "Received baked texture out of date, ignored." << llendl; | ||
603 | } | ||
604 | |||
605 | avatar->dirtyMesh(); | ||
606 | } | 473 | } |
607 | } | 474 | } |
475 | else | ||
476 | { | ||
477 | llinfos << "Received baked texture out of date, ignored." << llendl; | ||
478 | } | ||
479 | |||
480 | avatar->dirtyMesh(); | ||
608 | } | 481 | } |
609 | else | 482 | else |
610 | { | 483 | { |
611 | // Baked texture failed to upload, but since we didn't set the new baked texture, it means that they'll | 484 | // Baked texture failed to upload (in which case since we |
612 | // try and rebake it at some point in the future (after login?) | 485 | // didn't set the new baked texture, it means that they'll try |
486 | // and rebake it at some point in the future (after login?)), | ||
487 | // or this response to upload is out of date, in which case a | ||
488 | // current response should be on the way or already processed. | ||
613 | llwarns << "Baked upload failed" << llendl; | 489 | llwarns << "Baked upload failed" << llendl; |
614 | } | 490 | } |
615 | 491 | ||
616 | delete baked_upload_data; | 492 | delete baked_upload_data; |
617 | } | 493 | } |
618 | 494 | ||
619 | void LLTexLayerSetBuffer::bindBumpTexture( U32 stage ) | ||
620 | { | ||
621 | if( mBumpTex.notNull() ) | ||
622 | { | ||
623 | gGL.getTexUnit(stage)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName()); | ||
624 | gGL.getTexUnit(0)->activate(); | ||
625 | |||
626 | if( mLastBindTime != LLImageGL::sLastFrameTime ) | ||
627 | { | ||
628 | mLastBindTime = LLImageGL::sLastFrameTime; | ||
629 | mBumpTex->updateBoundTexMem(); | ||
630 | } | ||
631 | } | ||
632 | else | ||
633 | { | ||
634 | gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE); | ||
635 | gGL.getTexUnit(0)->activate(); | ||
636 | } | ||
637 | } | ||
638 | |||
639 | |||
640 | //----------------------------------------------------------------------------- | 495 | //----------------------------------------------------------------------------- |
641 | // LLTexLayerSet | 496 | // LLTexLayerSet |
642 | // An ordered set of texture layers that get composited into a single texture. | 497 | // An ordered set of texture layers that get composited into a single texture. |
@@ -720,15 +575,19 @@ LLTexLayerSet::LLTexLayerSet( LLVOAvatar* avatar ) | |||
720 | mComposite( NULL ), | 575 | mComposite( NULL ), |
721 | mAvatar( avatar ), | 576 | mAvatar( avatar ), |
722 | mUpdatesEnabled( FALSE ), | 577 | mUpdatesEnabled( FALSE ), |
723 | mHasBump( FALSE ), | 578 | mIsVisible(TRUE), |
579 | mBakedTexIndex(BAKED_HEAD), | ||
724 | mInfo( NULL ) | 580 | mInfo( NULL ) |
725 | { | 581 | { |
726 | } | 582 | } |
727 | 583 | ||
728 | LLTexLayerSet::~LLTexLayerSet() | 584 | LLTexLayerSet::~LLTexLayerSet() |
729 | { | 585 | { |
586 | deleteCaches(); | ||
730 | std::for_each(mLayerList.begin(), mLayerList.end(), DeletePointer()); | 587 | std::for_each(mLayerList.begin(), mLayerList.end(), DeletePointer()); |
588 | std::for_each(mMaskLayerList.begin(), mMaskLayerList.end(), DeletePointer()); | ||
731 | delete mComposite; | 589 | delete mComposite; |
590 | mComposite = NULL; | ||
732 | } | 591 | } |
733 | 592 | ||
734 | //----------------------------------------------------------------------------- | 593 | //----------------------------------------------------------------------------- |
@@ -751,7 +610,14 @@ BOOL LLTexLayerSet::setInfo(LLTexLayerSetInfo *info) | |||
751 | mInfo = NULL; | 610 | mInfo = NULL; |
752 | return FALSE; | 611 | return FALSE; |
753 | } | 612 | } |
754 | mLayerList.push_back( layer ); | 613 | if (!layer->isVisibilityMask()) |
614 | { | ||
615 | mLayerList.push_back(layer); | ||
616 | } | ||
617 | else | ||
618 | { | ||
619 | mMaskLayerList.push_back(layer); | ||
620 | } | ||
755 | } | 621 | } |
756 | 622 | ||
757 | requestUpdate(); | 623 | requestUpdate(); |
@@ -791,6 +657,11 @@ void LLTexLayerSet::deleteCaches() | |||
791 | LLTexLayer* layer = *iter; | 657 | LLTexLayer* layer = *iter; |
792 | layer->deleteCaches(); | 658 | layer->deleteCaches(); |
793 | } | 659 | } |
660 | for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++) | ||
661 | { | ||
662 | LLTexLayer* layer = *iter; | ||
663 | layer->deleteCaches(); | ||
664 | } | ||
794 | } | 665 | } |
795 | 666 | ||
796 | // Returns TRUE if at least one packet of data has been received for each of the textures that this layerset depends on. | 667 | // Returns TRUE if at least one packet of data has been received for each of the textures that this layerset depends on. |
@@ -807,103 +678,130 @@ BOOL LLTexLayerSet::isLocalTextureDataFinal() | |||
807 | } | 678 | } |
808 | 679 | ||
809 | 680 | ||
810 | BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) | 681 | void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear) |
811 | { | 682 | { |
812 | BOOL success = TRUE; | 683 | const LLTexLayerSetInfo *info = getInfo(); |
813 | 684 | ||
814 | LLGLSUIDefault gls_ui; | 685 | gGL.setColorMask(false, true); |
815 | LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE); | 686 | gGL.setSceneBlendType(LLRender::BT_REPLACE); |
816 | gGL.setColorMask(true, true); | ||
817 | |||
818 | // composite color layers | ||
819 | for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) | ||
820 | { | ||
821 | LLTexLayer* layer = *iter; | ||
822 | if( layer->getRenderPass() == RP_COLOR ) | ||
823 | { | ||
824 | gGL.flush(); | ||
825 | success &= layer->render( x, y, width, height ); | ||
826 | gGL.flush(); | ||
827 | } | ||
828 | } | ||
829 | 687 | ||
830 | // (Optionally) replace alpha with a single component image from a tga file. | 688 | // (Optionally) replace alpha with a single component image from a tga file. |
831 | if( !getInfo()->mStaticAlphaFileName.empty() ) | 689 | if (!info->mStaticAlphaFileName.empty()) |
832 | { | 690 | { |
833 | LLGLSNoAlphaTest gls_no_alpha_test; | 691 | LLGLSNoAlphaTest gls_no_alpha_test; |
834 | gGL.flush(); | 692 | gGL.flush(); |
835 | gGL.setColorMask(false, true); | ||
836 | gGL.setSceneBlendType(LLRender::BT_REPLACE); | ||
837 | |||
838 | { | 693 | { |
839 | LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticAlphaFileName, TRUE ); | 694 | LLImageGL* image_gl = gTexStaticImageList.getImageGL(info->mStaticAlphaFileName, TRUE); |
840 | if( image_gl ) | 695 | if (image_gl) |
841 | { | 696 | { |
842 | LLGLSUIDefault gls_ui; | 697 | LLGLSUIDefault gls_ui; |
843 | gGL.getTexUnit(0)->bind(image_gl, TRUE); | 698 | gGL.getTexUnit(0)->bind(image_gl); |
844 | gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE ); | 699 | gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_REPLACE); |
845 | gl_rect_2d_simple_tex( width, height ); | 700 | gl_rect_2d_simple_tex(width, height); |
846 | } | ||
847 | else | ||
848 | { | ||
849 | success = FALSE; | ||
850 | } | 701 | } |
851 | } | 702 | } |
852 | gGL.flush(); | 703 | gGL.flush(); |
853 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | ||
854 | |||
855 | gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); | ||
856 | gGL.setColorMask(true, true); | ||
857 | gGL.setSceneBlendType(LLRender::BT_ALPHA); | ||
858 | } | 704 | } |
859 | else | 705 | else if (forceClear || info->mClearAlpha || (mMaskLayerList.size() > 0)) |
860 | if( getInfo()->mClearAlpha ) | ||
861 | { | 706 | { |
862 | // Set the alpha channel to one (clean up after previous blending) | 707 | // Set the alpha channel to one (clean up after previous blending) |
708 | gGL.flush(); | ||
863 | LLGLDisable no_alpha(GL_ALPHA_TEST); | 709 | LLGLDisable no_alpha(GL_ALPHA_TEST); |
864 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | 710 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); |
865 | gGL.color4f( 0.f, 0.f, 0.f, 1.f ); | 711 | gGL.color4f( 0.f, 0.f, 0.f, 1.f ); |
866 | gGL.flush(); | ||
867 | gGL.setColorMask(false, true); | ||
868 | 712 | ||
869 | gl_rect_2d_simple( width, height ); | 713 | gl_rect_2d_simple( width, height ); |
870 | 714 | ||
871 | gGL.flush(); | 715 | gGL.flush(); |
872 | gGL.setColorMask(true, true); | ||
873 | } | 716 | } |
874 | stop_glerror(); | ||
875 | 717 | ||
876 | return success; | 718 | // (Optional) Mask out part of the baked texture with alpha masks |
719 | // will still have an effect even if mClearAlpha is set or the alpha component was replaced | ||
720 | if (mMaskLayerList.size() > 0) | ||
721 | { | ||
722 | gGL.setSceneBlendType(LLRender::BT_MULT_ALPHA); | ||
723 | gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_REPLACE); | ||
724 | for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++) | ||
725 | { | ||
726 | LLTexLayer* layer = *iter; | ||
727 | gGL.flush(); | ||
728 | layer->blendAlphaTexture(x, y, width, height); | ||
729 | gGL.flush(); | ||
730 | } | ||
731 | } | ||
732 | |||
733 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | ||
734 | |||
735 | gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); | ||
736 | gGL.setColorMask(true, true); | ||
737 | gGL.setSceneBlendType(LLRender::BT_ALPHA); | ||
877 | } | 738 | } |
878 | 739 | ||
879 | BOOL LLTexLayerSet::renderBump( S32 x, S32 y, S32 width, S32 height ) | 740 | BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) |
880 | { | 741 | { |
881 | BOOL success = TRUE; | 742 | BOOL success = TRUE; |
743 | mIsVisible = TRUE; | ||
744 | |||
745 | if (mMaskLayerList.size() > 0) | ||
746 | { | ||
747 | for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++) | ||
748 | { | ||
749 | LLTexLayer* layer = *iter; | ||
750 | if (layer->isInvisibleAlphaMask()) | ||
751 | { | ||
752 | mIsVisible = FALSE; | ||
753 | } | ||
754 | } | ||
755 | } | ||
882 | 756 | ||
883 | LLGLSUIDefault gls_ui; | 757 | LLGLSUIDefault gls_ui; |
884 | LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE); | 758 | LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE); |
759 | gGL.setColorMask(true, true); | ||
885 | 760 | ||
886 | //static S32 bump_layer_count = 1; | 761 | // clear buffer area to ensure we don't pick up UI elements |
762 | { | ||
763 | gGL.flush(); | ||
764 | LLGLDisable no_alpha(GL_ALPHA_TEST); | ||
765 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | ||
766 | gGL.color4f( 0.f, 0.f, 0.f, 1.f ); | ||
887 | 767 | ||
888 | for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) | 768 | gl_rect_2d_simple( width, height ); |
769 | |||
770 | gGL.flush(); | ||
771 | } | ||
772 | |||
773 | if (mIsVisible) | ||
889 | { | 774 | { |
890 | LLTexLayer* layer = *iter; | 775 | // composite color layers |
891 | if( layer->getRenderPass() == RP_BUMP ) | 776 | for (layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++) |
892 | { | 777 | { |
893 | success &= layer->render( x, y, width, height ); | 778 | LLTexLayer* layer = *iter; |
779 | if (layer->getRenderPass() == RP_COLOR || layer->getRenderPass() == RP_BUMP) | ||
780 | { | ||
781 | gGL.flush(); | ||
782 | success &= layer->render(x, y, width, height); | ||
783 | gGL.flush(); | ||
784 | } | ||
894 | } | 785 | } |
786 | |||
787 | renderAlphaMaskTextures(x, y, width, height, false); | ||
788 | |||
789 | stop_glerror(); | ||
895 | } | 790 | } |
791 | else | ||
792 | { | ||
793 | gGL.flush(); | ||
896 | 794 | ||
897 | // Set the alpha channel to one (clean up after previous blending) | 795 | gGL.setSceneBlendType(LLRender::BT_REPLACE); |
898 | LLGLDisable no_alpha(GL_ALPHA_TEST); | 796 | LLGLDisable no_alpha(GL_ALPHA_TEST); |
899 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | 797 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); |
900 | gGL.color4f( 0.f, 0.f, 0.f, 1.f ); | 798 | gGL.color4f( 0.f, 0.f, 0.f, 0.f ); |
901 | gGL.setColorMask(false, true); | ||
902 | 799 | ||
903 | gl_rect_2d_simple( width, height ); | 800 | gl_rect_2d_simple( width, height ); |
904 | 801 | gGL.setSceneBlendType(LLRender::BT_ALPHA); | |
905 | gGL.setColorMask(true, true); | 802 | |
906 | stop_glerror(); | 803 | gGL.flush(); |
804 | } | ||
907 | 805 | ||
908 | return success; | 806 | return success; |
909 | } | 807 | } |
@@ -943,7 +841,7 @@ void LLTexLayerSet::createComposite() | |||
943 | width /= 2; | 841 | width /= 2; |
944 | height /= 2; | 842 | height /= 2; |
945 | } | 843 | } |
946 | mComposite = new LLTexLayerSetBuffer( this, width, height, mHasBump ); | 844 | mComposite = new LLTexLayerSetBuffer(this, width, height); |
947 | } | 845 | } |
948 | } | 846 | } |
949 | 847 | ||
@@ -1004,6 +902,9 @@ void LLTexLayerSet::gatherAlphaMasks(U8 *data, S32 width, S32 height) | |||
1004 | } | 902 | } |
1005 | } | 903 | } |
1006 | } | 904 | } |
905 | |||
906 | // Set alpha back to that of our alpha masks. | ||
907 | renderAlphaMaskTextures(mComposite->getOriginX(), mComposite->getOriginY(), width, height, true); | ||
1007 | } | 908 | } |
1008 | 909 | ||
1009 | void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components) | 910 | void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components) |
@@ -1025,7 +926,8 @@ LLTexLayerInfo::LLTexLayerInfo( ) | |||
1025 | mFixedColor( 0.f, 0.f, 0.f, 0.f ), | 926 | mFixedColor( 0.f, 0.f, 0.f, 0.f ), |
1026 | mLocalTexture( -1 ), | 927 | mLocalTexture( -1 ), |
1027 | mStaticImageIsMask( FALSE ), | 928 | mStaticImageIsMask( FALSE ), |
1028 | mUseLocalTextureAlphaOnly( FALSE ) | 929 | mUseLocalTextureAlphaOnly(FALSE), |
930 | mIsVisibilityMask(FALSE) | ||
1029 | { | 931 | { |
1030 | } | 932 | } |
1031 | 933 | ||
@@ -1064,6 +966,14 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node) | |||
1064 | static LLStdStringHandle global_color_string = LLXmlTree::addAttributeString("global_color"); | 966 | static LLStdStringHandle global_color_string = LLXmlTree::addAttributeString("global_color"); |
1065 | node->getFastAttributeString( global_color_string, mGlobalColor ); | 967 | node->getFastAttributeString( global_color_string, mGlobalColor ); |
1066 | 968 | ||
969 | // Visibility mask (optional) | ||
970 | BOOL is_visibility; | ||
971 | static LLStdStringHandle visibility_mask_string = LLXmlTree::addAttributeString("visibility_mask"); | ||
972 | if (node->getFastAttributeBOOL(visibility_mask_string, is_visibility)) | ||
973 | { | ||
974 | mIsVisibilityMask = is_visibility; | ||
975 | } | ||
976 | |||
1067 | // color attribute (optional) | 977 | // color attribute (optional) |
1068 | LLColor4U color4u; | 978 | LLColor4U color4u; |
1069 | static LLStdStringHandle fixed_color_string = LLXmlTree::addAttributeString("fixed_color"); | 979 | static LLStdStringHandle fixed_color_string = LLXmlTree::addAttributeString("fixed_color"); |
@@ -1150,9 +1060,41 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node) | |||
1150 | { | 1060 | { |
1151 | mLocalTexture = TEX_HAIR; | 1061 | mLocalTexture = TEX_HAIR; |
1152 | } | 1062 | } |
1063 | else if ("hair_alpha" == local_texture) | ||
1064 | { | ||
1065 | mLocalTexture = TEX_HAIR_ALPHA; | ||
1066 | } | ||
1067 | else if ("head_alpha" == local_texture) | ||
1068 | { | ||
1069 | mLocalTexture = TEX_HEAD_ALPHA; | ||
1070 | } | ||
1071 | else if ("upper_alpha" == local_texture) | ||
1072 | { | ||
1073 | mLocalTexture = TEX_UPPER_ALPHA; | ||
1074 | } | ||
1075 | else if ("lower_alpha" == local_texture) | ||
1076 | { | ||
1077 | mLocalTexture = TEX_LOWER_ALPHA; | ||
1078 | } | ||
1079 | else if ("eyes_alpha" == local_texture) | ||
1080 | { | ||
1081 | mLocalTexture = TEX_EYES_ALPHA; | ||
1082 | } | ||
1083 | else if ("head_tattoo" == local_texture) | ||
1084 | { | ||
1085 | mLocalTexture = TEX_HEAD_TATTOO; | ||
1086 | } | ||
1087 | else if ("upper_tattoo" == local_texture) | ||
1088 | { | ||
1089 | mLocalTexture = TEX_UPPER_TATTOO; | ||
1090 | } | ||
1091 | else if ("lower_tattoo" == local_texture) | ||
1092 | { | ||
1093 | mLocalTexture = TEX_LOWER_TATTOO; | ||
1094 | } | ||
1153 | else | 1095 | else |
1154 | { | 1096 | { |
1155 | llwarns << "<texture> element has invalid local_texure attribute: " << mName << " " << local_texture << llendl; | 1097 | llwarns << "<texture> element has invalid local_texture attribute: " << mName << " " << local_texture << llendl; |
1156 | return FALSE; | 1098 | return FALSE; |
1157 | } | 1099 | } |
1158 | } | 1100 | } |
@@ -1253,13 +1195,14 @@ LLTexLayer::~LLTexLayer() | |||
1253 | 1195 | ||
1254 | BOOL LLTexLayer::setInfo(LLTexLayerInfo* info) | 1196 | BOOL LLTexLayer::setInfo(LLTexLayerInfo* info) |
1255 | { | 1197 | { |
1256 | llassert(mInfo == NULL); | 1198 | //llassert(mInfo == NULL); // nyx says this is probably bogus but needs investigating |
1199 | if (mInfo != NULL) // above llassert(), but softened into a warning | ||
1200 | { | ||
1201 | llwarns << "BAD STUFF! mInfo != NULL" << llendl; | ||
1202 | } | ||
1257 | mInfo = info; | 1203 | mInfo = info; |
1258 | //mID = info->mID; // No ID | 1204 | //mID = info->mID; // No ID |
1259 | 1205 | ||
1260 | if (info->mRenderPass == RP_BUMP) | ||
1261 | mTexLayerSet->setBump(TRUE); | ||
1262 | |||
1263 | { | 1206 | { |
1264 | LLTexLayerInfo::morph_name_list_t::iterator iter; | 1207 | LLTexLayerInfo::morph_name_list_t::iterator iter; |
1265 | for (iter = mInfo->mMorphNameList.begin(); iter != mInfo->mMorphNameList.end(); iter++) | 1208 | for (iter = mInfo->mMorphNameList.begin(); iter != mInfo->mMorphNameList.end(); iter++) |
@@ -1351,13 +1294,8 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) | |||
1351 | LLGLEnable color_mat(GL_COLOR_MATERIAL); | 1294 | LLGLEnable color_mat(GL_COLOR_MATERIAL); |
1352 | gPipeline.disableLights(); | 1295 | gPipeline.disableLights(); |
1353 | 1296 | ||
1354 | BOOL success = TRUE; | ||
1355 | |||
1356 | BOOL color_specified = FALSE; | ||
1357 | BOOL alpha_mask_specified = FALSE; | ||
1358 | |||
1359 | LLColor4 net_color; | 1297 | LLColor4 net_color; |
1360 | color_specified = findNetColor( &net_color ); | 1298 | BOOL color_specified = findNetColor(&net_color); |
1361 | 1299 | ||
1362 | if (mTexLayerSet->getAvatar()->mIsDummy) | 1300 | if (mTexLayerSet->getAvatar()->mIsDummy) |
1363 | { | 1301 | { |
@@ -1365,18 +1303,21 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) | |||
1365 | net_color = LLVOAvatar::getDummyColor(); | 1303 | net_color = LLVOAvatar::getDummyColor(); |
1366 | } | 1304 | } |
1367 | 1305 | ||
1306 | BOOL success = TRUE; | ||
1307 | |||
1368 | // If you can't see the layer, don't render it. | 1308 | // If you can't see the layer, don't render it. |
1369 | if( is_approx_zero( net_color.mV[VW] ) ) | 1309 | if( is_approx_zero( net_color.mV[VW] ) ) |
1370 | { | 1310 | { |
1371 | return success; | 1311 | return success; |
1372 | } | 1312 | } |
1373 | 1313 | ||
1314 | BOOL alpha_mask_specified = FALSE; | ||
1374 | alpha_list_t::iterator iter = mParamAlphaList.begin(); | 1315 | alpha_list_t::iterator iter = mParamAlphaList.begin(); |
1375 | if( iter != mParamAlphaList.end() ) | 1316 | if( iter != mParamAlphaList.end() ) |
1376 | { | 1317 | { |
1377 | // If we have alpha masks, but we're skipping all of them, skip the whole layer. | 1318 | // If we have alpha masks, but we're skipping all of them, skip the whole layer. |
1378 | // However, we can't do this optimization if we have morph masks that need updating. | 1319 | // However, we can't do this optimization if we have morph masks that need updating. |
1379 | if( mMaskedMorphs.empty() ) | 1320 | /* if( mMaskedMorphs.empty() ) |
1380 | { | 1321 | { |
1381 | BOOL skip_layer = TRUE; | 1322 | BOOL skip_layer = TRUE; |
1382 | 1323 | ||
@@ -1397,7 +1338,7 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) | |||
1397 | { | 1338 | { |
1398 | return success; | 1339 | return success; |
1399 | } | 1340 | } |
1400 | } | 1341 | }*/ |
1401 | 1342 | ||
1402 | renderAlphaMasks( x, y, width, height, &net_color ); | 1343 | renderAlphaMasks( x, y, width, height, &net_color ); |
1403 | alpha_mask_specified = TRUE; | 1344 | alpha_mask_specified = TRUE; |
@@ -1412,6 +1353,11 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) | |||
1412 | gGL.flush(); | 1353 | gGL.flush(); |
1413 | gGL.setSceneBlendType(LLRender::BT_REPLACE); | 1354 | gGL.setSceneBlendType(LLRender::BT_REPLACE); |
1414 | } | 1355 | } |
1356 | else if (getInfo()->mUseLocalTextureAlphaOnly) | ||
1357 | { | ||
1358 | // Use the alpha channel only | ||
1359 | gGL.setColorMask(false, true); | ||
1360 | } | ||
1415 | 1361 | ||
1416 | if( (getInfo()->mLocalTexture != -1) && !getInfo()->mUseLocalTextureAlphaOnly ) | 1362 | if( (getInfo()->mLocalTexture != -1) && !getInfo()->mUseLocalTextureAlphaOnly ) |
1417 | { | 1363 | { |
@@ -1419,13 +1365,17 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) | |||
1419 | LLImageGL* image_gl = NULL; | 1365 | LLImageGL* image_gl = NULL; |
1420 | if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) ) | 1366 | if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) ) |
1421 | { | 1367 | { |
1368 | if (mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture) == IMG_DEFAULT_AVATAR) | ||
1369 | { | ||
1370 | image_gl = NULL; | ||
1371 | } | ||
1422 | if( image_gl ) | 1372 | if( image_gl ) |
1423 | { | 1373 | { |
1424 | LLGLDisable alpha_test(getInfo()->mWriteAllChannels ? GL_ALPHA_TEST : 0); | 1374 | LLGLDisable alpha_test(getInfo()->mWriteAllChannels ? GL_ALPHA_TEST : 0); |
1425 | 1375 | ||
1426 | LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode(); | 1376 | LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode(); |
1427 | 1377 | ||
1428 | gGL.getTexUnit(0)->bind(image_gl, TRUE); | 1378 | gGL.getTexUnit(0)->bind(image_gl); |
1429 | gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); | 1379 | gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); |
1430 | 1380 | ||
1431 | gl_rect_2d_simple_tex( width, height ); | 1381 | gl_rect_2d_simple_tex( width, height ); |
@@ -1434,10 +1384,6 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) | |||
1434 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | 1384 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); |
1435 | } | 1385 | } |
1436 | } | 1386 | } |
1437 | else | ||
1438 | { | ||
1439 | success = FALSE; | ||
1440 | } | ||
1441 | } | 1387 | } |
1442 | } | 1388 | } |
1443 | 1389 | ||
@@ -1447,7 +1393,7 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) | |||
1447 | LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask ); | 1393 | LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask ); |
1448 | if( image_gl ) | 1394 | if( image_gl ) |
1449 | { | 1395 | { |
1450 | gGL.getTexUnit(0)->bind(image_gl, TRUE); | 1396 | gGL.getTexUnit(0)->bind(image_gl); |
1451 | gl_rect_2d_simple_tex( width, height ); | 1397 | gl_rect_2d_simple_tex( width, height ); |
1452 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | 1398 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); |
1453 | } | 1399 | } |
@@ -1477,6 +1423,12 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) | |||
1477 | stop_glerror(); | 1423 | stop_glerror(); |
1478 | } | 1424 | } |
1479 | 1425 | ||
1426 | if (getInfo()->mUseLocalTextureAlphaOnly) | ||
1427 | { | ||
1428 | // Restore color + alpha mode. | ||
1429 | gGL.setColorMask(true, true); | ||
1430 | } | ||
1431 | |||
1480 | if( !success ) | 1432 | if( !success ) |
1481 | { | 1433 | { |
1482 | llinfos << "LLTexLayer::render() partial: " << getInfo()->mName << llendl; | 1434 | llinfos << "LLTexLayer::render() partial: " << getInfo()->mName << llendl; |
@@ -1484,6 +1436,49 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) | |||
1484 | return success; | 1436 | return success; |
1485 | } | 1437 | } |
1486 | 1438 | ||
1439 | BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) | ||
1440 | { | ||
1441 | BOOL success = TRUE; | ||
1442 | |||
1443 | gGL.flush(); | ||
1444 | |||
1445 | if (!getInfo()->mStaticImageFileName.empty()) | ||
1446 | { | ||
1447 | LLImageGL* image_gl = gTexStaticImageList.getImageGL(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); | ||
1448 | if (image_gl) | ||
1449 | { | ||
1450 | LLGLSNoAlphaTest gls_no_alpha_test; | ||
1451 | gGL.getTexUnit(0)->bind(image_gl, TRUE); | ||
1452 | gl_rect_2d_simple_tex(width, height); | ||
1453 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | ||
1454 | } | ||
1455 | else | ||
1456 | { | ||
1457 | success = FALSE; | ||
1458 | } | ||
1459 | } | ||
1460 | else | ||
1461 | { | ||
1462 | if (getInfo()->mLocalTexture >=0 && getInfo()->mLocalTexture < TEX_NUM_INDICES) | ||
1463 | { | ||
1464 | LLImageGL* image_gl = NULL; | ||
1465 | if (mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl)) | ||
1466 | { | ||
1467 | if (image_gl) | ||
1468 | { | ||
1469 | LLGLSNoAlphaTest gls_no_alpha_test; | ||
1470 | gGL.getTexUnit(0)->bind(image_gl); | ||
1471 | gl_rect_2d_simple_tex(width, height); | ||
1472 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | ||
1473 | success = TRUE; | ||
1474 | } | ||
1475 | } | ||
1476 | } | ||
1477 | } | ||
1478 | |||
1479 | return success; | ||
1480 | } | ||
1481 | |||
1487 | U8* LLTexLayer::getAlphaData() | 1482 | U8* LLTexLayer::getAlphaData() |
1488 | { | 1483 | { |
1489 | LLCRC alpha_mask_crc; | 1484 | LLCRC alpha_mask_crc; |
@@ -1609,7 +1604,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4 | |||
1609 | 1604 | ||
1610 | // Approximates a min() function | 1605 | // Approximates a min() function |
1611 | gGL.flush(); | 1606 | gGL.flush(); |
1612 | gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO); | 1607 | gGL.setSceneBlendType(LLRender::BT_MULT_ALPHA); |
1613 | 1608 | ||
1614 | // Accumulate the alpha component of the texture | 1609 | // Accumulate the alpha component of the texture |
1615 | if( getInfo()->mLocalTexture != -1 ) | 1610 | if( getInfo()->mLocalTexture != -1 ) |
@@ -1624,7 +1619,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4 | |||
1624 | 1619 | ||
1625 | LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode(); | 1620 | LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode(); |
1626 | 1621 | ||
1627 | gGL.getTexUnit(0)->bind(image_gl, TRUE); | 1622 | gGL.getTexUnit(0)->bind(image_gl); |
1628 | gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); | 1623 | gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); |
1629 | 1624 | ||
1630 | gl_rect_2d_simple_tex( width, height ); | 1625 | gl_rect_2d_simple_tex( width, height ); |
@@ -1633,10 +1628,6 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4 | |||
1633 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | 1628 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); |
1634 | } | 1629 | } |
1635 | } | 1630 | } |
1636 | else | ||
1637 | { | ||
1638 | success = FALSE; | ||
1639 | } | ||
1640 | } | 1631 | } |
1641 | } | 1632 | } |
1642 | 1633 | ||
@@ -1650,15 +1641,11 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4 | |||
1650 | ( (image_gl->getComponents() == 1) && getInfo()->mStaticImageIsMask ) ) | 1641 | ( (image_gl->getComponents() == 1) && getInfo()->mStaticImageIsMask ) ) |
1651 | { | 1642 | { |
1652 | LLGLSNoAlphaTest gls_no_alpha_test; | 1643 | LLGLSNoAlphaTest gls_no_alpha_test; |
1653 | gGL.getTexUnit(0)->bind(image_gl, TRUE); | 1644 | gGL.getTexUnit(0)->bind(image_gl); |
1654 | gl_rect_2d_simple_tex( width, height ); | 1645 | gl_rect_2d_simple_tex( width, height ); |
1655 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | 1646 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); |
1656 | } | 1647 | } |
1657 | } | 1648 | } |
1658 | else | ||
1659 | { | ||
1660 | success = FALSE; | ||
1661 | } | ||
1662 | } | 1649 | } |
1663 | } | 1650 | } |
1664 | 1651 | ||
@@ -1677,7 +1664,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4 | |||
1677 | 1664 | ||
1678 | gGL.setColorMask(true, true); | 1665 | gGL.setColorMask(true, true); |
1679 | 1666 | ||
1680 | if (!mMorphMasksValid && !mMaskedMorphs.empty()) | 1667 | if (success && !mMorphMasksValid && !mMaskedMorphs.empty()) |
1681 | { | 1668 | { |
1682 | LLCRC alpha_mask_crc; | 1669 | LLCRC alpha_mask_crc; |
1683 | const LLUUID& uuid = mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture); | 1670 | const LLUUID& uuid = mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture); |
@@ -1825,6 +1812,26 @@ void LLTexLayer::invalidateMorphMasks() | |||
1825 | mMorphMasksValid = FALSE; | 1812 | mMorphMasksValid = FALSE; |
1826 | } | 1813 | } |
1827 | 1814 | ||
1815 | BOOL LLTexLayer::isVisibilityMask() const | ||
1816 | { | ||
1817 | return mInfo->mIsVisibilityMask; | ||
1818 | } | ||
1819 | |||
1820 | BOOL LLTexLayer::isInvisibleAlphaMask() | ||
1821 | { | ||
1822 | const LLTexLayerInfo *info = getInfo(); | ||
1823 | |||
1824 | if (info && info->mLocalTexture >= 0 && info->mLocalTexture < TEX_NUM_INDICES) | ||
1825 | { | ||
1826 | if (mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)info->mLocalTexture) == IMG_INVISIBLE) | ||
1827 | { | ||
1828 | return TRUE; | ||
1829 | } | ||
1830 | } | ||
1831 | |||
1832 | return FALSE; | ||
1833 | } | ||
1834 | |||
1828 | //----------------------------------------------------------------------------- | 1835 | //----------------------------------------------------------------------------- |
1829 | // LLTexLayerParamAlphaInfo | 1836 | // LLTexLayerParamAlphaInfo |
1830 | //----------------------------------------------------------------------------- | 1837 | //----------------------------------------------------------------------------- |
@@ -2095,14 +2102,14 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height ) | |||
2095 | // Create the GL texture, and then hang onto it for future use. | 2102 | // Create the GL texture, and then hang onto it for future use. |
2096 | if( mNeedsCreateTexture ) | 2103 | if( mNeedsCreateTexture ) |
2097 | { | 2104 | { |
2098 | mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw, 0, TRUE, LLViewerImageBoostLevel::TEXLAYER_CACHE); | 2105 | mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw); |
2099 | mNeedsCreateTexture = FALSE; | 2106 | mNeedsCreateTexture = FALSE; |
2100 | gGL.getTexUnit(0)->bind(mCachedProcessedImageGL); | 2107 | gGL.getTexUnit(0)->bind(mCachedProcessedImageGL); |
2101 | mCachedProcessedImageGL->setAddressMode(LLTexUnit::TAM_CLAMP); | 2108 | mCachedProcessedImageGL->setAddressMode(LLTexUnit::TAM_CLAMP); |
2102 | } | 2109 | } |
2103 | 2110 | ||
2104 | LLGLSNoAlphaTest gls_no_alpha_test; | 2111 | LLGLSNoAlphaTest gls_no_alpha_test; |
2105 | gGL.getTexUnit(0)->bind(mCachedProcessedImageGL, TRUE); | 2112 | gGL.getTexUnit(0)->bind(mCachedProcessedImageGL); |
2106 | gl_rect_2d_simple_tex( width, height ); | 2113 | gl_rect_2d_simple_tex( width, height ); |
2107 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | 2114 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); |
2108 | stop_glerror(); | 2115 | stop_glerror(); |
@@ -2550,7 +2557,7 @@ LLImageGL* LLTexStaticImageList::getImageGL(const std::string& file_name, BOOL i | |||
2550 | // that once an image is a mask it's always a mask. | 2557 | // that once an image is a mask it's always a mask. |
2551 | image_gl->setExplicitFormat( GL_ALPHA8, GL_ALPHA ); | 2558 | image_gl->setExplicitFormat( GL_ALPHA8, GL_ALPHA ); |
2552 | } | 2559 | } |
2553 | image_gl->createGLTexture(0, image_raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); | 2560 | image_gl->createGLTexture(0, image_raw); |
2554 | 2561 | ||
2555 | gGL.getTexUnit(0)->bind(image_gl); | 2562 | gGL.getTexUnit(0)->bind(image_gl); |
2556 | image_gl->setAddressMode(LLTexUnit::TAM_CLAMP); | 2563 | image_gl->setAddressMode(LLTexUnit::TAM_CLAMP); |
diff --git a/linden/indra/newview/lltexlayer.h b/linden/indra/newview/lltexlayer.h index 1924d0b..020ba86 100644 --- a/linden/indra/newview/lltexlayer.h +++ b/linden/indra/newview/lltexlayer.h | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "lluuid.h" | 41 | #include "lluuid.h" |
42 | #include "llviewerimage.h" | 42 | #include "llviewerimage.h" |
43 | #include "llviewervisualparam.h" | 43 | #include "llviewervisualparam.h" |
44 | #include "llvoavatardefines.h" | ||
44 | #include "llwearable.h" | 45 | #include "llwearable.h" |
45 | #include "v4color.h" | 46 | #include "v4color.h" |
46 | #include "llfloater.h" | 47 | #include "llfloater.h" |
@@ -186,6 +187,7 @@ protected: | |||
186 | std::string mStaticImageFileName; | 187 | std::string mStaticImageFileName; |
187 | BOOL mStaticImageIsMask; | 188 | BOOL mStaticImageIsMask; |
188 | BOOL mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture. Use alpha as a mask | 189 | BOOL mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture. Use alpha as a mask |
190 | BOOL mIsVisibilityMask; | ||
189 | 191 | ||
190 | typedef std::vector<std::pair<std::string,BOOL> > morph_name_list_t; | 192 | typedef std::vector<std::pair<std::string,BOOL> > morph_name_list_t; |
191 | morph_name_list_t mMorphNameList; | 193 | morph_name_list_t mMorphNameList; |
@@ -205,14 +207,13 @@ protected: | |||
205 | class LLTexLayerSetBuffer : public LLDynamicTexture | 207 | class LLTexLayerSetBuffer : public LLDynamicTexture |
206 | { | 208 | { |
207 | public: | 209 | public: |
208 | LLTexLayerSetBuffer( LLTexLayerSet* owner, S32 width, S32 height, BOOL has_bump ); | 210 | LLTexLayerSetBuffer(LLTexLayerSet* owner, S32 width, S32 height); |
209 | virtual ~LLTexLayerSetBuffer(); | 211 | virtual ~LLTexLayerSetBuffer(); |
210 | 212 | ||
211 | virtual void preRender(BOOL clear_depth); | 213 | virtual void preRender(BOOL clear_depth); |
212 | virtual void postRender(BOOL success); | 214 | virtual void postRender(BOOL success); |
213 | virtual BOOL render(); | 215 | virtual BOOL render(); |
214 | BOOL updateImmediate(); | 216 | BOOL updateImmediate(); |
215 | void bindBumpTexture( U32 stage ); | ||
216 | bool isInitialized(void) const; | 217 | bool isInitialized(void) const; |
217 | BOOL needsRender(); | 218 | BOOL needsRender(); |
218 | void requestUpdate(); | 219 | void requestUpdate(); |
@@ -220,8 +221,7 @@ public: | |||
220 | void cancelUpload(); | 221 | void cancelUpload(); |
221 | BOOL uploadPending() { return mUploadPending; } | 222 | BOOL uploadPending() { return mUploadPending; } |
222 | BOOL render( S32 x, S32 y, S32 width, S32 height ); | 223 | BOOL render( S32 x, S32 y, S32 width, S32 height ); |
223 | void readBackAndUpload(U8* baked_bump_data); | 224 | void readBackAndUpload(); |
224 | void createBumpTexture() ; | ||
225 | 225 | ||
226 | static void onTextureUploadComplete( const LLUUID& uuid, | 226 | static void onTextureUploadComplete( const LLUUID& uuid, |
227 | void* userdata, | 227 | void* userdata, |
@@ -236,16 +236,13 @@ private: | |||
236 | void popProjection(); | 236 | void popProjection(); |
237 | 237 | ||
238 | private: | 238 | private: |
239 | BOOL mHasBump ; | ||
240 | BOOL mNeedsUpdate; | 239 | BOOL mNeedsUpdate; |
241 | BOOL mNeedsUpload; | 240 | BOOL mNeedsUpload; |
242 | BOOL mUploadPending; | 241 | BOOL mUploadPending; |
243 | LLUUID mUploadID; // Identifys the current upload process (null if none). Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit) | 242 | LLUUID mUploadID; // Identifys the current upload process (null if none). Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit) |
244 | LLTexLayerSet* mTexLayerSet; | 243 | LLTexLayerSet* mTexLayerSet; |
245 | LLPointer<LLImageGL> mBumpTex; // zero if none | ||
246 | 244 | ||
247 | static S32 sGLByteCount; | 245 | static S32 sGLByteCount; |
248 | static S32 sGLBumpByteCount; | ||
249 | }; | 246 | }; |
250 | 247 | ||
251 | //----------------------------------------------------------------------------- | 248 | //----------------------------------------------------------------------------- |
@@ -254,6 +251,7 @@ private: | |||
254 | //----------------------------------------------------------------------------- | 251 | //----------------------------------------------------------------------------- |
255 | class LLTexLayerSet | 252 | class LLTexLayerSet |
256 | { | 253 | { |
254 | friend class LLTexLayerSetBuffer; | ||
257 | public: | 255 | public: |
258 | LLTexLayerSet( LLVOAvatar* avatar ); | 256 | LLTexLayerSet( LLVOAvatar* avatar ); |
259 | ~LLTexLayerSet(); | 257 | ~LLTexLayerSet(); |
@@ -264,7 +262,7 @@ public: | |||
264 | BOOL setInfo(LLTexLayerSetInfo *info); | 262 | BOOL setInfo(LLTexLayerSetInfo *info); |
265 | 263 | ||
266 | BOOL render( S32 x, S32 y, S32 width, S32 height ); | 264 | BOOL render( S32 x, S32 y, S32 width, S32 height ); |
267 | BOOL renderBump( S32 x, S32 y, S32 width,S32 height ); | 265 | void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false); |
268 | BOOL isBodyRegion( const std::string& region ) { return mInfo->mBodyRegion == region; } | 266 | BOOL isBodyRegion( const std::string& region ) { return mInfo->mBodyRegion == region; } |
269 | LLTexLayerSetBuffer* getComposite(); | 267 | LLTexLayerSetBuffer* getComposite(); |
270 | void requestUpdate(); | 268 | void requestUpdate(); |
@@ -283,8 +281,9 @@ public: | |||
283 | void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components); | 281 | void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components); |
284 | const std::string getBodyRegion() { return mInfo->mBodyRegion; } | 282 | const std::string getBodyRegion() { return mInfo->mBodyRegion; } |
285 | BOOL hasComposite() { return (mComposite != NULL); } | 283 | BOOL hasComposite() { return (mComposite != NULL); } |
286 | void setBump( BOOL b ) { mHasBump = b; } | 284 | LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; } |
287 | BOOL hasBump() { return mHasBump; } | 285 | void setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; } |
286 | BOOL isVisible() const { return mIsVisible; } | ||
288 | 287 | ||
289 | public: | 288 | public: |
290 | static BOOL sHasCaches; | 289 | static BOOL sHasCaches; |
@@ -292,11 +291,14 @@ public: | |||
292 | protected: | 291 | protected: |
293 | typedef std::vector<LLTexLayer *> layer_list_t; | 292 | typedef std::vector<LLTexLayer *> layer_list_t; |
294 | layer_list_t mLayerList; | 293 | layer_list_t mLayerList; |
294 | layer_list_t mMaskLayerList; | ||
295 | LLTexLayerSetBuffer* mComposite; | 295 | LLTexLayerSetBuffer* mComposite; |
296 | // Backlink only; don't make this an LLPointer. | 296 | // Backlink only; don't make this an LLPointer. |
297 | LLVOAvatar* mAvatar; | 297 | LLVOAvatar* mAvatar; |
298 | BOOL mUpdatesEnabled; | 298 | BOOL mUpdatesEnabled; |
299 | BOOL mHasBump; | 299 | BOOL mIsVisible; |
300 | |||
301 | LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex; | ||
300 | 302 | ||
301 | LLTexLayerSetInfo *mInfo; | 303 | LLTexLayerSetInfo *mInfo; |
302 | }; | 304 | }; |
@@ -348,6 +350,9 @@ public: | |||
348 | BOOL renderImageRaw( U8* in_data, S32 in_width, S32 in_height, S32 in_components, S32 width, S32 height, BOOL is_mask ); | 350 | BOOL renderImageRaw( U8* in_data, S32 in_width, S32 in_height, S32 in_components, S32 width, S32 height, BOOL is_mask ); |
349 | BOOL renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4* colorp ); | 351 | BOOL renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4* colorp ); |
350 | BOOL hasAlphaParams() { return (!mParamAlphaList.empty());} | 352 | BOOL hasAlphaParams() { return (!mParamAlphaList.empty());} |
353 | BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); | ||
354 | BOOL isVisibilityMask() const; | ||
355 | BOOL isInvisibleAlphaMask(); | ||
351 | 356 | ||
352 | protected: | 357 | protected: |
353 | LLTexLayerSet* mTexLayerSet; | 358 | LLTexLayerSet* mTexLayerSet; |
diff --git a/linden/indra/newview/lltexturectrl.cpp b/linden/indra/newview/lltexturectrl.cpp index f4476fb..635c2b0 100644 --- a/linden/indra/newview/lltexturectrl.cpp +++ b/linden/indra/newview/lltexturectrl.cpp | |||
@@ -1322,7 +1322,11 @@ void LLTextureCtrl::draw() | |||
1322 | mTexturep = gImageList.getImageFromFile(mFallbackImageName); | 1322 | mTexturep = gImageList.getImageFromFile(mFallbackImageName); |
1323 | mTexturep->setBoostLevel(LLViewerImageBoostLevel::BOOST_PREVIEW); | 1323 | mTexturep->setBoostLevel(LLViewerImageBoostLevel::BOOST_PREVIEW); |
1324 | } | 1324 | } |
1325 | 1325 | else // mImageAssetID == LLUUID::null | |
1326 | { | ||
1327 | mTexturep = NULL; | ||
1328 | } | ||
1329 | |||
1326 | // Border | 1330 | // Border |
1327 | LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL ); | 1331 | LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL ); |
1328 | gl_rect_2d( border, mBorderColor, FALSE ); | 1332 | gl_rect_2d( border, mBorderColor, FALSE ); |
diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index 5172072..f97fffd 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp | |||
@@ -8146,6 +8146,14 @@ class LLEditEnableTakeOff : public view_listener_t | |||
8146 | { | 8146 | { |
8147 | new_value = LLAgent::selfHasWearable((void *)WT_SKIRT); | 8147 | new_value = LLAgent::selfHasWearable((void *)WT_SKIRT); |
8148 | } | 8148 | } |
8149 | if (clothing == "alpha") | ||
8150 | { | ||
8151 | new_value = LLAgent::selfHasWearable((void *)WT_ALPHA); | ||
8152 | } | ||
8153 | if (clothing == "tattoo") | ||
8154 | { | ||
8155 | new_value = LLAgent::selfHasWearable((void *)WT_TATTOO); | ||
8156 | } | ||
8149 | 8157 | ||
8150 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | 8158 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) |
8151 | // Why aren't they using LLWearable::typeNameToType()? *confuzzled* | 8159 | // Why aren't they using LLWearable::typeNameToType()? *confuzzled* |
@@ -8201,6 +8209,14 @@ class LLEditTakeOff : public view_listener_t | |||
8201 | { | 8209 | { |
8202 | LLAgent::userRemoveWearable((void*)WT_SKIRT); | 8210 | LLAgent::userRemoveWearable((void*)WT_SKIRT); |
8203 | } | 8211 | } |
8212 | else if (clothing == "alpha") | ||
8213 | { | ||
8214 | LLAgent::userRemoveWearable((void*)WT_ALPHA); | ||
8215 | } | ||
8216 | else if (clothing == "tattoo") | ||
8217 | { | ||
8218 | LLAgent::userRemoveWearable((void*)WT_TATTOO); | ||
8219 | } | ||
8204 | else if (clothing == "all") | 8220 | else if (clothing == "all") |
8205 | { | 8221 | { |
8206 | LLAgent::userRemoveAllClothesConfirm(); | 8222 | LLAgent::userRemoveAllClothesConfirm(); |
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index bcc8472..7c867d2 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp | |||
@@ -767,6 +767,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, | |||
767 | mFullyLoadedInitialized(FALSE), | 767 | mFullyLoadedInitialized(FALSE), |
768 | mFullyLoaded(FALSE), | 768 | mFullyLoaded(FALSE), |
769 | mHasBakedHair( FALSE ), | 769 | mHasBakedHair( FALSE ), |
770 | mSupportsAlphaLayers(FALSE), | ||
770 | mFirstSetActualBoobGravRan( false ), | 771 | mFirstSetActualBoobGravRan( false ), |
771 | mFirstSetActualButtGravRan( false ), | 772 | mFirstSetActualButtGravRan( false ), |
772 | mFirstSetActualFatGravRan( false ) | 773 | mFirstSetActualFatGravRan( false ) |
@@ -4706,14 +4707,9 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) | |||
4706 | 4707 | ||
4707 | if (pass == AVATAR_RENDER_PASS_SINGLE) | 4708 | if (pass == AVATAR_RENDER_PASS_SINGLE) |
4708 | { | 4709 | { |
4709 | const bool should_alpha_mask = mHasBakedHair && isTextureDefined(TEX_HEAD_BAKED) && isTextureDefined(TEX_UPPER_BAKED) | 4710 | const bool should_alpha_mask = mSupportsAlphaLayers && mHasBakedHair |
4710 | && isTextureDefined(TEX_LOWER_BAKED) | 4711 | && !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked |
4711 | && mBakedTextureData[BAKED_HEAD].mIsLoaded | 4712 | && !LLDrawPoolAvatar::sSkipTransparent; |
4712 | && mBakedTextureData[BAKED_UPPER].mIsLoaded && mBakedTextureData[BAKED_LOWER].mIsLoaded | ||
4713 | && mBakedTextureData[BAKED_HEAD].mIsUsed | ||
4714 | && mBakedTextureData[BAKED_UPPER].mIsUsed && mBakedTextureData[BAKED_LOWER].mIsUsed | ||
4715 | && !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked | ||
4716 | && !(isSelf() && gAgent.cameraCustomizeAvatar()); // don't alpha mask if in customize mode | ||
4717 | 4713 | ||
4718 | LLGLState test(GL_ALPHA_TEST, should_alpha_mask); | 4714 | LLGLState test(GL_ALPHA_TEST, should_alpha_mask); |
4719 | 4715 | ||
@@ -4826,27 +4822,25 @@ U32 LLVOAvatar::renderRigid() | |||
4826 | return 0; | 4822 | return 0; |
4827 | } | 4823 | } |
4828 | 4824 | ||
4829 | if (isTextureVisible(TEX_EYES_BAKED) || mIsDummy) | 4825 | const bool should_alpha_mask = mSupportsAlphaLayers && mHasBakedHair |
4830 | { | 4826 | && !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked |
4831 | // If the meshes need to be drawn, enable alpha masking but not blending | 4827 | && !LLDrawPoolAvatar::sSkipTransparent; |
4832 | bool should_alpha_mask = mHasBakedHair | ||
4833 | && mBakedTextureData[BAKED_EYES].mIsLoaded | ||
4834 | && mBakedTextureData[BAKED_EYES].mIsUsed | ||
4835 | && !(isSelf() && gAgent.cameraCustomizeAvatar()); | ||
4836 | 4828 | ||
4837 | LLGLState test(GL_ALPHA_TEST, should_alpha_mask); | ||
4838 | 4829 | ||
4839 | if (should_alpha_mask) | 4830 | LLGLState test(GL_ALPHA_TEST, should_alpha_mask); |
4840 | { | ||
4841 | gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); | ||
4842 | } | ||
4843 | 4831 | ||
4832 | if (should_alpha_mask) | ||
4833 | { | ||
4834 | gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); | ||
4835 | } | ||
4836 | |||
4837 | if (isTextureVisible(TEX_EYES_BAKED) || mIsDummy) | ||
4838 | { | ||
4844 | num_indices += mMeshLOD[MESH_ID_EYEBALL_LEFT]->render(mAdjustedPixelArea, TRUE, mIsDummy); | 4839 | num_indices += mMeshLOD[MESH_ID_EYEBALL_LEFT]->render(mAdjustedPixelArea, TRUE, mIsDummy); |
4845 | num_indices += mMeshLOD[MESH_ID_EYEBALL_RIGHT]->render(mAdjustedPixelArea, TRUE, mIsDummy); | 4840 | num_indices += mMeshLOD[MESH_ID_EYEBALL_RIGHT]->render(mAdjustedPixelArea, TRUE, mIsDummy); |
4846 | |||
4847 | gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); | ||
4848 | } | 4841 | } |
4849 | 4842 | ||
4843 | gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); | ||
4850 | return num_indices; | 4844 | return num_indices; |
4851 | } | 4845 | } |
4852 | 4846 | ||
@@ -5019,6 +5013,7 @@ void LLVOAvatar::updateTextures() | |||
5019 | // Spam if this is a baked texture, not set to default image, without valid host info | 5013 | // Spam if this is a baked texture, not set to default image, without valid host info |
5020 | if (isIndexBakedTexture((ETextureIndex)index) | 5014 | if (isIndexBakedTexture((ETextureIndex)index) |
5021 | && imagep->getID() != IMG_DEFAULT_AVATAR | 5015 | && imagep->getID() != IMG_DEFAULT_AVATAR |
5016 | && imagep->getID() != IMG_INVISIBLE | ||
5022 | && !imagep->getTargetHost().isOk()) | 5017 | && !imagep->getTargetHost().isOk()) |
5023 | { | 5018 | { |
5024 | LL_WARNS_ONCE("Texture") << "LLVOAvatar::updateTextures No host for texture " | 5019 | LL_WARNS_ONCE("Texture") << "LLVOAvatar::updateTextures No host for texture " |
@@ -5829,6 +5824,7 @@ BOOL LLVOAvatar::loadAvatar() | |||
5829 | if (layer_set->isBodyRegion(baked_dict->mName)) | 5824 | if (layer_set->isBodyRegion(baked_dict->mName)) |
5830 | { | 5825 | { |
5831 | mBakedTextureData[baked_iter->first].mTexLayerSet = layer_set; | 5826 | mBakedTextureData[baked_iter->first].mTexLayerSet = layer_set; |
5827 | layer_set->setBakedTexIndex(baked_iter->first); | ||
5832 | found_baked_entry = true; | 5828 | found_baked_entry = true; |
5833 | break; | 5829 | break; |
5834 | } | 5830 | } |
@@ -7525,6 +7521,9 @@ void LLVOAvatar::updateMeshTextures() | |||
7525 | 7521 | ||
7526 | } | 7522 | } |
7527 | 7523 | ||
7524 | // Turn on alpha masking correctly for yourself and other avatars on 1.23+ | ||
7525 | mSupportsAlphaLayers = isSelf() || is_layer_baked[BAKED_HAIR]; | ||
7526 | |||
7528 | // Baked textures should be requested from the sim this avatar is on. JC | 7527 | // Baked textures should be requested from the sim this avatar is on. JC |
7529 | const LLHost target_host = getObjectHost(); | 7528 | const LLHost target_host = getObjectHost(); |
7530 | if (!target_host.isOk()) | 7529 | if (!target_host.isOk()) |
@@ -7554,7 +7553,7 @@ void LLVOAvatar::updateMeshTextures() | |||
7554 | else | 7553 | else |
7555 | { | 7554 | { |
7556 | mBakedTextureData[i].mIsLoaded = FALSE; | 7555 | mBakedTextureData[i].mIsLoaded = FALSE; |
7557 | if ( (i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER) ) | 7556 | if ((baked_img->getID() != IMG_INVISIBLE) && (i == BAKED_HEAD || i == BAKED_UPPER || i == BAKED_LOWER)) |
7558 | { | 7557 | { |
7559 | baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID )); | 7558 | baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID )); |
7560 | } | 7559 | } |
@@ -7826,7 +7825,13 @@ void LLVOAvatar::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) | |||
7826 | // Baked textures live on other sims. | 7825 | // Baked textures live on other sims. |
7827 | LLHost target_host = getObjectHost(); | 7826 | LLHost target_host = getObjectHost(); |
7828 | setTEImage( te, gImageList.getImageFromHost( uuid, target_host ) ); | 7827 | setTEImage( te, gImageList.getImageFromHost( uuid, target_host ) ); |
7829 | updateMeshTextures(); | 7828 | if (uuid != IMG_INVISIBLE) |
7829 | { | ||
7830 | // Do not update textures when setting a new invisible baked texture as | ||
7831 | // it would result in destroying the calling object (setNewBakedTexture() | ||
7832 | // is called by LLTexLayerSetBuffer::render()) ! | ||
7833 | updateMeshTextures(); | ||
7834 | } | ||
7830 | dirtyMesh(); | 7835 | dirtyMesh(); |
7831 | 7836 | ||
7832 | 7837 | ||
@@ -7839,7 +7844,7 @@ void LLVOAvatar::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) | |||
7839 | if (text_dict->mIsBakedTexture) | 7844 | if (text_dict->mIsBakedTexture) |
7840 | { | 7845 | { |
7841 | llinfos << "New baked texture: " << text_dict->mName << " UUID: " << uuid <<llendl; | 7846 | llinfos << "New baked texture: " << text_dict->mName << " UUID: " << uuid <<llendl; |
7842 | mBakedTextureData[text_dict->mBakedTextureIndex].mTexLayerSet->requestUpdate(); | 7847 | //mBakedTextureData[text_dict->mBakedTextureIndex].mTexLayerSet->requestUpdate(); |
7843 | } | 7848 | } |
7844 | else | 7849 | else |
7845 | { | 7850 | { |
@@ -8087,6 +8092,10 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context ) | |||
8087 | { | 8092 | { |
8088 | llinfos << " " << text_dict->mName << ": IMG_DEFAULT" << llendl; | 8093 | llinfos << " " << text_dict->mName << ": IMG_DEFAULT" << llendl; |
8089 | } | 8094 | } |
8095 | else if (te_image->getID() == IMG_INVISIBLE) | ||
8096 | { | ||
8097 | llinfos << " " << text_dict->mName << ": IMG_INVISIBLE" << llendl; | ||
8098 | } | ||
8090 | else if( te_image->getID() == IMG_DEFAULT_AVATAR ) | 8099 | else if( te_image->getID() == IMG_DEFAULT_AVATAR ) |
8091 | { | 8100 | { |
8092 | llinfos << " " << text_dict->mName << ": IMG_DEFAULT_AVATAR" << llendl; | 8101 | llinfos << " " << text_dict->mName << ": IMG_DEFAULT_AVATAR" << llendl; |
@@ -8258,11 +8267,11 @@ BOOL LLVOAvatar::isWearingWearableType( EWearableType type ) | |||
8258 | } | 8267 | } |
8259 | 8268 | ||
8260 | //----------------------------------------------------------------------------- | 8269 | //----------------------------------------------------------------------------- |
8261 | // updatedWearable( EWearableType type ) | 8270 | // wearableUpdated(EWearableType type, BOOL upload_result) |
8262 | // forces an update to any baked textures relevant to type. | 8271 | // forces an update to any baked textures relevant to type. |
8263 | // Should be called only on saving the wearable | 8272 | // will force an upload of the resulting bake if the second parameter is TRUE |
8264 | //----------------------------------------------------------------------------- | 8273 | //----------------------------------------------------------------------------- |
8265 | void LLVOAvatar::wearableUpdated( EWearableType type ) | 8274 | void LLVOAvatar::wearableUpdated(EWearableType type, BOOL upload_result) |
8266 | { | 8275 | { |
8267 | for (LLVOAvatarDictionary::wearable_map_t::const_iterator wearable_iter = LLVOAvatarDictionary::getInstance()->getWearables().begin(); | 8276 | for (LLVOAvatarDictionary::wearable_map_t::const_iterator wearable_iter = LLVOAvatarDictionary::getInstance()->getWearables().begin(); |
8268 | wearable_iter != LLVOAvatarDictionary::getInstance()->getWearables().end(); | 8277 | wearable_iter != LLVOAvatarDictionary::getInstance()->getWearables().end(); |
@@ -8281,8 +8290,8 @@ void LLVOAvatar::wearableUpdated( EWearableType type ) | |||
8281 | { | 8290 | { |
8282 | if (mBakedTextureData[index].mTexLayerSet) | 8291 | if (mBakedTextureData[index].mTexLayerSet) |
8283 | { | 8292 | { |
8284 | mBakedTextureData[index].mTexLayerSet->requestUpdate(); | 8293 | invalidateComposite(mBakedTextureData[index].mTexLayerSet, upload_result); |
8285 | mBakedTextureData[index].mTexLayerSet->requestUpload(); | 8294 | updateMeshTextures(); |
8286 | } | 8295 | } |
8287 | break; | 8296 | break; |
8288 | } | 8297 | } |
@@ -8381,7 +8390,7 @@ void LLVOAvatar::onFirstTEMessageReceived() | |||
8381 | LLViewerImage* image = getTEImage( mBakedTextureData[i].mTextureIndex ); | 8390 | LLViewerImage* image = getTEImage( mBakedTextureData[i].mTextureIndex ); |
8382 | mBakedTextureData[i].mLastTextureIndex = image->getID(); | 8391 | mBakedTextureData[i].mLastTextureIndex = image->getID(); |
8383 | // If we have more than one texture for the other baked layers, we'll want to call this for them too. | 8392 | // If we have more than one texture for the other baked layers, we'll want to call this for them too. |
8384 | if ( (i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER) ) | 8393 | if ((image->getID() != IMG_INVISIBLE) && (i == BAKED_HEAD || i == BAKED_UPPER || i == BAKED_LOWER)) |
8385 | { | 8394 | { |
8386 | image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID )); | 8395 | image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID )); |
8387 | } | 8396 | } |
@@ -8653,7 +8662,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi, | |||
8653 | { | 8662 | { |
8654 | const ETextureIndex texture_index = iter->first; | 8663 | const ETextureIndex texture_index = iter->first; |
8655 | const LLViewerImage *baked_img = self->getTEImage(texture_index); | 8664 | const LLViewerImage *baked_img = self->getTEImage(texture_index); |
8656 | if (id == baked_img->getID()) | 8665 | if (baked_img && id == baked_img->getID()) |
8657 | { | 8666 | { |
8658 | const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex; | 8667 | const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex; |
8659 | if (self->mBakedTextureData[baked_index].mTexLayerSet) | 8668 | if (self->mBakedTextureData[baked_index].mTexLayerSet) |
diff --git a/linden/indra/newview/llvoavatar.h b/linden/indra/newview/llvoavatar.h index 0bf648a..1914f47 100644 --- a/linden/indra/newview/llvoavatar.h +++ b/linden/indra/newview/llvoavatar.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <string> | 39 | #include <string> |
40 | #include <vector> | 40 | #include <vector> |
41 | 41 | ||
42 | #include "imageids.h" // IMG_INVISIBLE | ||
42 | #include "llchat.h" | 43 | #include "llchat.h" |
43 | #include "lldrawpoolalpha.h" | 44 | #include "lldrawpoolalpha.h" |
44 | #include "llviewerobject.h" | 45 | #include "llviewerobject.h" |
@@ -342,7 +343,7 @@ public: | |||
342 | BOOL teToColorParams( LLVOAvatarDefines::ETextureIndex te, const char* param_name[3] ); | 343 | BOOL teToColorParams( LLVOAvatarDefines::ETextureIndex te, const char* param_name[3] ); |
343 | 344 | ||
344 | BOOL isWearingWearableType( EWearableType type ); | 345 | BOOL isWearingWearableType( EWearableType type ); |
345 | void wearableUpdated( EWearableType type ); | 346 | void wearableUpdated(EWearableType type, BOOL upload_result = TRUE); |
346 | 347 | ||
347 | //-------------------------------------------------------------------- | 348 | //-------------------------------------------------------------------- |
348 | // texture compositing | 349 | // texture compositing |
@@ -602,6 +603,7 @@ private: | |||
602 | BOOL mIsBuilt; // state of deferred character building | 603 | BOOL mIsBuilt; // state of deferred character building |
603 | F32 mSpeedAccum; // measures speed (for diagnostics mostly). | 604 | F32 mSpeedAccum; // measures speed (for diagnostics mostly). |
604 | 605 | ||
606 | BOOL mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients | ||
605 | 607 | ||
606 | // LLFrameTimer mUpdateLODTimer; // controls frequency of LOD change calculations | 608 | // LLFrameTimer mUpdateLODTimer; // controls frequency of LOD change calculations |
607 | BOOL mDirtyMesh; | 609 | BOOL mDirtyMesh; |
@@ -827,7 +829,7 @@ inline BOOL LLVOAvatar::isTextureDefined(U8 te) const | |||
827 | 829 | ||
828 | inline BOOL LLVOAvatar::isTextureVisible(U8 te) const | 830 | inline BOOL LLVOAvatar::isTextureVisible(U8 te) const |
829 | { | 831 | { |
830 | return ((isTextureDefined(te) || isSelf()) | 832 | return ((isTextureDefined(te) || mIsSelf) |
831 | && (getTEImage(te)->getID() != IMG_INVISIBLE | 833 | && (getTEImage(te)->getID() != IMG_INVISIBLE |
832 | || LLDrawPoolAlpha::sShowDebugAlpha)); | 834 | || LLDrawPoolAlpha::sShowDebugAlpha)); |
833 | } | 835 | } |
diff --git a/linden/indra/newview/llvoavatardefines.cpp b/linden/indra/newview/llvoavatardefines.cpp index 371ecbb..359a821 100644 --- a/linden/indra/newview/llvoavatardefines.cpp +++ b/linden/indra/newview/llvoavatardefines.cpp | |||
@@ -60,6 +60,14 @@ void LLVOAvatarDictionary::initData() | |||
60 | mTextureMap[TEX_UPPER_UNDERSHIRT] = new TextureDictionaryEntry("undershirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", WT_UNDERSHIRT); | 60 | mTextureMap[TEX_UPPER_UNDERSHIRT] = new TextureDictionaryEntry("undershirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", WT_UNDERSHIRT); |
61 | mTextureMap[TEX_LOWER_UNDERPANTS] = new TextureDictionaryEntry("underpants", TRUE, BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", WT_UNDERPANTS); | 61 | mTextureMap[TEX_LOWER_UNDERPANTS] = new TextureDictionaryEntry("underpants", TRUE, BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", WT_UNDERPANTS); |
62 | mTextureMap[TEX_SKIRT] = new TextureDictionaryEntry("skirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultSkirtUUID", WT_SKIRT); | 62 | mTextureMap[TEX_SKIRT] = new TextureDictionaryEntry("skirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultSkirtUUID", WT_SKIRT); |
63 | mTextureMap[TEX_LOWER_ALPHA] = new TextureDictionaryEntry("lower_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA); | ||
64 | mTextureMap[TEX_UPPER_ALPHA] = new TextureDictionaryEntry("upper_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA); | ||
65 | mTextureMap[TEX_HEAD_ALPHA] = new TextureDictionaryEntry("head_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA); | ||
66 | mTextureMap[TEX_EYES_ALPHA] = new TextureDictionaryEntry("eyes_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA); | ||
67 | mTextureMap[TEX_HAIR_ALPHA] = new TextureDictionaryEntry("hair_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA); | ||
68 | mTextureMap[TEX_HEAD_TATTOO] = new TextureDictionaryEntry("head_tattoo", TRUE, BAKED_NUM_INDICES, "", WT_TATTOO); | ||
69 | mTextureMap[TEX_UPPER_TATTOO] = new TextureDictionaryEntry("upper_tattoo", TRUE, BAKED_NUM_INDICES, "", WT_TATTOO); | ||
70 | mTextureMap[TEX_LOWER_TATTOO] = new TextureDictionaryEntry("lower_tattoo", TRUE, BAKED_NUM_INDICES, "", WT_TATTOO); | ||
63 | mTextureMap[TEX_HEAD_BAKED] = new TextureDictionaryEntry("head-baked", FALSE, BAKED_HEAD); | 71 | mTextureMap[TEX_HEAD_BAKED] = new TextureDictionaryEntry("head-baked", FALSE, BAKED_HEAD); |
64 | mTextureMap[TEX_UPPER_BAKED] = new TextureDictionaryEntry("upper-baked", FALSE, BAKED_UPPER); | 72 | mTextureMap[TEX_UPPER_BAKED] = new TextureDictionaryEntry("upper-baked", FALSE, BAKED_UPPER); |
65 | mTextureMap[TEX_LOWER_BAKED] = new TextureDictionaryEntry("lower-baked", FALSE, BAKED_LOWER); | 73 | mTextureMap[TEX_LOWER_BAKED] = new TextureDictionaryEntry("lower-baked", FALSE, BAKED_LOWER); |
@@ -68,12 +76,12 @@ void LLVOAvatarDictionary::initData() | |||
68 | mTextureMap[TEX_SKIRT_BAKED] = new TextureDictionaryEntry("skirt-baked", FALSE, BAKED_SKIRT); | 76 | mTextureMap[TEX_SKIRT_BAKED] = new TextureDictionaryEntry("skirt-baked", FALSE, BAKED_SKIRT); |
69 | 77 | ||
70 | // Baked textures | 78 | // Baked textures |
71 | mBakedTextureMap[BAKED_HEAD] = new BakedDictionaryEntry(TEX_HEAD_BAKED, "head", 1, TEX_HEAD_BODYPAINT); | 79 | mBakedTextureMap[BAKED_HEAD] = new BakedDictionaryEntry(TEX_HEAD_BAKED, "head", 3, TEX_HEAD_BODYPAINT, TEX_HEAD_TATTOO, TEX_HEAD_ALPHA); |
72 | mBakedTextureMap[BAKED_UPPER] = new BakedDictionaryEntry(TEX_UPPER_BAKED, "upper_body", 5, TEX_UPPER_SHIRT,TEX_UPPER_BODYPAINT,TEX_UPPER_JACKET,TEX_UPPER_GLOVES,TEX_UPPER_UNDERSHIRT); | 80 | mBakedTextureMap[BAKED_UPPER] = new BakedDictionaryEntry(TEX_UPPER_BAKED, "upper_body", 7, TEX_UPPER_SHIRT, TEX_UPPER_BODYPAINT, TEX_UPPER_JACKET, TEX_UPPER_GLOVES, TEX_UPPER_UNDERSHIRT, TEX_UPPER_TATTOO, TEX_UPPER_ALPHA); |
73 | mBakedTextureMap[BAKED_LOWER] = new BakedDictionaryEntry(TEX_LOWER_BAKED, "lower_body", 6, TEX_LOWER_PANTS,TEX_LOWER_BODYPAINT,TEX_LOWER_SHOES,TEX_LOWER_SOCKS,TEX_LOWER_JACKET,TEX_LOWER_UNDERPANTS); | 81 | mBakedTextureMap[BAKED_LOWER] = new BakedDictionaryEntry(TEX_LOWER_BAKED, "lower_body", 8, TEX_LOWER_PANTS, TEX_LOWER_BODYPAINT, TEX_LOWER_SHOES, TEX_LOWER_SOCKS, TEX_LOWER_JACKET, TEX_LOWER_UNDERPANTS, TEX_LOWER_TATTOO, TEX_LOWER_ALPHA); |
74 | mBakedTextureMap[BAKED_EYES] = new BakedDictionaryEntry(TEX_EYES_BAKED, "eyes", 1, TEX_EYES_IRIS); | 82 | mBakedTextureMap[BAKED_EYES] = new BakedDictionaryEntry(TEX_EYES_BAKED, "eyes", 2, TEX_EYES_IRIS, TEX_EYES_ALPHA); |
75 | mBakedTextureMap[BAKED_SKIRT] = new BakedDictionaryEntry(TEX_SKIRT_BAKED, "skirt", 1, TEX_SKIRT); | 83 | mBakedTextureMap[BAKED_SKIRT] = new BakedDictionaryEntry(TEX_SKIRT_BAKED, "skirt", 1, TEX_SKIRT); |
76 | mBakedTextureMap[BAKED_HAIR] = new BakedDictionaryEntry(TEX_HAIR_BAKED, "hair", 1, TEX_HAIR); | 84 | mBakedTextureMap[BAKED_HAIR] = new BakedDictionaryEntry(TEX_HAIR_BAKED, "hair", 2, TEX_HAIR, TEX_HAIR_ALPHA); |
77 | 85 | ||
78 | // Meshes | 86 | // Meshes |
79 | mMeshMap[MESH_ID_HAIR] = new MeshDictionaryEntry(BAKED_HAIR, "hairMesh", 6, LLViewerJoint::PN_4); | 87 | mMeshMap[MESH_ID_HAIR] = new MeshDictionaryEntry(BAKED_HAIR, "hairMesh", 6, LLViewerJoint::PN_4); |
@@ -86,12 +94,12 @@ void LLVOAvatarDictionary::initData() | |||
86 | mMeshMap[MESH_ID_SKIRT] = new MeshDictionaryEntry(BAKED_SKIRT, "skirtMesh", 5, LLViewerJoint::PN_5); | 94 | mMeshMap[MESH_ID_SKIRT] = new MeshDictionaryEntry(BAKED_SKIRT, "skirtMesh", 5, LLViewerJoint::PN_5); |
87 | 95 | ||
88 | // Wearables | 96 | // Wearables |
89 | mWearableMap[BAKED_HEAD] = new WearableDictionaryEntry("18ded8d6-bcfc-e415-8539-944c0f5ea7a6", 3, WT_SHAPE, WT_SKIN, WT_HAIR); | 97 | mWearableMap[BAKED_HEAD] = new WearableDictionaryEntry("18ded8d6-bcfc-e415-8539-944c0f5ea7a6", 5, WT_SHAPE, WT_SKIN, WT_HAIR, WT_TATTOO, WT_ALPHA); |
90 | mWearableMap[BAKED_UPPER] = new WearableDictionaryEntry("338c29e3-3024-4dbb-998d-7c04cf4fa88f", 6, WT_SHAPE, WT_SKIN, WT_SHIRT, WT_JACKET, WT_GLOVES, WT_UNDERSHIRT); | 98 | mWearableMap[BAKED_UPPER] = new WearableDictionaryEntry("338c29e3-3024-4dbb-998d-7c04cf4fa88f", 8, WT_SHAPE, WT_SKIN, WT_SHIRT, WT_JACKET, WT_GLOVES, WT_UNDERSHIRT, WT_TATTOO, WT_ALPHA); |
91 | mWearableMap[BAKED_LOWER] = new WearableDictionaryEntry("91b4a2c7-1b1a-ba16-9a16-1f8f8dcc1c3f", 7, WT_SHAPE, WT_SKIN, WT_PANTS, WT_SHOES, WT_SOCKS, WT_JACKET, WT_UNDERPANTS); | 99 | mWearableMap[BAKED_LOWER] = new WearableDictionaryEntry("91b4a2c7-1b1a-ba16-9a16-1f8f8dcc1c3f", 9, WT_SHAPE, WT_SKIN, WT_PANTS, WT_SHOES, WT_SOCKS, WT_JACKET, WT_UNDERPANTS, WT_TATTOO, WT_ALPHA); |
92 | mWearableMap[BAKED_EYES] = new WearableDictionaryEntry("b2cf28af-b840-1071-3c6a-78085d8128b5", 1, WT_EYES); | 100 | mWearableMap[BAKED_EYES] = new WearableDictionaryEntry("b2cf28af-b840-1071-3c6a-78085d8128b5", 2, WT_EYES, WT_ALPHA); |
93 | mWearableMap[BAKED_SKIRT] = new WearableDictionaryEntry("ea800387-ea1a-14e0-56cb-24f2022f969a", 1, WT_SKIRT); | 101 | mWearableMap[BAKED_SKIRT] = new WearableDictionaryEntry("ea800387-ea1a-14e0-56cb-24f2022f969a", 1, WT_SKIRT); |
94 | mWearableMap[BAKED_HAIR] = new WearableDictionaryEntry("0af1ef7c-ad24-11dd-8790-001f5bf833e8", 1, WT_HAIR); | 102 | mWearableMap[BAKED_HAIR] = new WearableDictionaryEntry("0af1ef7c-ad24-11dd-8790-001f5bf833e8", 2, WT_HAIR, WT_ALPHA); |
95 | } | 103 | } |
96 | 104 | ||
97 | /* | 105 | /* |
diff --git a/linden/indra/newview/llvoavatardefines.h b/linden/indra/newview/llvoavatardefines.h index b4da140..1fb516c 100644 --- a/linden/indra/newview/llvoavatardefines.h +++ b/linden/indra/newview/llvoavatardefines.h | |||
@@ -70,9 +70,16 @@ enum ETextureIndex | |||
70 | TEX_SKIRT, | 70 | TEX_SKIRT, |
71 | TEX_SKIRT_BAKED, // Pre-composited | 71 | TEX_SKIRT_BAKED, // Pre-composited |
72 | TEX_HAIR_BAKED, // Pre-composited | 72 | TEX_HAIR_BAKED, // Pre-composited |
73 | TEX_LOWER_ALPHA, | ||
74 | TEX_UPPER_ALPHA, | ||
75 | TEX_HEAD_ALPHA, | ||
76 | TEX_EYES_ALPHA, | ||
77 | TEX_HAIR_ALPHA, | ||
78 | TEX_HEAD_TATTOO, | ||
79 | TEX_UPPER_TATTOO, | ||
80 | TEX_LOWER_TATTOO, | ||
73 | TEX_NUM_INDICES | 81 | TEX_NUM_INDICES |
74 | }; // "Note: if TEX_NUM_ENTRIES changes, update AGENT_TEXTURES in llagentinfo.h, mTextureIndexBaked, and BAKED_TEXTURE_COUNT" | 82 | }; |
75 | // Seraph - Above comment about order is probably obsolete. | ||
76 | 83 | ||
77 | typedef std::vector<ETextureIndex> texture_vec_t; | 84 | typedef std::vector<ETextureIndex> texture_vec_t; |
78 | 85 | ||
diff --git a/linden/indra/newview/llwearable.cpp b/linden/indra/newview/llwearable.cpp index 087c74c..b74ef02 100644 --- a/linden/indra/newview/llwearable.cpp +++ b/linden/indra/newview/llwearable.cpp | |||
@@ -70,6 +70,8 @@ const std::string LLWearable::sTypeName[ WT_COUNT+1 ] = | |||
70 | "undershirt", | 70 | "undershirt", |
71 | "underpants", | 71 | "underpants", |
72 | "skirt", | 72 | "skirt", |
73 | "alpha", | ||
74 | "tattoo", | ||
73 | "invalid" | 75 | "invalid" |
74 | }; | 76 | }; |
75 | 77 | ||
@@ -89,6 +91,8 @@ const std::string LLWearable::sTypeLabel[ WT_COUNT+1 ] = | |||
89 | "Undershirt", | 91 | "Undershirt", |
90 | "Underpants", | 92 | "Underpants", |
91 | "Skirt", | 93 | "Skirt", |
94 | "Alpha", | ||
95 | "Tattoo", | ||
92 | "invalid" | 96 | "invalid" |
93 | }; | 97 | }; |
94 | 98 | ||
@@ -112,6 +116,8 @@ LLAssetType::EType LLWearable::typeToAssetType(EWearableType wearable_type) | |||
112 | case WT_UNDERSHIRT: | 116 | case WT_UNDERSHIRT: |
113 | case WT_UNDERPANTS: | 117 | case WT_UNDERPANTS: |
114 | case WT_SKIRT: | 118 | case WT_SKIRT: |
119 | case WT_ALPHA: | ||
120 | case WT_TATTOO: | ||
115 | return LLAssetType::AT_CLOTHING; | 121 | return LLAssetType::AT_CLOTHING; |
116 | default: | 122 | default: |
117 | return LLAssetType::AT_NONE; | 123 | return LLAssetType::AT_NONE; |
diff --git a/linden/indra/newview/rlvhandler.cpp b/linden/indra/newview/rlvhandler.cpp index 88cd174..7f6643c 100644 --- a/linden/indra/newview/rlvhandler.cpp +++ b/linden/indra/newview/rlvhandler.cpp | |||
@@ -1097,7 +1097,7 @@ BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCm | |||
1097 | 1097 | ||
1098 | const EWearableType layerTypes[] = | 1098 | const EWearableType layerTypes[] = |
1099 | { | 1099 | { |
1100 | WT_GLOVES, WT_JACKET, WT_PANTS, WT_SHIRT, WT_SHOES, WT_SKIRT, WT_SOCKS, | 1100 | WT_GLOVES, WT_JACKET, WT_PANTS, WT_SHIRT, WT_SHOES, WT_SKIRT, WT_ALPHA, WT_TATTOO, WT_SOCKS, |
1101 | WT_UNDERPANTS, WT_UNDERSHIRT, WT_SKIN, WT_EYES, WT_HAIR, WT_SHAPE | 1101 | WT_UNDERPANTS, WT_UNDERSHIRT, WT_SKIN, WT_EYES, WT_HAIR, WT_SHAPE |
1102 | }; | 1102 | }; |
1103 | 1103 | ||
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_customize.xml b/linden/indra/newview/skins/default/xui/en-us/floater_customize.xml index e947ecd..a0dd938 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_customize.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_customize.xml | |||
@@ -1108,6 +1108,174 @@ scratch and wear it. | |||
1108 | height="20" label="Revert" label_selected="Revert" left="305" | 1108 | height="20" label="Revert" label_selected="Revert" left="305" |
1109 | mouse_opaque="true" name="Revert" scale_image="true" width="82" /> | 1109 | mouse_opaque="true" name="Revert" scale_image="true" width="82" /> |
1110 | </panel> | 1110 | </panel> |
1111 | <panel name="Tattoo" label="Tattoo" border="true" mouse_opaque="true" | ||
1112 | follows="left|top|right|bottom" width="389" height="481" left="102" bottom="-482"> | ||
1113 | <icon bottom="-21" color="1 1 1 1" follows="top|right" height="16" | ||
1114 | image_name="icon_lock.tga" left="333" mouse_opaque="true" name="square" | ||
1115 | width="16" /> | ||
1116 | <icon bottom="-24" color="1 1 1 1" follows="left|top" height="16" left="8" | ||
1117 | mouse_opaque="true" name="icon" width="16" /> | ||
1118 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1119 | bottom="-24" drop_shadow_visible="true" follows="left|top|right" | ||
1120 | font="SansSerif" h_pad="0" halign="left" height="16" left="26" | ||
1121 | mouse_opaque="true" name="title" v_pad="0" width="355"> | ||
1122 | [DESC] | ||
1123 | </text> | ||
1124 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1125 | bottom="-24" drop_shadow_visible="true" follows="left|top|right" | ||
1126 | font="SansSerif" h_pad="0" halign="left" height="16" left="26" | ||
1127 | mouse_opaque="true" name="title_no_modify" v_pad="0" width="355"> | ||
1128 | [DESC]: cannot modify | ||
1129 | </text> | ||
1130 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1131 | bottom="-24" drop_shadow_visible="true" follows="left|top|right" | ||
1132 | font="SansSerif" h_pad="0" halign="left" height="16" left="26" | ||
1133 | mouse_opaque="true" name="title_loading" v_pad="0" width="355"> | ||
1134 | [DESC]: loading... | ||
1135 | </text> | ||
1136 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1137 | bottom="-24" drop_shadow_visible="true" follows="left|top|right" | ||
1138 | font="SansSerif" h_pad="0" halign="left" height="16" left="26" | ||
1139 | mouse_opaque="true" name="title_not_worn" v_pad="0" width="355"> | ||
1140 | [DESC]: not worn | ||
1141 | </text> | ||
1142 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1143 | bottom="-38" drop_shadow_visible="true" follows="left|top|right" | ||
1144 | font="SansSerifSmall" h_pad="0" halign="left" height="14" left="8" | ||
1145 | mouse_opaque="true" name="path" v_pad="0" width="373"> | ||
1146 | Located in [PATH] | ||
1147 | </text> | ||
1148 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1149 | bottom="-74" drop_shadow_visible="true" follows="left|top|right" | ||
1150 | font="SansSerifSmall" h_pad="0" halign="left" height="28" left="8" | ||
1151 | mouse_opaque="true" name="not worn instructions" v_pad="0" width="373"> | ||
1152 | Put on a new tattoo by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. | ||
1153 | </text> | ||
1154 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1155 | bottom="-74" drop_shadow_visible="true" follows="left|top|right" | ||
1156 | font="SansSerifSmall" h_pad="0" halign="left" height="28" left="8" | ||
1157 | mouse_opaque="true" name="no modify instructions" v_pad="0" width="373"> | ||
1158 | You do not have permission to modify this wearable. | ||
1159 | </text> | ||
1160 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1161 | bottom="-486" drop_shadow_visible="true" follows="left|top|right" | ||
1162 | font="SansSerif" h_pad="0" halign="right" height="28" right="117" | ||
1163 | mouse_opaque="true" name="Item Action Label" v_pad="0" width="100"> | ||
1164 | Tattoo: | ||
1165 | </text> | ||
1166 | <texture_picker name="Head Tattoo" label="Head Tattoo" tool_tip="Click to choose a picture" | ||
1167 | can_apply_immediately="true" default_image_name="Default" allow_no_texture="true" | ||
1168 | follows="left|top" width="70" height="80" left="14" bottom="-145"/> | ||
1169 | <texture_picker name="Upper Tattoo" label="Upper Tattoo" tool_tip="Click to choose a picture" | ||
1170 | can_apply_immediately="true" default_image_name="Default" allow_no_texture="true" | ||
1171 | follows="left|top" width="70" height="80" left="14" bottom="-235"/> | ||
1172 | <texture_picker name="Lower Tattoo" label="Lower Tattoo" tool_tip="Click to choose a picture" | ||
1173 | can_apply_immediately="true" default_image_name="Default" allow_no_texture="true" | ||
1174 | follows="left|top" width="70" height="80" left="14" bottom="-325"/> | ||
1175 | <button name="Create New" label="Create New Tattoo" label_selected="Create New Tattoo" | ||
1176 | follows="left|top" halign="center" width="170" height="24" left="8" bottom="-128" | ||
1177 | mouse_opaque="true" scale_image="true"/> | ||
1178 | <button name="Take Off" label="Take Off" label_selected="Take Off" | ||
1179 | follows="left|top" width="82" height="20" left="8" bottom="-365"/> | ||
1180 | <button name="Save" label="Save" label_selected="Save" | ||
1181 | follows="right|bottom" width="82" height="20" left="123" bottom="-478"/> | ||
1182 | <button name="Save As" label="Save As..." label_selected="Save As..." | ||
1183 | follows="right|bottom" width="92" height="20" left="209" bottom="-478"/> | ||
1184 | <button name="Revert" label="Revert" label_selected="Revert" | ||
1185 | follows="right|bottom" width="82" height="20" left="305" bottom="-478"/> | ||
1186 | </panel> | ||
1187 | <panel name="Alpha" label="Alpha" border="true" mouse_opaque="true" | ||
1188 | follows="left|top|right|bottom" width="389" height="481" left="102" bottom="-482"> | ||
1189 | <icon bottom="-21" color="1 1 1 1" follows="top|right" height="16" | ||
1190 | image_name="icon_lock.tga" left="333" mouse_opaque="true" name="square" | ||
1191 | width="16" /> | ||
1192 | <icon bottom="-24" color="1 1 1 1" follows="left|top" height="16" left="8" | ||
1193 | mouse_opaque="true" name="icon" width="16" /> | ||
1194 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1195 | bottom="-24" drop_shadow_visible="true" follows="left|top|right" | ||
1196 | font="SansSerif" h_pad="0" halign="left" height="16" left="26" | ||
1197 | mouse_opaque="true" name="title" v_pad="0" width="355"> | ||
1198 | [DESC] | ||
1199 | </text> | ||
1200 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1201 | bottom="-24" drop_shadow_visible="true" follows="left|top|right" | ||
1202 | font="SansSerif" h_pad="0" halign="left" height="16" left="26" | ||
1203 | mouse_opaque="true" name="title_no_modify" v_pad="0" width="355"> | ||
1204 | [DESC]: cannot modify | ||
1205 | </text> | ||
1206 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1207 | bottom="-24" drop_shadow_visible="true" follows="left|top|right" | ||
1208 | font="SansSerif" h_pad="0" halign="left" height="16" left="26" | ||
1209 | mouse_opaque="true" name="title_loading" v_pad="0" width="355"> | ||
1210 | [DESC]: loading... | ||
1211 | </text> | ||
1212 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1213 | bottom="-24" drop_shadow_visible="true" follows="left|top|right" | ||
1214 | font="SansSerif" h_pad="0" halign="left" height="16" left="26" | ||
1215 | mouse_opaque="true" name="title_not_worn" v_pad="0" width="355"> | ||
1216 | [DESC]: not worn | ||
1217 | </text> | ||
1218 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1219 | bottom="-38" drop_shadow_visible="true" follows="left|top|right" | ||
1220 | font="SansSerifSmall" h_pad="0" halign="left" height="14" left="8" | ||
1221 | mouse_opaque="true" name="path" v_pad="0" width="373"> | ||
1222 | Located in [PATH] | ||
1223 | </text> | ||
1224 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1225 | bottom="-74" drop_shadow_visible="true" follows="left|top|right" | ||
1226 | font="SansSerifSmall" h_pad="0" halign="left" height="28" left="8" | ||
1227 | mouse_opaque="true" name="not worn instructions" v_pad="0" width="373"> | ||
1228 | Put on a new alpha mask by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. | ||
1229 | </text> | ||
1230 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1231 | bottom="-74" drop_shadow_visible="true" follows="left|top|right" | ||
1232 | font="SansSerifSmall" h_pad="0" halign="left" height="28" left="8" | ||
1233 | mouse_opaque="true" name="no modify instructions" v_pad="0" width="373"> | ||
1234 | You do not have permission to modify this wearable. | ||
1235 | </text> | ||
1236 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
1237 | bottom="-486" drop_shadow_visible="true" follows="left|top|right" | ||
1238 | font="SansSerif" h_pad="0" halign="right" height="28" right="117" | ||
1239 | mouse_opaque="true" name="Item Action Label" v_pad="0" width="100"> | ||
1240 | Alpha: | ||
1241 | </text> | ||
1242 | <texture_picker name="Head Alpha" label="Head Alpha" tool_tip="Click to choose a picture" | ||
1243 | can_apply_immediately="true" default_image_name="Default" allow_no_texture="true" | ||
1244 | follows="left|top" width="64" height="80" left="120" bottom="-165"/> | ||
1245 | <texture_picker name="Upper Alpha" label="Upper Alpha" tool_tip="Click to choose a picture" | ||
1246 | can_apply_immediately="true" default_image_name="Default" allow_no_texture="true" | ||
1247 | follows="left|top" width="64" height="80" left_delta="90" bottom="-165"/> | ||
1248 | <texture_picker name="Lower Alpha" label="Lower Alpha" tool_tip="Click to choose a picture" | ||
1249 | can_apply_immediately="true" default_image_name="Default" allow_no_texture="true" | ||
1250 | follows="left|top" width="64" height="80" left_delta="90" bottom="-165"/> | ||
1251 | <check_box name="head alpha texture invisible" | ||
1252 | follows="left" width="16" height="16" left="142" bottom="-185"/> | ||
1253 | <check_box name="upper alpha texture invisible" | ||
1254 | follows="left" width="16" height="16" left_delta="90" bottom="-185"/> | ||
1255 | <check_box name="lower alpha texture invisible" | ||
1256 | follows="left" width="16" height="16" left_delta="90" bottom="-185"/> | ||
1257 | <texture_picker name="Hair Alpha" label="Hair Alpha" tool_tip="Click to choose a picture" | ||
1258 | can_apply_immediately="true" default_image_name="Default" allow_no_texture="true" | ||
1259 | follows="left|top" width="64" height="80" left="120" bottom="-280"/> | ||
1260 | <texture_picker name="Eye Alpha" label="Eye Alpha" tool_tip="Click to choose a picture" | ||
1261 | can_apply_immediately="true" default_image_name="Default" allow_no_texture="true" | ||
1262 | follows="left|top" width="64" height="80" left_delta="90" bottom="-280"/> | ||
1263 | <check_box name="hair alpha texture invisible" | ||
1264 | follows="left" width="16" height="16" left="142" bottom="-300"/> | ||
1265 | <check_box name="eye alpha texture invisible" | ||
1266 | follows="left" width="16" height="16" left_delta="90" bottom="-300"/> | ||
1267 | <button name="Create New" label="Create New Alpha" label_selected="Create New Alpha" | ||
1268 | follows="left|top" halign="center" width="170" height="24" left="8" bottom="-128" | ||
1269 | mouse_opaque="true" scale_image="true"/> | ||
1270 | <button name="Take Off" label="Take Off" label_selected="Take Off" | ||
1271 | follows="left|top" width="82" height="20" left="123" bottom="-340"/> | ||
1272 | <button name="Save" label="Save" label_selected="Save" | ||
1273 | follows="right|bottom" width="82" height="20" left="123" bottom="-478"/> | ||
1274 | <button name="Save As" label="Save As..." label_selected="Save As..." | ||
1275 | follows="right|bottom" width="92" height="20" left="209" bottom="-478"/> | ||
1276 | <button name="Revert" label="Revert" label_selected="Revert" | ||
1277 | follows="right|bottom" width="82" height="20" left="305" bottom="-478"/> | ||
1278 | </panel> | ||
1111 | </tab_container> | 1279 | </tab_container> |
1112 | <scroll_container bottom="-476" follows="left|top|right|bottom" height="382" left="197" | 1280 | <scroll_container bottom="-476" follows="left|top|right|bottom" height="382" left="197" |
1113 | mouse_opaque="false" name="panel_container" opaque="false" width="292" /> | 1281 | mouse_opaque="false" name="panel_container" opaque="false" width="292" /> |
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_inventory.xml b/linden/indra/newview/skins/default/xui/en-us/floater_inventory.xml index 103a11e..f1a6626 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_inventory.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_inventory.xml | |||
@@ -160,6 +160,14 @@ | |||
160 | mouse_opaque="true" name="New Underpants" width="125"> | 160 | mouse_opaque="true" name="New Underpants" width="125"> |
161 | <on_click filter="" function="Inventory.DoCreate" userdata="underpants" /> | 161 | <on_click filter="" function="Inventory.DoCreate" userdata="underpants" /> |
162 | </menu_item_call> | 162 | </menu_item_call> |
163 | <menu_item_call bottom_delta="-18" height="18" label="New Tattoo" left="0" | ||
164 | mouse_opaque="true" name="New Tattoo" width="125"> | ||
165 | <on_click filter="" function="Inventory.DoCreate" userdata="tattoo" /> | ||
166 | </menu_item_call> | ||
167 | <menu_item_call bottom_delta="-18" height="18" label="New Alpha" left="0" | ||
168 | mouse_opaque="true" name="New Alpha" width="125"> | ||
169 | <on_click filter="" function="Inventory.DoCreate" userdata="alpha" /> | ||
170 | </menu_item_call> | ||
163 | </menu> | 171 | </menu> |
164 | <menu bottom_delta="-599" drop_shadow="true" height="85" left="0" | 172 | <menu bottom_delta="-599" drop_shadow="true" height="85" left="0" |
165 | mouse_opaque="false" name="New Body Parts" opaque="true" width="118"> | 173 | mouse_opaque="false" name="New Body Parts" opaque="true" width="118"> |
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_new_outfit_dialog.xml b/linden/indra/newview/skins/default/xui/en-us/floater_new_outfit_dialog.xml index 27a08c1..51cd2f5 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_new_outfit_dialog.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_new_outfit_dialog.xml | |||
@@ -21,7 +21,7 @@ | |||
21 | <check_box bottom="-276" enabled="true" follows="left|top" font="SansSerifSmall" | 21 | <check_box bottom="-276" enabled="true" follows="left|top" font="SansSerifSmall" |
22 | height="16" initial_value="false" label="Eyes" left="13" | 22 | height="16" initial_value="false" label="Eyes" left="13" |
23 | mouse_opaque="true" name="checkbox_Eyes" radio_style="false" width="100" /> | 23 | mouse_opaque="true" name="checkbox_Eyes" radio_style="false" width="100" /> |
24 | <check_box bottom="-434" enabled="true" follows="left|top" font="SansSerifSmall" | 24 | <check_box bottom="-456" enabled="true" follows="left|top" font="SansSerifSmall" |
25 | height="16" initial_value="false" label="Rename Clothing To Folder Name" | 25 | height="16" initial_value="false" label="Rename Clothing To Folder Name" |
26 | left="13" mouse_opaque="true" name="rename" radio_style="false" width="210" /> | 26 | left="13" mouse_opaque="true" name="rename" radio_style="false" width="210" /> |
27 | <check_box bottom="-216" enabled="true" follows="left|top" font="SansSerifSmall" | 27 | <check_box bottom="-216" enabled="true" follows="left|top" font="SansSerifSmall" |
@@ -53,6 +53,12 @@ | |||
53 | <check_box bottom="-376" enabled="true" follows="left|top" font="SansSerifSmall" | 53 | <check_box bottom="-376" enabled="true" follows="left|top" font="SansSerifSmall" |
54 | height="16" initial_value="false" label="Skirt" left="113" | 54 | height="16" initial_value="false" label="Skirt" left="113" |
55 | mouse_opaque="true" name="checkbox_Skirt" radio_style="false" width="100" /> | 55 | mouse_opaque="true" name="checkbox_Skirt" radio_style="false" width="100" /> |
56 | <check_box bottom="-396" enabled="true" follows="left|top" font="SansSerifSmall" | ||
57 | height="16" initial_value="false" label="Tattoo" left="113" | ||
58 | mouse_opaque="true" name="checkbox_Tattoo" radio_style="false" width="100" /> | ||
59 | <check_box bottom="-416" enabled="true" follows="left|top" font="SansSerifSmall" | ||
60 | height="16" initial_value="false" label="Alpha" left="113" | ||
61 | mouse_opaque="true" name="checkbox_Alpha" radio_style="false" width="100" /> | ||
56 | <check_box bottom="-216" enabled="false" follows="left|top" font="SansSerifSmall" | 62 | <check_box bottom="-216" enabled="false" follows="left|top" font="SansSerifSmall" |
57 | height="16" initial_value="false" label="Chest" left="213" | 63 | height="16" initial_value="false" label="Chest" left="213" |
58 | mouse_opaque="true" name="checkbox_Chest" radio_style="false" width="100" /> | 64 | mouse_opaque="true" name="checkbox_Chest" radio_style="false" width="100" /> |
@@ -250,7 +256,7 @@ now wearing into it. | |||
250 | Attachments: | 256 | Attachments: |
251 | </text> | 257 | </text> |
252 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | 258 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" |
253 | bottom="-414" drop_shadow_visible="true" enabled="true" follows="left|top" | 259 | bottom="-436" drop_shadow_visible="true" enabled="true" follows="left|top" |
254 | font="SansSerifSmall" h_pad="0" halign="left" height="14" left="13" | 260 | font="SansSerifSmall" h_pad="0" halign="left" height="14" left="13" |
255 | mouse_opaque="true" name="Options:" v_pad="0" width="100"> | 261 | mouse_opaque="true" name="Options:" v_pad="0" width="100"> |
256 | Options: | 262 | Options: |
diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_inventory.xml b/linden/indra/newview/skins/default/xui/en-us/menu_inventory.xml index e50d02d..ad43c9d 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_inventory.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_inventory.xml | |||
@@ -88,6 +88,14 @@ | |||
88 | mouse_opaque="true" name="New Underpants" width="128"> | 88 | mouse_opaque="true" name="New Underpants" width="128"> |
89 | <on_click filter="" function="Inventory.DoCreate" userdata="underpants" /> | 89 | <on_click filter="" function="Inventory.DoCreate" userdata="underpants" /> |
90 | </menu_item_call> | 90 | </menu_item_call> |
91 | <menu_item_call bottom_delta="-18" height="18" label="New Tattoo" left="0" | ||
92 | mouse_opaque="true" name="New Tattoo" width="128"> | ||
93 | <on_click filter="" function="Inventory.DoCreate" userdata="tattoo" /> | ||
94 | </menu_item_call> | ||
95 | <menu_item_call bottom_delta="-18" height="18" label="New Alpha" left="0" | ||
96 | mouse_opaque="true" name="New Alpha" width="128"> | ||
97 | <on_click filter="" function="Inventory.DoCreate" userdata="alpha" /> | ||
98 | </menu_item_call> | ||
91 | </menu> | 99 | </menu> |
92 | <menu bottom_delta="0" color="MenuDefaultBgColor" drop_shadow="true" height="175" left="0" | 100 | <menu bottom_delta="0" color="MenuDefaultBgColor" drop_shadow="true" height="175" left="0" |
93 | mouse_opaque="false" name="New Body Parts" opaque="true" tear_off="false" | 101 | mouse_opaque="false" name="New Body Parts" opaque="true" tear_off="false" |