diff options
author | Brad Kittenbrink <brad@lindenlab.com> | 2022-06-27 10:24:53 -0700 |
---|---|---|
committer | Brad Kittenbrink <brad@lindenlab.com> | 2022-06-27 10:24:53 -0700 |
commit | acdd77d4ce31a5014eff72f18b374e877001adf9 (patch) | |
tree | 2345c2ac7b2e1c8c1b341ccf6ff1e65993d8dea3 /indra/newview | |
parent | fbb6eb216f5dc06ff5c7c1cabc6ab46a94918e1b (diff) | |
parent | 231c618a844cee26a3779b703c88d8807df872e6 (diff) |
Merge remote-tracking branch 'origin/DRTVWR-559' into brad/SL-17602-new-material-upload
Diffstat (limited to 'indra/newview')
19 files changed, 784 insertions, 156 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index d5b4e278bc..e4be88926f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -27,15 +27,24 @@ #define DEBUG_BASIC 0 #define DEBUG_VERTEX 0 -#define DEBUG_NORMAL 0 +#define DEBUG_NORMAL_RAW 0 // Output packed normal map "as is" to diffuse +#define DEBUG_NORMAL_OUT 0 // Output unpacked normal to diffuse #define DEBUG_POSITION 0 uniform sampler2D diffuseMap; //always in sRGB space +uniform float metallicFactor; +uniform float roughnessFactor; +uniform vec3 emissiveColor; + #ifdef HAS_NORMAL_MAP uniform sampler2D bumpMap; #endif +#ifdef HAS_EMISSIVE_MAP + uniform sampler2D emissiveMap; +#endif + #ifdef HAS_SPECULAR_MAP uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness #endif @@ -76,8 +85,6 @@ void main() // else vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb; - vec3 emissive = vec3(0); - #ifdef HAS_NORMAL_MAP vec4 norm = texture2D(bumpMap, vary_texcoord1.xy); norm.xyz = norm.xyz * 2 - 1; @@ -105,6 +112,14 @@ void main() vec3 spec = vec3(1,1,1); #endif + spec.g *= roughnessFactor; + spec.b *= metallicFactor; + + vec3 emissive = emissiveColor; +#ifdef HAS_EMISSIVE_MAP + emissive *= texture2D(emissiveMap, vary_texcoord0.xy).rgb; +#endif + #if DEBUG_BASIC col.rgb = vec3( 1, 0, 1 ); @@ -112,15 +127,18 @@ void main() #if DEBUG_VERTEX col.rgb = vertex_color.rgb; #endif -#if DEBUG_NORMAL +#if DEBUG_NORMAL_RAW + col.rgb = texture2D(bumpMap, vary_texcoord1.xy).rgb; +#endif +#if DEBUG_NORMAL_OUT col.rgb = vary_normal; #endif #if DEBUG_POSITION col.rgb = vary_position.xyz; #endif - frag_data[0] = vec4(col, 0.0); - frag_data[1] = vec4(spec.rgb, vertex_color.a); // Occlusion, Roughness, Metal - frag_data[2] = vec4(encode_normal(tnorm), vertex_color.a, GBUFFER_FLAG_HAS_PBR); // - frag_data[3] = vec4(emissive,0); // Emissive + frag_data[0] = vec4(col, 0.0); // Diffuse + frag_data[1] = vec4(spec.rgb, vertex_color.a); // Occlusion, Roughness, Metal + frag_data[2] = vec4(encode_normal(tnorm), vertex_color.a, GBUFFER_FLAG_HAS_PBR); // normal, environment intensity, flags + frag_data[3] = vec4(emissive,0); // Emissive } diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index f2ae699130..243f1c4498 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -27,23 +27,26 @@ #define DEBUG_PBR_PACKORM1 0 // Rough=1, Metal=1 #define DEBUG_PBR_TANGENT1 1 // Tangent = 1,0,0 -#define DEBUG_PBR_RAW_DIFF 0 // Output: use diffuse in G-Buffer -#define DEBUG_PBR_RAW_SPEC 0 // Output: use spec in G-Buffer -#define DEBUG_PBR_IRRADIANCE 0 // Output: Diffuse Irradiance -#define DEBUG_PBR_DIFFUSE 0 // Output: Radiance Lambertian -#define DEBUG_PBR_ORM 0 // Output: Packed Occlusion Roughness Metal -#define DEBUG_PBR_ROUGH 0 // Output: grayscale roughenss -#define DEBUG_PBR_METAL 0 // Output: grayscale metal -#define DEBUG_PBR_REFLECTANCE 0 // Output: diffuse reflectance -#define DEBUG_PBR_SPEC 0 // Output: Final spec -#define DEBUG_PBR_SPEC_REFLECTION 0 // Output: reflection -#define DEBUG_PBR_NORMAL 0 // Output: passed in normal -#define DEBUG_PBR_VIEW 0 // Output: view_dir -#define DEBUG_PBR_BRDF 0 // Output: Environment BRDF -#define DEBUG_PBR_DOT_NV 0 // Output: -#define DEBUG_PBR_DOT_TV 0 // Output: -#define DEBUG_PBR_DOT_BV 0 // Output: -#define DEBUG_PBR_FRESNEL 0 // Output: roughness dependent fresnel +#define DEBUG_PBR_RAW_DIFF 0 // Output: use diffuse in G-Buffer +#define DEBUG_PBR_RAW_SPEC 0 // Output: use spec in G-Buffer +#define DEBUG_PBR_IRRADIANCE 0 // Output: Diffuse Irradiance +#define DEBUG_PBR_DIFFUSE 0 // Output: Radiance Lambertian +#define DEBUG_PBR_ORM 0 // Output: Packed Occlusion Roughness Metal +#define DEBUG_PBR_ROUGH_PERCEPTUAL 0 // Output: grayscale Perceptual Roughenss +#define DEBUG_PBR_ROUGH_ALPHA 0 // Output: grayscale Alpha Roughness +#define DEBUG_PBR_METAL 0 // Output: grayscale metal +#define DEBUG_PBR_REFLECTANCE 0 // Output: diffuse reflectance +#define DEBUG_PBR_BRDF_UV 0 // Output: red green BRDF UV (GGX input) +#define DEBUG_PBR_BRDF_SCALE_BIAS 0 // Output: red green BRDF Scale Bias (GGX output) +#define DEBUG_PBR_SPEC 0 // Output: Final spec +#define DEBUG_PBR_SPEC_REFLECTION 0 // Output: reflection +#define DEBUG_PBR_NORMAL 0 // Output: passed in normal. To see raw normal map: set DEBUG_PBR_RAW_DIFF 1, and in pbropaqueF set DEBUG_NORMAL_RAW +#define DEBUG_PBR_VIEW 0 // Output: view_dir +#define DEBUG_PBR_BRDF 0 // Output: Environment BRDF +#define DEBUG_PBR_DOT_NV 0 // Output: grayscale dot(Normal,ViewDir) +#define DEBUG_PBR_DOT_TV 0 // Output: +#define DEBUG_PBR_DOT_BV 0 // Output: +#define DEBUG_PBR_FRESNEL 0 // Output: roughness dependent fresnel #extension GL_ARB_texture_rectangle : enable #extension GL_ARB_shader_texture_lod : enable @@ -254,8 +257,11 @@ void main() color.rgb = colorDiffuse + colorEmissive + colorSpec; - #if DEBUG_PBR_BRDF - color.rgb = vec3(vScaleBias,0); + #if DEBUG_PBR_BRDF_UV + color.rgb = vec3(brdfPoint,0.0); + #endif + #if DEBUG_PBR_BRDF_SCALE_BIAS + color.rgb = vec3(vScaleBias,0.0); #endif #if DEBUG_PBR_FRESNEL color.rgb = fresnelR; @@ -281,9 +287,12 @@ void main() #if DEBUG_PBR_METAL color.rgb = vec3(metal); #endif - #if DEBUG_PBR_ROUGH + #if DEBUG_PBR_ROUGH_PERCEPTUAL color.rgb = vec3(perceptualRough); #endif + #if DEBUG_PBR_ROUGH_ALPHA + color.rgb = vec3(alphaRough); + #endif #if DEBUG_PBR_SPEC color.rgb = colorSpec; #endif diff --git a/indra/newview/lldrawpoolpbropaque.cpp b/indra/newview/lldrawpoolpbropaque.cpp index 86b3ac0d46..0c257a33a5 100644 --- a/indra/newview/lldrawpoolpbropaque.cpp +++ b/indra/newview/lldrawpoolpbropaque.cpp @@ -99,30 +99,48 @@ void LLDrawPoolPBROpaque::renderDeferred(S32 pass) { LLDrawInfo& params = **i; -//gGL.getTexUnit(0)->activate(); + //gGL.getTexUnit(0)->activate(); - if (mShaderLevel > 1) + if (params.mTexture.notNull()) { - if (params.mTexture.notNull()) - { - gGL.getTexUnit(0)->bindFast(params.mTexture); // diffuse - } + gGL.getTexUnit(0)->bindFast(params.mTexture); // diffuse + } + else + { + gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sWhiteImagep); } if (params.mNormalMap) { gDeferredPBROpaqueProgram.bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap); } + else + { + // TODO: bind default normal map (???? WTF is it ???) + } if (params.mSpecularMap) { gDeferredPBROpaqueProgram.bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap); // Packed Occlusion Roughness Metal } + else + { + gDeferredPBROpaqueProgram.bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); + } + + if (params.mEmissiveMap) + { + gDeferredPBROpaqueProgram.bindTexture(LLShaderMgr::EMISSIVE_MAP, params.mEmissiveMap); // Packed Occlusion Roughness Metal + } + else + { + gDeferredPBROpaqueProgram.bindTexture(LLShaderMgr::EMISSIVE_MAP, LLViewerFetchedTexture::sWhiteImagep); + } + + gDeferredPBROpaqueProgram.uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, params.mGLTFMaterial->mRoughnessFactor); + gDeferredPBROpaqueProgram.uniform1f(LLShaderMgr::METALLIC_FACTOR, params.mGLTFMaterial->mMetallicFactor); + gDeferredPBROpaqueProgram.uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, params.mGLTFMaterial->mEmissiveColor.mV); - // Similar to LLDrawPooLMaterials::pushMaterialsBatch(params, getVertexDataMask(), false); LLRenderPass::pushBatch(params, getVertexDataMask(), FALSE, FALSE); - //LLRenderPass::applyModelMatrix(params); - //params.mVertexBuffer->setBufferFast(getVertexDataMask()); - //params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); } } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index d1ea5409ed..071e770811 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1384,6 +1384,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLColor4U color = tep->getColor(); + if (tep->getGLTFMaterial()) + { + color = tep->getGLTFMaterial()->mAlbedoColor; + } + if (rebuild_color) { //decide if shiny goes in alpha channel of color if (tep && diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 707ff2b7b6..f7dc493109 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -1306,6 +1306,18 @@ const std::string& LLInventoryFilter::getFilterText() filtered_by_all_types = FALSE; } + if (isFilterObjectTypesWith(LLInventoryType::IT_MATERIAL)) + { + filtered_types += LLTrans::getString("Materials"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + not_filtered_types += LLTrans::getString("Materials"); + filtered_by_all_types = FALSE; + } + if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD)) { filtered_types += LLTrans::getString("Notecards"); diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 44e493fdf4..e9b0e8404a 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -99,6 +99,8 @@ LLIconDictionary::LLIconDictionary() addEntry(LLInventoryType::ICONNAME_SETTINGS_DAY, new IconEntry("Inv_SettingsDay")); addEntry(LLInventoryType::ICONNAME_SETTINGS, new IconEntry("Inv_Settings")); + addEntry(LLInventoryType::ICONNAME_MATERIAL, new IconEntry("Inv_Material")); + addEntry(LLInventoryType::ICONNAME_INVALID, new IconEntry("Inv_Invalid")); addEntry(LLInventoryType::ICONNAME_UNKNOWN, new IconEntry("Inv_Unknown")); @@ -177,6 +179,9 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type, case LLAssetType::AT_SETTINGS: idx = assignSettingsIcon(misc_flag); break; + case LLAssetType::AT_MATERIAL: + idx = LLInventoryType::ICONNAME_MATERIAL; + break; case LLAssetType::AT_UNKNOWN: idx = LLInventoryType::ICONNAME_UNKNOWN; default: diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 828b368063..1744bf9033 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -29,17 +29,20 @@ #include "llmaterialeditor.h" #include "llagent.h" +#include "llappviewer.h" #include "llcombobox.h" #include "llinventorymodel.h" +#include "llnotificationsutil.h" +#include "lltexturectrl.h" +#include "lltrans.h" #include "llviewermenufile.h" -#include "llappviewer.h" #include "llviewertexture.h" -#include "llnotificationsutil.h" #include "llsdutil.h" #include "llselectmgr.h" #include "llviewerinventory.h" #include "llviewerregion.h" #include "llvovolume.h" +#include "llcolorswatch.h" #include "tinygltf/tiny_gltf.h" @@ -50,23 +53,84 @@ // Default constructor LLMaterialEditor::LLMaterialEditor(const LLSD& key) : LLFloater(key) + , mHasUnsavedChanges(false) { } BOOL LLMaterialEditor::postBuild() { + mAlbedoTextureCtrl = getChild<LLTextureCtrl>("albedo_texture"); + mMetallicTextureCtrl = getChild<LLTextureCtrl>("metallic_roughness_texture"); + mEmissiveTextureCtrl = getChild<LLTextureCtrl>("emissive_texture"); + mNormalTextureCtrl = getChild<LLTextureCtrl>("normal_texture"); + + mAlbedoTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitAlbedoTexture, this, _1, _2)); + mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitMetallicTexture, this, _1, _2)); + mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitEmissiveTexture, this, _1, _2)); + mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitNormalTexture, this, _1, _2)); + childSetAction("save", boost::bind(&LLMaterialEditor::onClickSave, this)); + childSetAction("save_as", boost::bind(&LLMaterialEditor::onClickSaveAs, this)); + childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this)); + + boost::function<void(LLUICtrl*, void*)> changes_callback = [this](LLUICtrl * ctrl, void*) { setHasUnsavedChanges(true); }; + + childSetCommitCallback("double sided", changes_callback, NULL); + + // Albedo + childSetCommitCallback("albedo color", changes_callback, NULL); + getChild<LLColorSwatchCtrl>("albedo color")->setCanApplyImmediately(TRUE); + childSetCommitCallback("transparency", changes_callback, NULL); + childSetCommitCallback("alpha mode", changes_callback, NULL); + childSetCommitCallback("alpha cutoff", changes_callback, NULL); + + // Metallic-Roughness + childSetCommitCallback("metalness factor", changes_callback, NULL); + childSetCommitCallback("roughness factor", changes_callback, NULL); + + // Metallic-Roughness + childSetCommitCallback("metalness factor", changes_callback, NULL); + childSetCommitCallback("roughness factor", changes_callback, NULL); + + // Emissive + childSetCommitCallback("emissive color", changes_callback, NULL); + getChild<LLColorSwatchCtrl>("emissive color")->setCanApplyImmediately(TRUE); + + childSetVisible("unsaved_changes", mHasUnsavedChanges); + return LLFloater::postBuild(); } +void LLMaterialEditor::onClickCloseBtn(bool app_quitting) +{ + if (app_quitting) + { + closeFloater(app_quitting); + } + else + { + onClickCancel(); + } +} + LLUUID LLMaterialEditor::getAlbedoId() { - return childGetValue("albedo texture").asUUID(); + return mAlbedoTextureCtrl->getValue().asUUID(); } void LLMaterialEditor::setAlbedoId(const LLUUID& id) { - childSetValue("albedo texture", id); + mAlbedoTextureCtrl->setValue(id); + mAlbedoTextureCtrl->setDefaultImageAssetID(id); + + if (id.notNull()) + { + // todo: this does not account for posibility of texture + // being from inventory, need to check that + childSetValue("albedo_upload_fee", getString("upload_fee_string")); + // Only set if we will need to upload this texture + mAlbedoTextureUploadId = id; + } } LLColor4 LLMaterialEditor::getAlbedoColor() @@ -76,7 +140,6 @@ LLColor4 LLMaterialEditor::getAlbedoColor() return ret; } - void LLMaterialEditor::setAlbedoColor(const LLColor4& color) { childSetValue("albedo color", color.getValue()); @@ -108,14 +171,29 @@ void LLMaterialEditor::setAlphaCutoff(F32 alpha_cutoff) childSetValue("alpha cutoff", alpha_cutoff); } +void LLMaterialEditor::setMaterialName(const std::string &name) +{ + setTitle(name); + mMaterialName = name; +} + LLUUID LLMaterialEditor::getMetallicRoughnessId() { - return childGetValue("metallic-roughness texture").asUUID(); + return mMetallicTextureCtrl->getValue().asUUID(); } void LLMaterialEditor::setMetallicRoughnessId(const LLUUID& id) { - childSetValue("metallic-roughness texture", id); + mMetallicTextureCtrl->setValue(id); + mMetallicTextureCtrl->setDefaultImageAssetID(id); + + if (id.notNull()) + { + // todo: this does not account for posibility of texture + // being from inventory, need to check that + childSetValue("metallic_upload_fee", getString("upload_fee_string")); + mMetallicTextureUploadId = id; + } } F32 LLMaterialEditor::getMetalnessFactor() @@ -140,12 +218,21 @@ void LLMaterialEditor::setRoughnessFactor(F32 factor) LLUUID LLMaterialEditor::getEmissiveId() { - return childGetValue("emissive texture").asUUID(); + return mEmissiveTextureCtrl->getValue().asUUID(); } void LLMaterialEditor::setEmissiveId(const LLUUID& id) { - childSetValue("emissive texture", id); + mEmissiveTextureCtrl->setValue(id); + mEmissiveTextureCtrl->setDefaultImageAssetID(id); + + if (id.notNull()) + { + // todo: this does not account for posibility of texture + // being from inventory, need to check that + childSetValue("emissive_upload_fee", getString("upload_fee_string")); + mEmissiveTextureUploadId = id; + } } LLColor4 LLMaterialEditor::getEmissiveColor() @@ -160,12 +247,21 @@ void LLMaterialEditor::setEmissiveColor(const LLColor4& color) LLUUID LLMaterialEditor::getNormalId() { - return childGetValue("normal texture").asUUID(); + return mNormalTextureCtrl->getValue().asUUID(); } void LLMaterialEditor::setNormalId(const LLUUID& id) { - childSetValue("normal texture", id); + mNormalTextureCtrl->setValue(id); + mNormalTextureCtrl->setDefaultImageAssetID(id); + + if (id.notNull()) + { + // todo: this does not account for posibility of texture + // being from inventory, need to check that + childSetValue("normal_upload_fee", getString("upload_fee_string")); + mNormalTextureUploadId = id; + } } bool LLMaterialEditor::getDoubleSided() @@ -178,6 +274,76 @@ void LLMaterialEditor::setDoubleSided(bool double_sided) childSetValue("double sided", double_sided); } +void LLMaterialEditor::setHasUnsavedChanges(bool value) +{ + if (value != mHasUnsavedChanges) + { + mHasUnsavedChanges = value; + childSetVisible("unsaved_changes", value); + } + + // HACK -- apply any changes to selection immediately + applyToSelection(); +} + +void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data) +{ + // might be better to use arrays, to have a single callback + // and not to repeat the same thing for each tecture control + LLUUID new_val = mAlbedoTextureCtrl->getValue().asUUID(); + if (new_val == mAlbedoTextureUploadId && mAlbedoTextureUploadId.notNull()) + { + childSetValue("albedo_upload_fee", getString("upload_fee_string")); + } + else + { + childSetValue("albedo_upload_fee", getString("no_upload_fee_string")); + } + setHasUnsavedChanges(true); +} + +void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & data) +{ + LLUUID new_val = mMetallicTextureCtrl->getValue().asUUID(); + if (new_val == mMetallicTextureUploadId && mMetallicTextureUploadId.notNull()) + { + childSetValue("metallic_upload_fee", getString("upload_fee_string")); + } + else + { + childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); + } + setHasUnsavedChanges(true); +} + +void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & data) +{ + LLUUID new_val = mEmissiveTextureCtrl->getValue().asUUID(); + if (new_val == mEmissiveTextureUploadId && mEmissiveTextureUploadId.notNull()) + { + childSetValue("emissive_upload_fee", getString("upload_fee_string")); + } + else + { + childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); + } + setHasUnsavedChanges(true); +} + +void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data) +{ + LLUUID new_val = mNormalTextureCtrl->getValue().asUUID(); + if (new_val == mNormalTextureUploadId && mNormalTextureUploadId.notNull()) + { + childSetValue("normal_upload_fee", getString("upload_fee_string")); + } + else + { + childSetValue("normal_upload_fee", getString("no_upload_fee_string")); + } + setHasUnsavedChanges(true); +} + static void write_color(const LLColor4& color, std::vector<double>& c) { @@ -272,7 +438,7 @@ void LLMaterialEditor::onClickSave() std::string dump = str.str(); - LL_INFOS() << dump << LL_ENDL; + LL_INFOS() << mMaterialName << ": " << dump << LL_ENDL; // gen a new uuid for this asset LLTransactionID tid; @@ -313,6 +479,54 @@ void LLMaterialEditor::onClickSave() ); } +void LLMaterialEditor::onClickSaveAs() +{ + LLSD args; + args["DESC"] = mMaterialName; + + LLNotificationsUtil::add("SaveMaterialAs", args, LLSD(), boost::bind(&LLMaterialEditor::onSaveAsMsgCallback, this, _1, _2)); +} + +void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + std::string new_name = response["message"].asString(); + LLStringUtil::trim(new_name); + if (!new_name.empty()) + { + setMaterialName(new_name); + onClickSave(); + } + else + { + LLNotificationsUtil::add("InvalidMaterialName"); + } + } +} + +void LLMaterialEditor::onClickCancel() +{ + if (mHasUnsavedChanges) + { + LLNotificationsUtil::add("UsavedMaterialChanges", LLSD(), LLSD(), boost::bind(&LLMaterialEditor::onCancelMsgCallback, this, _1, _2)); + } + else + { + closeFloater(); + } +} + +void LLMaterialEditor::onCancelMsgCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + closeFloater(); + } +} + class LLMaterialFilePicker : public LLFilePickerThread { public: @@ -358,28 +572,115 @@ const tinygltf::Image* get_image_from_texture_index(const tinygltf::Model& model return nullptr; } -static LLViewerFetchedTexture* get_texture(const std::string& folder, const tinygltf::Model& model, S32 texture_index) +static LLImageRaw* get_texture(const std::string& folder, const tinygltf::Model& model, S32 texture_index) { - LLViewerFetchedTexture* ret = nullptr; - const tinygltf::Image* image = get_image_from_texture_index(model, texture_index); + LLImageRaw* rawImage = nullptr; + if (image != nullptr && image->bits == 8 && !image->image.empty() && image->component <= 4) { - LLPointer<LLImageRaw> rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component); + rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component); rawImage->verticalFlip(); - - ret = LLViewerTextureManager::getFetchedTexture(rawImage, FTType::FTT_LOCAL_FILE, true); + } + + return rawImage; +} - ret->forceToSaveRawImage(0, F32_MAX); +static void strip_alpha_channel(LLPointer<LLImageRaw>& img) +{ + if (img->getComponents() == 4) + { + LLImageRaw* tmp = new LLImageRaw(img->getWidth(), img->getHeight(), 3); + tmp->copyUnscaled4onto3(img); + img = tmp; } +} - // TODO: provide helpful error message if image fails to load +// copy red channel from src_img to dst_img +// PRECONDITIONS: +// dst_img must be 3 component +// src_img and dst_image must have the same dimensions +static void copy_red_channel(LLPointer<LLImageRaw>& src_img, LLPointer<LLImageRaw>& dst_img) +{ + llassert(src_img->getWidth() == dst_img->getWidth() && src_img->getHeight() == dst_img->getHeight()); + llassert(dst_img->getComponents() == 3); - return ret; + U32 pixel_count = dst_img->getWidth() * dst_img->getHeight(); + U8* src = src_img->getData(); + U8* dst = dst_img->getData(); + S8 src_components = src_img->getComponents(); + + for (U32 i = 0; i < pixel_count; ++i) + { + dst[i * 3] = src[i * src_components]; + } +} + +static void pack_textures(tinygltf::Model& model, tinygltf::Material& material, + LLPointer<LLImageRaw>& albedo_img, + LLPointer<LLImageRaw>& normal_img, + LLPointer<LLImageRaw>& mr_img, + LLPointer<LLImageRaw>& emissive_img, + LLPointer<LLImageRaw>& occlusion_img, + LLPointer<LLViewerFetchedTexture>& albedo_tex, + LLPointer<LLViewerFetchedTexture>& normal_tex, + LLPointer<LLViewerFetchedTexture>& mr_tex, + LLPointer<LLViewerFetchedTexture>& emissive_tex) +{ + // TODO: downscale if needed + if (albedo_img) + { + albedo_tex = LLViewerTextureManager::getFetchedTexture(albedo_img, FTType::FTT_LOCAL_FILE, true); + } + + if (normal_img) + { + strip_alpha_channel(normal_img); + normal_tex = LLViewerTextureManager::getFetchedTexture(normal_img, FTType::FTT_LOCAL_FILE, true); + } + + if (mr_img) + { + strip_alpha_channel(mr_img); + + if (occlusion_img && material.pbrMetallicRoughness.metallicRoughnessTexture.index != material.occlusionTexture.index) + { + // occlusion is a distinct texture from pbrMetallicRoughness + // pack into mr red channel + int occlusion_idx = material.occlusionTexture.index; + int mr_idx = material.pbrMetallicRoughness.metallicRoughnessTexture.index; + if (occlusion_idx != mr_idx) + { + //scale occlusion image to match resolution of mr image + occlusion_img->scale(mr_img->getWidth(), mr_img->getHeight()); + + copy_red_channel(occlusion_img, mr_img); + } + } + } + else if (occlusion_img) + { + //no mr but occlusion exists, make a white mr_img and copy occlusion red channel over + mr_img = new LLImageRaw(occlusion_img->getWidth(), occlusion_img->getHeight(), 3); + mr_img->clear(255, 255, 255); + copy_red_channel(occlusion_img, mr_img); + + } + + if (mr_img) + { + mr_tex = LLViewerTextureManager::getFetchedTexture(mr_img, FTType::FTT_LOCAL_FILE, true); + } + + if (emissive_img) + { + strip_alpha_channel(emissive_img); + emissive_tex = LLViewerTextureManager::getFetchedTexture(emissive_img, FTType::FTT_LOCAL_FILE, true); + } } static LLColor4 get_color(const std::vector<double>& in) @@ -423,13 +724,14 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) if (!loaded) { - // TODO: show error_msg to user + LLNotificationsUtil::add("CannotUploadMaterial"); return; } if (model_in.materials.empty()) { - // TODO: show error message that materials are missing + // materials are missing + LLNotificationsUtil::add("CannotUploadMaterial"); return; } @@ -443,41 +745,56 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) model_out.materials.resize(1); // get albedo texture - LLPointer<LLViewerFetchedTexture> albedo_tex = get_texture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index); + LLPointer<LLImageRaw> albedo_img = get_texture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index); + // get normal map + LLPointer<LLImageRaw> normal_img = get_texture(folder, model_in, material_in.normalTexture.index); + // get metallic-roughness texture + LLPointer<LLImageRaw> mr_img = get_texture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index); + // get emissive texture + LLPointer<LLImageRaw> emissive_img = get_texture(folder, model_in, material_in.emissiveTexture.index); + // get occlusion map if needed + LLPointer<LLImageRaw> occlusion_img; + if (material_in.occlusionTexture.index != material_in.pbrMetallicRoughness.metallicRoughnessTexture.index) + { + occlusion_img = get_texture(folder, model_in, material_in.occlusionTexture.index); + } + LLPointer<LLViewerFetchedTexture> albedo_tex; + LLPointer<LLViewerFetchedTexture> normal_tex; + LLPointer<LLViewerFetchedTexture> mr_tex; + LLPointer<LLViewerFetchedTexture> emissive_tex; + + pack_textures(model_in, material_in, albedo_img, normal_img, mr_img, emissive_img, occlusion_img, + albedo_tex, normal_tex, mr_tex, emissive_tex); + LLUUID albedo_id; if (albedo_tex != nullptr) { + albedo_tex->forceToSaveRawImage(0, F32_MAX); albedo_id = albedo_tex->getID(); } - // get metallic-roughness texture - LLPointer<LLViewerFetchedTexture> mr_tex = get_texture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index); + LLUUID normal_id; + if (normal_tex != nullptr) + { + normal_tex->forceToSaveRawImage(0, F32_MAX); + normal_id = normal_tex->getID(); + } LLUUID mr_id; if (mr_tex != nullptr) { + mr_tex->forceToSaveRawImage(0, F32_MAX); mr_id = mr_tex->getID(); } - // get emissive texture - LLPointer<LLViewerFetchedTexture> emissive_tex = get_texture(folder, model_in, material_in.emissiveTexture.index); - LLUUID emissive_id; if (emissive_tex != nullptr) { + emissive_tex->forceToSaveRawImage(0, F32_MAX); emissive_id = emissive_tex->getID(); } - // get normal map - LLPointer<LLViewerFetchedTexture> normal_tex = get_texture(folder, model_in, material_in.normalTexture.index); - - LLUUID normal_id; - if (normal_tex != nullptr) - { - normal_id = normal_tex->getID(); - } - mME->setAlbedoId(albedo_id); mME->setMetallicRoughnessId(mr_id); mME->setEmissiveId(emissive_id); @@ -491,9 +808,13 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) mME->setMetalnessFactor(material_in.pbrMetallicRoughness.metallicFactor); mME->setRoughnessFactor(material_in.pbrMetallicRoughness.roughnessFactor); - + mME->setDoubleSided(material_in.doubleSided); + std::string new_material = LLTrans::getString("New Material"); + mME->setMaterialName(new_material); + + mME->setHasUnsavedChanges(true); mME->openFloater(); mME->applyToSelection(); diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index e773ecd169..7f9c6c0b63 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -28,6 +28,8 @@ #include "llfloater.h" +class LLTextureCtrl; + class LLMaterialEditor : public LLFloater { public: @@ -40,9 +42,14 @@ public: void applyToSelection(); void onClickSave(); + void onClickSaveAs(); + void onSaveAsMsgCallback(const LLSD& notification, const LLSD& response); + void onClickCancel(); + void onCancelMsgCallback(const LLSD& notification, const LLSD& response); // llpanel BOOL postBuild() override; + void onClickCloseBtn(bool app_quitting = false) override; LLUUID getAlbedoId(); void setAlbedoId(const LLUUID& id); @@ -59,6 +66,8 @@ public: F32 getAlphaCutoff(); void setAlphaCutoff(F32 alpha_cutoff); + + void setMaterialName(const std::string &name); LLUUID getMetallicRoughnessId(); void setMetallicRoughnessId(const LLUUID& id); @@ -80,5 +89,27 @@ public: bool getDoubleSided(); void setDoubleSided(bool double_sided); + + void setHasUnsavedChanges(bool value); + + void onCommitAlbedoTexture(LLUICtrl* ctrl, const LLSD& data); + void onCommitMetallicTexture(LLUICtrl* ctrl, const LLSD& data); + void onCommitEmissiveTexture(LLUICtrl* ctrl, const LLSD& data); + void onCommitNormalTexture(LLUICtrl* ctrl, const LLSD& data); + +private: + LLTextureCtrl* mAlbedoTextureCtrl; + LLTextureCtrl* mMetallicTextureCtrl; + LLTextureCtrl* mEmissiveTextureCtrl; + LLTextureCtrl* mNormalTextureCtrl; + + // 'Default' texture, unless it's null or from inventory is the one with the fee + LLUUID mAlbedoTextureUploadId; + LLUUID mMetallicTextureUploadId; + LLUUID mEmissiveTextureUploadId; + LLUUID mNormalTextureUploadId; + + bool mHasUnsavedChanges; + std::string mMaterialName; }; diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 89256b40c4..49562da3f7 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -919,6 +919,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter() getChild<LLUICtrl>("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE)); getChild<LLUICtrl>("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE)); getChild<LLUICtrl>("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK)); + getChild<LLUICtrl>("check_material")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MATERIAL)); getChild<LLUICtrl>("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD)); getChild<LLUICtrl>("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT)); getChild<LLUICtrl>("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL)); @@ -975,6 +976,12 @@ void LLFloaterInventoryFinder::draw() filtered_by_all_types = FALSE; } + if (!getChild<LLUICtrl>("check_material")->getValue()) + { + filter &= ~(0x1 << LLInventoryType::IT_MATERIAL); + filtered_by_all_types = FALSE; + } + if (!getChild<LLUICtrl>("check_notecard")->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_NOTECARD); @@ -1129,6 +1136,7 @@ void LLFloaterInventoryFinder::selectAllTypes(void* user_data) self->getChild<LLUICtrl>("check_clothing")->setValue(TRUE); self->getChild<LLUICtrl>("check_gesture")->setValue(TRUE); self->getChild<LLUICtrl>("check_landmark")->setValue(TRUE); + self->getChild<LLUICtrl>("check_material")->setValue(TRUE); self->getChild<LLUICtrl>("check_notecard")->setValue(TRUE); self->getChild<LLUICtrl>("check_object")->setValue(TRUE); self->getChild<LLUICtrl>("check_script")->setValue(TRUE); @@ -1149,6 +1157,7 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data) self->getChild<LLUICtrl>("check_clothing")->setValue(FALSE); self->getChild<LLUICtrl>("check_gesture")->setValue(FALSE); self->getChild<LLUICtrl>("check_landmark")->setValue(FALSE); + self->getChild<LLUICtrl>("check_material")->setValue(FALSE); self->getChild<LLUICtrl>("check_notecard")->setValue(FALSE); self->getChild<LLUICtrl>("check_object")->setValue(FALSE); self->getChild<LLUICtrl>("check_script")->setValue(FALSE); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 1c4a56b549..b761f34790 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -193,10 +193,8 @@ void LLFloaterTexturePicker::setActive( BOOL active ) void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b) { mCanApplyImmediately = b; - if (!mCanApplyImmediately) - { - getChild<LLUICtrl>("apply_immediate_check")->setValue(FALSE); - } + + getChild<LLUICtrl>("apply_immediate_check")->setValue(mCanApplyImmediately); updateFilterPermMask(); } @@ -413,11 +411,7 @@ BOOL LLFloaterTexturePicker::postBuild() getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("TextureLivePreview")); childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this); - - if (!mCanApplyImmediately) - { - getChildView("show_folders_check")->setEnabled(FALSE); - } + getChildView("apply_immediate_check")->setEnabled(mCanApplyImmediately); getChild<LLUICtrl>("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this)); childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this); @@ -483,7 +477,7 @@ void LLFloaterTexturePicker::draw() } getChildView("Default")->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative); - getChildView("Blank")->setEnabled(mImageAssetID != mBlankImageAssetID || mTentative); + getChildView("Blank")->setEnabled((mImageAssetID != mBlankImageAssetID && mBlankImageAssetID != mDefaultImageAssetID) || mTentative); getChildView("None")->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative)); LLFloater::draw(); @@ -1146,7 +1140,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) mOnCloseCallback(NULL), mOnSelectCallback(NULL), mBorderColor( p.border_color() ), - mAllowNoTexture( FALSE ), + mAllowNoTexture( p.allow_no_texture ), mAllowLocalTexture( TRUE ), mImmediateFilterPermMask( PERM_NONE ), mNonImmediateFilterPermMask( PERM_NONE ), diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 92f6f89af6..1475c8c6fc 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -91,7 +91,7 @@ public: : image_id("image"), default_image_id("default_image_id"), default_image_name("default_image_name"), - allow_no_texture("allow_no_texture"), + allow_no_texture("allow_no_texture", false), can_apply_immediately("can_apply_immediately"), no_commit_on_selection("no_commit_on_selection", false), label_width("label_width", -1), diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 49eba9856c..e76f0b36ee 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -1650,6 +1650,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredPBROpaqueProgram.addPermutation("HAS_NORMAL_MAP", "1"); gDeferredPBROpaqueProgram.addPermutation("HAS_SPECULAR_MAP", "1"); + gDeferredPBROpaqueProgram.addPermutation("HAS_EMISSIVE_MAP", "1"); gDeferredPBROpaqueProgram.addPermutation("DIFFUSE_ALPHA_MODE", "0"); success = make_rigged_variant(gDeferredPBROpaqueProgram, gDeferredSkinnedPBROpaqueProgram); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 82a5b28576..ac9c385405 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -372,8 +372,12 @@ void validate_framebuffer_object(); // for_impostor -- whether or not these render targets are for an impostor (if true, avoids implicit sRGB conversions) bool addDeferredAttachments(LLRenderTarget& target, bool for_impostor = false) { - return target.addColorAttachment(for_impostor ? GL_RGBA : GL_SRGB8_ALPHA8) && //specular - target.addColorAttachment(GL_RGB10_A2); //normal+z + bool pbr = gSavedSettings.getBOOL("RenderPBR"); + bool valid = true + && target.addColorAttachment(for_impostor ? GL_RGBA : GL_SRGB8_ALPHA8) // frag-data[1] specular or PBR packed OcclusionRoughnessMetal + && target.addColorAttachment(GL_RGB10_A2) // frag_data[2] normal+z+fogmask, See: class1\deferred\materialF.glsl & softenlight + && (pbr ? target.addColorAttachment(GL_RGBA) : true); // frag_data[3] emissive + return valid; } LLPipeline::LLPipeline() : diff --git a/indra/newview/skins/default/textures/icons/Inv_Material.png b/indra/newview/skins/default/textures/icons/Inv_Material.png Binary files differnew file mode 100644 index 0000000000..f5918ceaed --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Material.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index a36b859b6c..b0ae5fe447 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -303,6 +303,7 @@ with the same filename but different name <texture name="Inv_LostClosed" file_name="icons/Inv_LostClosed.png" preload="false" /> <texture name="Inv_LostOpen" file_name="icons/Inv_LostOpen.png" preload="false" /> <texture name="Inv_Landmark" file_name="icons/Inv_Landmark.png" preload="false" /> + <texture name="Inv_Material" file_name="icons/Inv_Material.png" preload="false" /> <texture name="Inv_Mesh" file_name="icons/Inv_Mesh.png" preload="false" /> <texture name="Inv_Notecard" file_name="icons/Inv_Notecard.png" preload="false" /> <texture name="Inv_Object" file_name="icons/Inv_Object.png" preload="false" /> diff --git a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml index d783d1e23c..e91efb89b2 100644 --- a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml @@ -2,7 +2,7 @@ <floater legacy_header_height="18" can_minimize="false" - height="466" + height="486" layout="topleft" name="Inventory Finder" help_topic="inventory_finder" @@ -95,12 +95,29 @@ width="126" /> <icon height="16" + image_name="Inv_Material" + layout="topleft" + left="8" + mouse_opaque="true" + name="icon_material" + top="122" + width="16" /> + <check_box + height="16" + label="Materials" + layout="topleft" + left_pad="2" + name="check_material" + top_delta="0" + width="126" /> + <icon + height="16" image_name="Inv_Notecard" layout="topleft" left="8" mouse_opaque="true" name="icon_notecard" - top="122" + top="142" width="16" /> <check_box height="16" @@ -117,7 +134,7 @@ left="8" mouse_opaque="true" name="icon_object" - top="142" + top="162" width="16" /> <check_box height="16" @@ -134,7 +151,7 @@ left="8" mouse_opaque="true" name="icon_script" - top="162" + top="182" width="16" /> <check_box height="16" @@ -151,7 +168,7 @@ left="8" mouse_opaque="true" name="icon_sound" - top="182" + top="202" width="16" /> <check_box height="16" @@ -168,7 +185,7 @@ left="8" mouse_opaque="true" name="icon_texture" - top="202" + top="222" width="16" /> <check_box height="16" @@ -185,7 +202,7 @@ left="8" mouse_opaque="true" name="icon_snapshot" - top="222" + top="242" width="16" /> <check_box height="16" @@ -202,7 +219,7 @@ left="8" mouse_opaque="true" name="icon_settings" - top="242" + top="262" width="16" /> <check_box height="16" @@ -220,7 +237,7 @@ layout="topleft" left="8" name="All" - top="262" + top="282" width="100" /> <button height="20" @@ -274,7 +291,7 @@ width="260"/> <check_box height="16" - top="352" + top="372" label="Since Logoff" layout="topleft" left_delta="0" @@ -290,7 +307,7 @@ layout="topleft" left_delta="0" name="- OR -" - top="370" + top="390" width="144"> - OR - </text> @@ -298,7 +315,7 @@ height="16" layout="topleft" name="date_search_direction" - top="388" + top="408" left="8" width="270"> <radio_item @@ -368,6 +385,6 @@ layout="topleft" name="Close" right="-6" - top="434" + top="454" width="76" /> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_material_editor.xml b/indra/newview/skins/default/xui/en/floater_material_editor.xml index 5d72e6f79d..36315d3b04 100644 --- a/indra/newview/skins/default/xui/en/floater_material_editor.xml +++ b/indra/newview/skins/default/xui/en/floater_material_editor.xml @@ -3,12 +3,22 @@ legacy_header_height="18" can_resize="false" default_tab_group="1" - height="777" + height="887" layout="topleft" name="material editor" help_topic="material_editor" - title="Material: [MATERIAL_NAME]" + title="[MATERIAL_NAME]" width="256"> + <string name="no_upload_fee_string">no upload fee</string> + <string name="upload_fee_string">L$10 upload fee</string> + <check_box + follows="left|top" + label="Double Sided" + left="14" + top="14" + name="double sided" + height="25" + width="120" /> <panel border="true" follows="left|top" @@ -17,11 +27,12 @@ layout="topleft" left="5" mouse_opaque="false" - name="Texture" - top="20" + name="albedo_texture_pnl" + top_pad="5" > <text type="string" + font.style="BOLD" length="1" follows="left|top" height="10" @@ -31,18 +42,33 @@ width="64"> Albedo: </text> - <texture_picker - can_apply_immediately="true" + <texture_picker + can_apply_immediately="false" default_image_name="Default" fallback_image="materials_ui_x_24.png" + allow_no_texture="true" follows="left|top" top_pad="8" height="151" layout="topleft" left="10" - name="albedo texture" + name="albedo_texture" tool_tip="Albedo map. Alpha channel is optional and used for transparency." width="128" /> + <text + type="string" + font.style="BOLD" + length="1" + follows="left|top" + height="10" + width="128" + layout="topleft" + left="10" + top_pad="-17" + name="albedo_upload_fee" + > + No upload fee + </text> <text type="string" length="1" @@ -50,12 +76,12 @@ height="10" layout="topleft" left_pad="5" - top_delta="-15" + top="8" > Tint </text> <color_swatch - can_apply_immediately="true" + can_apply_immediately="false" follows="left|top" height="40" label_height="0" @@ -152,45 +178,61 @@ border="true" follows="left|top" width="246" - height="160" + height="175" layout="topleft" left="5" mouse_opaque="false" - name="Texture" + name="metallic_texture_pnl" top_pad="5" > <text type="string" + font.style="BOLD" length="1" follows="left|top" height="10" layout="topleft" left="10" - top_pad="5" + top="5" > Metallic-Roughness: </text> - <texture_picker - can_apply_immediately="true" + <texture_picker + can_apply_immediately="false" default_image_name="Default" fallback_image="materials_ui_x_24.png" + allow_no_texture="true" follows="left|top" width="128" height="151" layout="topleft" left="10" - name="metallic-roughness texture" + name="metallic_roughness_texture" tool_tip="GLTF metallic-roughness map with optional occlusion. Red channel is occlusion, green channel is roughness, blue channel is metalness." top_pad="8" /> <text type="string" + font.style="BOLD" + length="1" + follows="left|top" + height="10" + width="128" + layout="topleft" + left="10" + top_pad="-17" + name="metallic_upload_fee" + > + No upload fee + </text> + <text + type="string" length="1" follows="left|top" height="10" layout="topleft" left_pad="5" - top_delta="-15" + top="8" > Metallic Factor </text> @@ -237,15 +279,16 @@ border="true" follows="left|top" width="246" - height="160" + height="175" layout="topleft" left="5" mouse_opaque="false" - name="Texture" + name="emissive_texture_pnl" top_pad="5" > <text type="string" + font.style="BOLD" length="1" follows="left|top" height="10" @@ -256,29 +299,44 @@ Emissive: </text> <texture_picker - can_apply_immediately="true" + can_apply_immediately="false" default_image_name="Default" fallback_image="materials_ui_x_24.png" + allow_no_texture="true" follows="left|top" top_pad="8" height="151" layout="topleft" left="10" - name="emissive texture" + name="emissive_texture" width="128" /> <text type="string" + font.style="BOLD" + length="1" + follows="left|top" + height="10" + width="128" + layout="topleft" + left="10" + top_pad="-17" + name="emissive_upload_fee" + > + No upload fee + </text> + <text + type="string" length="1" follows="left|top" height="10" layout="topleft" left_pad="5" - top_delta="-15" + top="8" > Tint </text> <color_swatch - can_apply_immediately="true" + can_apply_immediately="false" follows="left|top" height="40" label_height="0" @@ -316,14 +374,16 @@ border="true" follows="left|top" width="246" - height="160" + height="175" layout="topleft" left="5" mouse_opaque="false" top_pad="5" + name="normal_texture_pnl" > <text type="string" + font.style="BOLD" length="1" follows="left|top" height="10" @@ -334,41 +394,106 @@ Normal: </text> <texture_picker - can_apply_immediately="true" + can_apply_immediately="false" default_image_name="Default" fallback_image="materials_ui_x_24.png" + allow_no_texture="true" follows="left|top" top_pad="8" height="151" layout="topleft" left="10" - name="normal texture" + name="normal_texture" width="128" /> - <!--<check_box - follows="left|top" - label="Mikkt Space" - left_pad="10" - top_delta="0" - height="25" - width="120" />--> + <text + type="string" + font.style="BOLD" + length="1" + follows="left|top" + height="10" + width="128" + layout="topleft" + left="10" + top_pad="-17" + name="normal_upload_fee" + > + No upload fee + </text> + </panel> + + <panel + follows="right|bottom" + width="246" + height="97" + layout="bottomright" + top_delta="-2" + left="5" + name="button_panel" + > + <text + type="string" + name="unsaved_changes" + font.style="BOLD" + text_color="DrYellow" + length="1" + follows="left|top" + height="10" + width="200" + layout="topleft" + left="10" + top="0" + > + Usaved changes + </text> + <button + follows="left|top" + height="25" + label="Save" + layout="topleft" + name="save" + top_pad="7" + left="0" + width="120" /> + <button + follows="left|top" + height="25" + label="Save As..." + layout="topleft" + name="save_as" + top_delta="0" + left_pad="6" + width="120" /> + <text + type="string" + font.style="BOLD" + length="1" + follows="left|top" + height="10" + width="220" + layout="topleft" + left="10" + top_pad="5" + > + Total upload fee: L$ [FEE] + </text> + + <view_border + bevel_style="none" + height="0" + layout="topleft" + left="0" + name="button_border" + top_pad="7" + width="246"/> + + <button + follows="left|top" + height="25" + label="Cancel" + layout="topleft" + name="cancel" + top_pad="7" + left="61" + width="121" /> </panel> - <check_box - follows="left|top" - label="Double Sided" - left="5" - top_pad="5" - name="double sided" - height="25" - width="120" /> - <button - follows="right|bottom" - height="25" - label="Save" - layout="bottomright" - name="save" - tool_tip="Browse for an editor (executable) to edit floater XML files" - top_delta="-2" - left="5" - width="246" /> - </floater> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 786cf32e7a..0ca3e043e7 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -9025,7 +9025,64 @@ Unable to upload texture. [REASON] <tag>fail</tag> </notification> - + + <notification + icon="alertmodal.tga" + name="CannotUploadMaterial" + type="alertmodal"> +There was a problem uploading the file + <tag>fail</tag> + </notification> + + <notification + icon="alertmodal.tga" + label="Save Material" + name="SaveMaterialAs" + type="alertmodal"> + <unique/> + Name this material: + <tag>confirm</tag> + <form name="form"> + <input name="message" type="text"> + [DESC] + </input> + <button + default="true" + index="0" + name="OK" + text="OK"/> + <button + index="1" + name="Cancel" + text="Cancel"/> + </form> + </notification> + + <notification + icon="alertmodal.tga" + name="InvalidMaterialName" + type="alertmodal"> +Please enter a non-empty name + <tag>fail</tag> + </notification> + + <notification + icon="alertmodal.tga" + name="UsavedMaterialChanges" + type="alertmodal"> + You have unsaved changes. + <form name="form"> + <button + index="0" + name="discard" + text="Discard changes"/> + <button + index="1" + name="keep" + text="Keep editing"/> + </form> + </notification> + <notification icon="alertmodal.tga" name="LivePreviewUnavailable" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 0866f29355..e1678f418f 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2414,6 +2414,7 @@ If you continue to receive this message, please contact Second Life support for <string name="Clothing" value=" Clothing," /> <string name="Gestures" value=" Gestures," /> <string name="Landmarks" value=" Landmarks," /> + <string name="Materials" value=" Materials," /> <string name="Notecards" value=" Notecards," /> <string name="Objects" value=" Objects," /> <string name="Scripts" value=" Scripts," /> |