From a37bff8bf1add5afe154b25156d7ebe38ff9af31 Mon Sep 17 00:00:00 2001
From: Graham Madarasz <graham@lindenlab.com>
Date: Tue, 14 May 2013 15:26:43 -0700
Subject: [PATCH] NORSPEC-103 reflect normal/spec UVs in face edit overlay
 display

---
 indra/newview/llface.cpp            |  4 +-
 indra/newview/llpanelface.cpp       | 19 ++++++-
 indra/newview/llselectmgr.cpp       | 77 ++++++++++++++++++++++----
 indra/newview/llselectmgr.h         |  8 ++-
 indra/newview/llviewershadermgr.cpp | 25 +++++++++
 indra/newview/llviewershadermgr.h   |  3 +
 indra/newview/pipeline.cpp          | 85 ++++++++++++++++++++++++++---
 indra/newview/pipeline.h            |  7 +++
 8 files changed, 207 insertions(+), 21 deletions(-)

diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 007ad1f8d9..eb78d42c35 100755
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -582,7 +582,9 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
 		}
 		else
 		{
-			mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
+			// cheaters sometimes prosper...
+			//
+			mVertexBuffer->setBuffer(mVertexBuffer->getTypeMask());
 			mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
 		}
 
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 9d0b9d0cac..f8c05bd007 100755
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1646,6 +1646,18 @@ void LLPanelFace::updateUI()
 					getChild<LLColorSwatchCtrl>("shinycolorswatch")->set(material->getSpecularLightColor(),TRUE);
 				}
 
+				// Update sel manager as to which channel we're editing so it can reflect the correct overlay UI
+				// NORSPEC-103
+				LLRender::eTexIndex channel_to_edit = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? (LLRender::eTexIndex)combobox_mattype->getCurrentIndex() : LLRender::DIFFUSE_MAP;
+
+				if ( ((channel_to_edit == LLRender::NORMAL_MAP) && material->getNormalID().isNull())
+					||((channel_to_edit == LLRender::SPECULAR_MAP) && material->getSpecularID().isNull()))
+				{
+					channel_to_edit = LLRender::DIFFUSE_MAP;
+				}
+
+				LLSelectMgr::getInstance()->setTextureChannel(channel_to_edit);
+
 				// Bumpy (normal)
 				texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
 				texture_ctrl->setImageAssetID(material->getNormalID());
@@ -1670,7 +1682,10 @@ void LLPanelFace::updateUI()
 				}
 				updateBumpyControls(!material->getNormalID().isNull(), true);
 			}
-
+			else
+			{
+				LLSelectMgr::getInstance()->setTextureChannel(LLRender::DIFFUSE_MAP);
+			}
 		}
 
 		// Set variable values for numeric expressions
@@ -1856,7 +1871,7 @@ void LLPanelFace::updateMaterial()
 		}
 		
 		LL_DEBUGS("Materials") << "Updating material: " << material->asLLSD() << LL_ENDL;
-
+		
 		LLSelectMgr::getInstance()->selectionSetMaterial( material );
 	}
 	else
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 3f60b5f642..7c9c935a1b 100755
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -188,6 +188,7 @@ LLSelectMgr::LLSelectMgr()
    mDebugSelectMgr(LLCachedControl<bool>(gSavedSettings, "DebugSelectMgr", FALSE))
 {
 	mTEMode = FALSE;
+	mTextureChannel = LLRender::DIFFUSE_MAP;
 	mLastCameraPos.clearVec();
 
 	sHighlightThickness	= gSavedSettings.getF32("SelectionHighlightThickness");
@@ -236,6 +237,8 @@ void LLSelectMgr::clearSelections()
 	mHighlightedObjects->deleteAllNodes();
 	mRectSelectedObjects.clear();
 	mGridObjects.deleteAllNodes();
+
+	LLPipeline::setRenderHighlightTextureChannel(LLRender::DIFFUSE_MAP);
 }
 
 void LLSelectMgr::update()
@@ -844,6 +847,10 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab
 	// check to see if object is already in list
 	LLSelectNode *nodep = mSelectedObjects->findNode(objectp);
 
+	// Reset (in anticipation of being set to an appropriate value by panel refresh, if they're up)
+	//
+	setTextureChannel(LLRender::DIFFUSE_MAP);
+
 	// if not in list, add it
 	if (!nodep)
 	{
@@ -4467,7 +4474,8 @@ void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type)
 	struct f : public LLSelectedNodeFunctor
 	{
 		EActionType mActionType;
-		f(EActionType a) : mActionType(a) {}
+		LLSelectMgr* mManager;
+		f(EActionType a, LLSelectMgr* p) : mActionType(a), mManager(p) {}
 		virtual bool apply(LLSelectNode* selectNode)
 		{
 			LLViewerObject*	object = selectNode->getObject();
@@ -4514,10 +4522,10 @@ void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type)
 			}
 		
 			selectNode->mSavedScale = object->getScale();
-			selectNode->saveTextureScaleRatios();
+			selectNode->saveTextureScaleRatios(mManager->mTextureChannel);			
 			return true;
 		}
-	} func(action_type);
+	} func(action_type, this);
 	getSelection()->applyToNodes(&func);	
 	
 	mSavedSelectionBBox = getBBoxOfSelection();
@@ -5828,23 +5836,72 @@ void LLSelectNode::saveTextures(const uuid_vec_t& textures)
 	}
 }
 
-void LLSelectNode::saveTextureScaleRatios()
+void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query)
 {
 	mTextureScaleRatios.clear();
 	if (mObject.notNull())
 	{
+		
+		LLVector3 scale = mObject->getScale();
+
 		for (U8 i = 0; i < mObject->getNumTEs(); i++)
 		{
-			F32 s,t;
+			F32 s = 1.0f;
+			F32 t = 1.0f;
+			
+			LLVector3 v;
+
 			const LLTextureEntry* tep = mObject->getTE(i);
-			tep->getScale(&s,&t);
-			U32 s_axis = 0;
-			U32 t_axis = 0;
+			if (!tep)
+				continue;
+
+			LLMaterialPtr mat = tep->getMaterialParams();
 
+			U32 s_axis = VX;
+			U32 t_axis = VY;
 			LLPrimitive::getTESTAxes(i, &s_axis, &t_axis);
 
-			LLVector3 v;
-			LLVector3 scale = mObject->getScale();
+			switch(index_to_query)
+			{
+				case LLRender::DIFFUSE_MAP:
+				{
+					tep->getScale(&s,&t);
+				}
+				break;
+
+				case LLRender::NORMAL_MAP:
+				{
+					if (mat)
+					{
+						mat->getNormalRepeat(s, t);
+					}
+					else
+					{
+						tep->getScale(&s,&t);
+					}
+									
+				}
+				break;
+
+				case LLRender::SPECULAR_MAP:
+				{
+					if (mat)
+					{
+						mat->getSpecularRepeat(s, t);
+					}
+					else
+					{
+						tep->getScale(&s,&t);
+					}
+				}
+				break;
+
+				default:
+					// should never be.
+					//
+					llassert_always(false);
+				break;
+			}
 
 			if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR)
 			{
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 1991b5581b..f9b97cebdd 100755
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -147,7 +147,7 @@ public:
 	// *NOTE: invalidate stored textures and colors when # faces change
 	void saveColors();
 	void saveTextures(const uuid_vec_t& textures);
-	void saveTextureScaleRatios();
+	void saveTextureScaleRatios(LLRender::eTexIndex index_to_query);
 
 	BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const;
 
@@ -514,6 +514,11 @@ public:
 	void saveSelectedObjectColors();
 	void saveSelectedObjectTextures();
 
+	// Sets which texture channel to query for scale and rot of display
+	// and depends on UI state of LLPanelFace when editing
+	void setTextureChannel(LLRender::eTexIndex texIndex) { mTextureChannel = texIndex; }
+	LLRender::eTexIndex getTextureChannel() { return mTextureChannel; }
+
 	void selectionUpdatePhysics(BOOL use_physics);
 	void selectionUpdateTemporary(BOOL is_temporary);
 	void selectionUpdatePhantom(BOOL is_ghost);
@@ -777,6 +782,7 @@ private:
 	EGridMode				mGridMode;
 
 	BOOL					mTEMode;			// render te
+	LLRender::eTexIndex	mTextureChannel; // diff, norm, or spec, depending on UI editing mode
 	LLVector3d				mSelectionCenterGlobal;
 	LLBBox					mSelectionBBox;
 
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index fce06b9e13..022ddb69ce 100755
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -143,6 +143,9 @@ LLGLSLShader		gUnderWaterProgram;
 
 //interface shaders
 LLGLSLShader		gHighlightProgram;
+LLGLSLShader		gHighlightNormalProgram;
+LLGLSLShader		gHighlightSpecularProgram;
+
 LLGLSLShader		gPathfindingProgram;
 LLGLSLShader		gPathfindingNoNormalsProgram;
 
@@ -752,6 +755,8 @@ void LLViewerShaderMgr::unloadShaders()
 	gAvatarEyeballProgram.unload();
 	gAvatarPickProgram.unload();
 	gHighlightProgram.unload();
+	gHighlightNormalProgram.unload();
+	gHighlightSpecularProgram.unload();
 
 	gWLSkyProgram.unload();
 	gWLCloudProgram.unload();
@@ -2703,6 +2708,26 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 		success = gHighlightProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gHighlightNormalProgram.mName = "Highlight Normals Shader";
+		gHighlightNormalProgram.mShaderFiles.clear();
+		gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER_ARB));
+		gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gHighlightNormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];		
+		success = gHighlightNormalProgram.createShader(NULL, NULL);
+	}
+
+	if (success)
+	{
+		gHighlightSpecularProgram.mName = "Highlight Spec Shader";
+		gHighlightSpecularProgram.mShaderFiles.clear();
+		gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER_ARB));
+		gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gHighlightSpecularProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];		
+		success = gHighlightSpecularProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gUIProgram.mName = "UI Shader";
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 5ef5d2234c..a24427a7bb 100755
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -301,6 +301,9 @@ extern LLGLSLShader			gGlowExtractProgram;
 
 //interface shaders
 extern LLGLSLShader			gHighlightProgram;
+extern LLGLSLShader			gHighlightNormalProgram;
+extern LLGLSLShader			gHighlightSpecularProgram;
+
 extern LLGLSLShader			gPathfindingProgram;
 extern LLGLSLShader			gPathfindingNoNormalsProgram;
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index f4b445c2eb..bcbd752550 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -354,6 +354,7 @@ BOOL	LLPipeline::sRenderParticleBeacons = FALSE;
 BOOL	LLPipeline::sRenderSoundBeacons = FALSE;
 BOOL	LLPipeline::sRenderBeacons = FALSE;
 BOOL	LLPipeline::sRenderHighlight = TRUE;
+LLRender::eTexIndex LLPipeline::sRenderHighlightTextureChannel = LLRender::DIFFUSE_MAP;
 BOOL	LLPipeline::sForceOldBakedUpload = FALSE;
 S32		LLPipeline::sUseOcclusion = 0;
 BOOL	LLPipeline::sDelayVBUpdate = TRUE;
@@ -3843,7 +3844,9 @@ void LLPipeline::postSort(LLCamera& camera)
 	if (!sShadowRender)
 	{
 		mSelectedFaces.clear();
-		
+
+		LLPipeline::setRenderHighlightTextureChannel(LLSelectMgr::getInstance()->getTextureChannel());
+
 		// Draw face highlights for selected faces.
 		if (LLSelectMgr::getInstance()->getTEMode())
 		{
@@ -4066,13 +4069,14 @@ void LLPipeline::renderHighlights()
 		gGL.diffuseColor4f(1,1,1,0.5f);
 	}
 	
-	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
+	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep)
+	{
+		mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
+	}
+
+	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP))
 	{
 		// Make sure the selection image gets downloaded and decoded
-		if (!mFaceSelectImagep)
-		{
-			mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
-		}
 		mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
 
 		U32 count = mSelectedFaces.size();
@@ -4088,7 +4092,7 @@ void LLPipeline::renderHighlights()
 			facep->renderSelected(mFaceSelectImagep, color);
 		}
 	}
-
+	
 	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
 	{
 		// Paint 'em red!
@@ -4110,6 +4114,67 @@ void LLPipeline::renderHighlights()
 	{
 		gHighlightProgram.unbind();
 	}
+
+
+	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP))
+	{
+		color.setVec(1.0f, 0.5f, 0.5f, 0.5f);
+		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+		{
+			gHighlightNormalProgram.bind();
+			gGL.diffuseColor4f(1,1,1,0.5f);
+		}
+
+		mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
+
+		U32 count = mSelectedFaces.size();
+		for (U32 i = 0; i < count; i++)
+		{
+			LLFace *facep = mSelectedFaces[i];
+			if (!facep || facep->getDrawable()->isDead())
+			{
+				llerrs << "Bad face on selection" << llendl;
+				return;
+			}
+
+			facep->renderSelected(mFaceSelectImagep, color);
+		}
+
+		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+		{
+			gHighlightNormalProgram.unbind();
+		}
+	}
+
+	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP))
+	{
+		color.setVec(0.0f, 0.3f, 1.0f, 0.8f);
+		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+		{
+			gHighlightSpecularProgram.bind();
+			gGL.diffuseColor4f(1,1,1,0.5f);
+		}
+
+		mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
+
+		U32 count = mSelectedFaces.size();
+		for (U32 i = 0; i < count; i++)
+		{
+			LLFace *facep = mSelectedFaces[i];
+			if (!facep || facep->getDrawable()->isDead())
+			{
+				llerrs << "Bad face on selection" << llendl;
+				return;
+			}
+
+			facep->renderSelected(mFaceSelectImagep, color);
+		}
+
+		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+		{
+			gHighlightSpecularProgram.unbind();
+		}
+	}
 }
 
 //debug use
@@ -6727,6 +6792,12 @@ BOOL LLPipeline::getRenderHighlights(void*)
 	return sRenderHighlight;
 }
 
+// static
+void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel)
+{
+	sRenderHighlightTextureChannel = channel;
+}
+
 LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,
 														BOOL pick_transparent,												
 														S32* face_hit,
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 9b7d1d642c..4aee8f14d6 100755
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -394,6 +394,7 @@ public:
 	static void setRenderHighlights(BOOL val);
 	static void toggleRenderHighlights(void* data);
 	static BOOL getRenderHighlights(void* data);
+	static void setRenderHighlightTextureChannel(LLRender::eTexIndex channel); // sets which UV setup to display in highlight overlay
 
 	static void updateRenderBump();
 	static void updateRenderDeferred();
@@ -401,6 +402,8 @@ public:
 
 	static void throttleNewMemoryAllocation(BOOL disable);
 
+	
+
 	void addDebugBlip(const LLVector3& position, const LLColor4& color);
 
 	void hidePermanentObjects( std::vector<U32>& restoreList );
@@ -847,6 +850,10 @@ public:
 	static BOOL				sRenderBeacons;
 	static BOOL				sRenderHighlight;
 
+	// Determines which set of UVs to use in highlight display
+	//
+	static LLRender::eTexIndex sRenderHighlightTextureChannel;
+
 	//debug use
 	static U32              sCurRenderPoolType ;
 
-- 
GitLab