aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--linden/indra/llinventory/llinventory.cpp2
-rw-r--r--linden/indra/llinventory/llinventorytype.h40
-rw-r--r--linden/indra/llinventory/llwearabletype.h4
-rw-r--r--linden/indra/llrender/llrender.cpp3
-rw-r--r--linden/indra/llrender/llrender.h1
-rw-r--r--linden/indra/newview/app_settings/settings.xml11
-rw-r--r--linden/indra/newview/llagent.cpp8
-rw-r--r--linden/indra/newview/llfloatercustomize.cpp278
-rw-r--r--linden/indra/newview/llinventoryactions.cpp10
-rw-r--r--linden/indra/newview/llinventorybridge.cpp12
-rw-r--r--linden/indra/newview/llinventorybridge.h4
-rw-r--r--linden/indra/newview/llinventoryview.cpp6
-rw-r--r--linden/indra/newview/lltexlayer.cpp651
-rw-r--r--linden/indra/newview/lltexlayer.h27
-rw-r--r--linden/indra/newview/lltexturectrl.cpp6
-rw-r--r--linden/indra/newview/llviewermenu.cpp16
-rw-r--r--linden/indra/newview/llvoavatar.cpp73
-rw-r--r--linden/indra/newview/llvoavatar.h6
-rw-r--r--linden/indra/newview/llvoavatardefines.cpp28
-rw-r--r--linden/indra/newview/llvoavatardefines.h11
-rw-r--r--linden/indra/newview/llwearable.cpp6
-rw-r--r--linden/indra/newview/rlvhandler.cpp2
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/floater_customize.xml168
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/floater_inventory.xml8
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/floater_new_outfit_dialog.xml10
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/menu_inventory.xml8
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
361struct LLSubpart 363struct 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
673bool 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
687void LLPanelEditWearable::addInvisibilityCheckbox(ETextureIndex te, const std::string& name)
688{
689 childSetCommitCallback(name, LLPanelEditWearable::onInvisibilityCommit, this);
690
691 mInvisibilityList[name] = te;
692}
693
694// static
695void 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
661void LLPanelEditWearable::addColorSwatch( ETextureIndex te, const std::string& name ) 737void 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
768void 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
777void 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
691void LLPanelEditWearable::addTextureDropTarget( ETextureIndex te, const std::string& name, 791void 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
1046void 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
935void LLPanelEditWearable::setWearable(LLWearable* wearable, U32 perm_mask, BOOL is_complete) 1065void 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
2205void LLFloaterCustomize::onTabPrecommit( void* userdata, bool from_click ) 2409void 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 )
2219void LLFloaterCustomize::onTabChanged( void* userdata, bool from_click ) 2424void 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
2225void LLFloaterCustomize::onClose(bool app_quitting) 2433void 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
2213void LLFolderBridge::createNewAlpha(void* user_data)
2214{
2215 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_ALPHA);
2216}
2217
2218void LLFolderBridge::createNewTattoo(void* user_data)
2219{
2220 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_TATTOO);
2221}
2222
2211void LLFolderBridge::createNewShape(void* user_data) 2223void 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
65S32 LLTexLayerSetBuffer::sGLByteCount = 0; 65S32 LLTexLayerSetBuffer::sGLByteCount = 0;
66S32 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//-----------------------------------------------------------------------------
95LLTexLayerSetBuffer::LLTexLayerSetBuffer( LLTexLayerSet* owner, S32 width, S32 height, BOOL has_bump ) 94LLTexLayerSetBuffer::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
111LLTexLayerSetBuffer::~LLTexLayerSetBuffer() 106LLTexLayerSetBuffer::~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
122void LLTexLayerSetBuffer::restoreGLTexture() 122void LLTexLayerSetBuffer::restoreGLTexture()
123{ 123{
124 createBumpTexture() ;
125 LLDynamicTexture::restoreGLTexture() ; 124 LLDynamicTexture::restoreGLTexture() ;
126} 125}
127 126
128//virtual 127//virtual
129void LLTexLayerSetBuffer::destroyGLTexture() 128void 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
141void 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
179void LLTexLayerSetBuffer::dumpTotalByteCount() 134void 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
185void LLTexLayerSetBuffer::requestUpdate() 139void LLTexLayerSetBuffer::requestUpdate()
@@ -233,8 +187,8 @@ void LLTexLayerSetBuffer::popProjection()
233BOOL LLTexLayerSetBuffer::needsRender() 187BOOL 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
273BOOL LLTexLayerSetBuffer::render() 227BOOL 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
363void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data) 300void 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
619void 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
728LLTexLayerSet::~LLTexLayerSet() 584LLTexLayerSet::~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
810BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) 681void 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
879BOOL LLTexLayerSet::renderBump( S32 x, S32 y, S32 width, S32 height ) 740BOOL 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
1009void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components) 910void 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
1254BOOL LLTexLayer::setInfo(LLTexLayerInfo* info) 1196BOOL 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
1439BOOL 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
1487U8* LLTexLayer::getAlphaData() 1482U8* 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
1815BOOL LLTexLayer::isVisibilityMask() const
1816{
1817 return mInfo->mIsVisibilityMask;
1818}
1819
1820BOOL 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:
205class LLTexLayerSetBuffer : public LLDynamicTexture 207class LLTexLayerSetBuffer : public LLDynamicTexture
206{ 208{
207public: 209public:
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
238private: 238private:
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//-----------------------------------------------------------------------------
255class LLTexLayerSet 252class LLTexLayerSet
256{ 253{
254 friend class LLTexLayerSetBuffer;
257public: 255public:
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
289public: 288public:
290 static BOOL sHasCaches; 289 static BOOL sHasCaches;
@@ -292,11 +291,14 @@ public:
292protected: 291protected:
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
352protected: 357protected:
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//-----------------------------------------------------------------------------
8265void LLVOAvatar::wearableUpdated( EWearableType type ) 8274void 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
828inline BOOL LLVOAvatar::isTextureVisible(U8 te) const 830inline 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
77typedef std::vector<ETextureIndex> texture_vec_t; 84typedef 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"