summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/llassettype.cpp2
-rw-r--r--indra/llinventory/llinventorytype.cpp1
-rw-r--r--indra/llrender/llshadermgr.cpp6
-rw-r--r--indra/llrender/llshadermgr.h4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl34
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl49
-rw-r--r--indra/newview/lldrawpoolpbropaque.cpp38
-rw-r--r--indra/newview/llface.cpp5
-rw-r--r--indra/newview/llinventoryfilter.cpp12
-rw-r--r--indra/newview/llinventoryicon.cpp5
-rw-r--r--indra/newview/llmaterialeditor.cpp399
-rw-r--r--indra/newview/llmaterialeditor.h31
-rw-r--r--indra/newview/llpanelmaininventory.cpp9
-rw-r--r--indra/newview/lltexturectrl.cpp16
-rw-r--r--indra/newview/lltexturectrl.h2
-rw-r--r--indra/newview/llviewershadermgr.cpp1
-rw-r--r--indra/newview/pipeline.cpp8
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_Material.pngbin0 -> 684 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml43
-rw-r--r--indra/newview/skins/default/xui/en/floater_material_editor.xml227
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml59
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml1
23 files changed, 795 insertions, 158 deletions
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 0bb1f1a0fd..f08cc18036 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -96,7 +96,7 @@ LLAssetDictionary::LLAssetDictionary()
addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false));
addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false));
addEntry(LLAssetType::AT_SETTINGS, new AssetEntry("SETTINGS", "settings", "settings blob", true, true, true));
- addEntry(LLAssetType::AT_MATERIAL, new AssetEntry("MATERIAL", "material", "render material", true, true, true));
+ addEntry(LLAssetType::AT_MATERIAL, new AssetEntry("MATERIAL", "material", "render material", true, true, true));
addEntry(LLAssetType::AT_UNKNOWN, new AssetEntry("UNKNOWN", "invalid", NULL, false, false, false));
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp
index 57d521429c..ceda2f3caf 100644
--- a/indra/llinventory/llinventorytype.cpp
+++ b/indra/llinventory/llinventorytype.cpp
@@ -86,6 +86,7 @@ LLInventoryDictionary::LLInventoryDictionary()
addEntry(LLInventoryType::IT_WIDGET, new InventoryEntry("widget", "widget", 1, LLAssetType::AT_WIDGET));
addEntry(LLInventoryType::IT_PERSON, new InventoryEntry("person", "person", 1, LLAssetType::AT_PERSON));
addEntry(LLInventoryType::IT_SETTINGS, new InventoryEntry("settings", "settings", 1, LLAssetType::AT_SETTINGS));
+ addEntry(LLInventoryType::IT_MATERIAL, new InventoryEntry("material", "render material", 1, LLAssetType::AT_MATERIAL));
}
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 09d3f95736..896c4d2366 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1170,10 +1170,14 @@ void LLShaderMgr::initAttribsAndUniforms()
llassert(mReservedUniforms.size() == LLShaderMgr::PROJECTOR_AMBIENT_LOD+1);
mReservedUniforms.push_back("color");
-
+ mReservedUniforms.push_back("emissiveColor");
+ mReservedUniforms.push_back("metallicFactor");
+ mReservedUniforms.push_back("roughnessFactor");
+
mReservedUniforms.push_back("diffuseMap");
mReservedUniforms.push_back("altDiffuseMap");
mReservedUniforms.push_back("specularMap");
+ mReservedUniforms.push_back("emissiveMap");
mReservedUniforms.push_back("bumpMap");
mReservedUniforms.push_back("bumpMap2");
mReservedUniforms.push_back("environmentMap");
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 067df6fa04..3c68aa5e79 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -74,9 +74,13 @@ public:
PROJECTOR_LOD, // "proj_lod"
PROJECTOR_AMBIENT_LOD, // "proj_ambient_lod"
DIFFUSE_COLOR, // "color"
+ EMISSIVE_COLOR, // "emissiveColor"
+ METALLIC_FACTOR, // "metallicFactor"
+ ROUGHNESS_FACTOR, // "roughnessFactor"
DIFFUSE_MAP, // "diffuseMap"
ALTERNATE_DIFFUSE_MAP, // "altDiffuseMap"
SPECULAR_MAP, // "specularMap"
+ EMISSIVE_MAP, // "emissiveMap"
BUMP_MAP, // "bumpMap"
BUMP_MAP2, // "bumpMap2"
ENVIRONMENT_MAP, // "environmentMap"
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
new file mode 100644
index 0000000000..f5918ceaed
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_Material.png
Binary files differ
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," />