diff options
273 files changed, 13497 insertions, 4463 deletions
@@ -72,35 +72,35 @@ b53a0576eec80614d7767ed72b40ed67aeff27c9 DRTVWR-38_2.5.2-release  461c8c65b5c799ddfe365422f9be9c0095d91e7d 2.6.0-beta1-tip  9e4641f4a7870c0f565a25a2971368d5a29516a1 2.6.0-beta2  9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2 +42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release +42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release  c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1  c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start  c5bdef3aaa2744626aef3c217ce29e1900d357b3 DRTVWR-43_2.6.1-beta1 +c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release +c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release  56b2778c743c2a964d82e1caf11084d76a87de2c 2.6.2-start  d1203046bb653b763f835b04d184646949d8dd5c 2.6.2-beta1  d1203046bb653b763f835b04d184646949d8dd5c DRTVWR-45_2.6.2-beta1 -42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release -42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release -c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release -c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release +214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release +214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release  52b2263ab28f0976c689fd0b76c55a9eb027cdbf end-of-develop.py  ec32f1045e7c2644015245df3a9933620aa194b8 2.6.3-start  d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc 2.6.3-beta1  d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc DRTVWR-47_2.6.3-beta1  0630e977504af5ea320c58d33cae4e1ddee793e9 2.6.3-beta2  0630e977504af5ea320c58d33cae4e1ddee793e9 DRTVWR-48_2.6.3-beta2 +8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release +8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release  3178e311da3a8739a85363665006ea3c4610cad4 dons-headless-hackathon-work -214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release -214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release  7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd 2.6.5-beta1  7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd DRTVWR-50_2.6.5-beta1 -8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release -8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release  800cefce8d364ffdd2f383cbecb91294da3ea424 2.6.6-start  bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 2.6.6-beta1  bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 DRTVWR-52_2.6.6-beta1 -5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start  dac76a711da5f1489a01c1fa62ec97d99c25736d 2.6.6-release  dac76a711da5f1489a01c1fa62ec97d99c25736d DRTVWR-51_2.6.6-release +5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start  beafa8a9bd1d1b670b7523d865204dc4a4b38eef 2.6.8-beta1  beafa8a9bd1d1b670b7523d865204dc4a4b38eef DRTVWR-55_2.6.8-beta1  be2000b946f8cb3de5f44b2d419287d4c48ec4eb 2.6.8-release @@ -119,50 +119,50 @@ e67da2c6e3125966dd49eef98b36317afac1fcfe 2.6.9-start  9f79a6ed8fdcd2f3dac33ea6b3236eeb278dccfe 2.7.2-start  e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb 2.7.2-beta1  e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1 -6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start  fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.1-release  fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.2-release  fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release  fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-62_2.7.2-release +6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start  6af10678de4736222b2c3f7e010e984fb5b327de 2.7.4-start  be963a4eef635542f9617d7f5fd22ba48fb71958 2.7.4-beta1  be963a4eef635542f9617d7f5fd22ba48fb71958 DRTVWR-67_2.7.4-beta1 +057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release +057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release  19a498fa62570f352d7d246f17e3c81cc1d82d8b 2.7.5-start  09984bfa6cae17e0f72d02b75c1b7393c65eecfc 2.7.5-beta1  09984bfa6cae17e0f72d02b75c1b7393c65eecfc DRTVWR-69_2.7.5-beta1 +6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release +6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release  e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-beta1  e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-start  e1ed60913230dd64269a7f7fc52cbc6004f6d52c DRTVWR-71_2.8.0-beta1 -057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release -057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release -6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release -6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release +493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release +493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release  502f6a5deca9365ddae57db4f1e30172668e171e 2.8.1-start  2c7e459e0c883f8e406b932e41e60097e9ee077e 2.8.1-beta1  2c7e459e0c883f8e406b932e41e60097e9ee077e DRTVWR-73_2.8.1-beta1 -493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release -493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release -54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start -ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start  29e93d7e19991011bd12b5748142b11a5dcb4370 2.8.1-release  29e93d7e19991011bd12b5748142b11a5dcb4370 DRTVWR-72_2.8.1-release  4780e3bd2b3042f91be3426151f28c30d199bb3b 2.8.1-hotfix  4780e3bd2b3042f91be3426151f28c30d199bb3b DRTVWR-76_2.8.1-hotfix +54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start +ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start  599677276b227357140dda35bea4a2c18e2e67b5 2.8.3-beta1  599677276b227357140dda35bea4a2c18e2e67b5 DRTVWR-75_2.8.3-beta1 +fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release +fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release  6b678ea52f90d5c14181661dcd2546e25bde483e 3.0.0-start  b0be6ce3adfef3a014a2389d360539f8a86c5439 3.0.0-beta1  b0be6ce3adfef3a014a2389d360539f8a86c5439 DRTVWR-78_3.0.0-beta1 -fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release -fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release +1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release +1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release  82a2079ffcb57ecb1b3849cb41376b443e1eb912 3.0.1-start  364fd63517fbacbbcb9129d096187171ba8c9e48 3.0.1-beta1  364fd63517fbacbbcb9129d096187171ba8c9e48 DRTVWR-81_3.0.1-beta1  f2412ecd6740803ea9452f1d17fd872e263a0df7 3.0.2-start  42784bf50fa01974bada2a1af3892ee09c93fcda 3.0.2-beta1  42784bf50fa01974bada2a1af3892ee09c93fcda DRTVWR-83_3.0.2-beta1 -1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release -1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release  e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e 3.0.2-beta2  e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e DRTVWR-86_3.0.2-beta2  b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start @@ -170,9 +170,9 @@ b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start  6694f3f062aa45f64ab391d25a3eb3d5eb1b0871 DRTVWR-85_3.0.3-beta1  61aa7974df089e8621fe9a4c69bcdefdb3cc208a 3.0.3-beta2  61aa7974df089e8621fe9a4c69bcdefdb3cc208a DRTVWR-89_3.0.3-beta2 -586907287be581817b2422b5137971b22d54ea48 3.0.4-start  0496d2f74043cf4e6058e76ac3db03d44cff42ce 3.0.3-release  0496d2f74043cf4e6058e76ac3db03d44cff42ce DRTVWR-84_3.0.3-release +586907287be581817b2422b5137971b22d54ea48 3.0.4-start  92a3aa04775438226399b19deee12ac3b5a62838 3.0.5-start  c7282e59f374ee904bd793c3c444455e3399b0c5 3.1.0-start  2657fa785bbfac115852c41bd0adaff74c2ad5da 3.1.0-beta1 @@ -193,11 +193,11 @@ e440cd1dfbd128d7d5467019e497f7f803640ad6 DRTVWR-95_3.2.0-beta1  c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start  9e390d76807fa70d356b8716fb83b8ce42a629ef 3.2.1-beta1  9e390d76807fa70d356b8716fb83b8ce42a629ef DRTVWR-100_3.2.1-beta1 +a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release +a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release  40b46edba007d15d0059c80864b708b99c1da368 3.2.2-start  523df3e67378541498d516d52af4402176a26bac 3.2.2-beta1  523df3e67378541498d516d52af4402176a26bac DRTVWR-102_3.2.2-beta1 -a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release -a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release  80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start  3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-beta1  3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-start @@ -279,6 +279,10 @@ a8057e1b9a1246b434a27405be35e030f7d28b0c 3.3.4-beta3  9cd174d3a54d93d409a7c346a15b8bfb40fc58f4 DRTVWR-184  ab2ffc547c8a8950ff187c4f6c95e5334fab597b 3.3.4-beta5  28e100d0379a2b0710c57647a28fc5239d3d7b99 3.3.4-release +6dfb0fba782c9233dd95f24ec48146db0d3f210b DRTVWR-199 +7c9102fb998885621919f2474a002c35b583539b 3.3.4-release2 +8c9085066c78ed5f6c9379dc054c82a6fcdb1851 DRTVWR-207 +351eea5f9dc192fc5ddea3b02958de97677a0a12 3.3.4-release3  005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167  888768f162d2c0a8de1dcc5fb9a08bd8bd120a6b DRTVWR-175  a8b3eca451a9eaab59987efb0ab1c4217e3f2dcc DRTVWR-182 @@ -294,13 +298,9 @@ ae5c83dd61d2d37c45f1d5b8bf2b036d87599f1b DRTVWR-198  b1dbb1a83f48f93f6f878cff9e52d2cb635e145c 3.4.0-beta2  37402e2b19af970d51b0a814d79892cc5647532b DRTVWR-200  182a9bf30e81070361bb020a78003b1cf398e79c 3.4.0-beta3 -6dfb0fba782c9233dd95f24ec48146db0d3f210b DRTVWR-199 -7c9102fb998885621919f2474a002c35b583539b 3.3.4-release2  7649a3dff5ec22d3727377e5f02efd0f421e4cb5 DRTVWR-201  84fb70dfe3444e75a44fb4bee43e2fc8221cebdd 3.4.0-beta4  573e863be2f26d3687161def4b9fea9b7038dda8 3.4.0-beta5 -8c9085066c78ed5f6c9379dc054c82a6fcdb1851 DRTVWR-207 -351eea5f9dc192fc5ddea3b02958de97677a0a12 3.3.4-release3  af7b28e75bd5a629cd9e0dc46fb3f1757626f493 DRTVWR-212  015012c2b740ccdec8a8c3d6e5f898449ecfe0b8 DRTVWR-213  62b07aa81b1957897c3846292bb9412977b0af6c 3.3.4-beta6 @@ -457,3 +457,7 @@ a314f1c94374ab1f6633dd2983f7090a68663eb2 3.5.2-beta4  9013c07bfe1c51107233f1924dccdcc5057dd909 3.5.2-beta6  9b1b6f33aa5394b27bb652b31b5cb81ef6060370 3.5.2-release  a277b841729f2a62ba1e34acacc964bc13c1ad6f 3.5.3-release +fb1630153bac5552046ea914af3f14deabc1def8 3.6.0-materials-beta1 +69429d81ae4dd321eda2607901ef0a0fde71b54c 3.6.0-release +69429d81ae4dd321eda2607901ef0a0fde71b54c 3.6.0-release +0a56f33ad6aa112032b14a41dad759ad377bdde9 3.6.0-release diff --git a/BuildParams b/BuildParams index a4b361261f..84d30f651b 100755 --- a/BuildParams +++ b/BuildParams @@ -60,6 +60,7 @@ viewer-release.build_debug_release_separately = true  viewer-release.build_viewer_update_version_manager = true  viewer-release.codeticket_add_context = false +  # ========================================  # mesh-development  # ======================================== @@ -122,6 +123,14 @@ viewer-pathfinding.build_CYGWIN_Debug = false  viewer-pathfinding.build_viewer_update_version_manager = false  # ======================================== +# viewer-materials +# ======================================== + +viewer-materials.viewer_channel = "Second Life Beta Materials" +viewer-materials.build_debug_release_separately = true +viewer-materials.build_CYGWIN_Debug = false +viewer-materials.build_viewer_update_version_manager = false +  # viewer-chui  #  # ======================================== @@ -189,3 +198,5 @@ runway.build_viewer_update_version_manager = false  # eof + + diff --git a/NORSPEC-207.patch b/NORSPEC-207.patch new file mode 100644 index 0000000000..a1c1447bda --- /dev/null +++ b/NORSPEC-207.patch @@ -0,0 +1,164 @@ +diff -r fe4bab01522e indra/llprimitive/llrendermaterialtable.cpp +--- a/indra/llprimitive/llrendermaterialtable.cpp	Wed May 15 17:57:21 2013 +0000 ++++ b/indra/llprimitive/llrendermaterialtable.cpp	Wed May 22 14:23:04 2013 -0700 +@@ -184,6 +184,44 @@ + 	} + } +  ++// 'v' is an integer value for 100ths of radians (don't ask...) ++// ++void LLRenderMaterialEntry::LLRenderMaterial::setSpecularMapRotation(S32 v) const ++{ ++	// Store the fact that we're using the new rotation rep ++	// ++	m_flags |= kNewSpecularMapRotation; ++ ++	// Store 'sign bit' in our m_flags ++	// ++	m_flags &= ~kSpecularMapRotationNegative; ++	m_flags |= (specularMapRotation < 0) ? kSpecularMapRotationNegative : 0; ++ ++	specularRotation = abs(specularRotation); ++	specularRotation = llmin(specularRotation, MAX_MATERIAL_MAP_ROTATION); ++ ++	m_specularRotation = (U16)(abs(specularMapRotation)); ++} ++ ++// 'v' is an integer value for 100ths of radians (don't ask...) ++// ++void LLRenderMaterialEntry::LLRenderMaterial::setNormalMapRotation(S32 v) const ++{ ++ ++	// Store the fact that we're using the new rep for this material ++	// ++	m_flags |= kNewNormalMapRotation; ++ ++	// Store 'sign bit' in our m_flags ++	// ++	m_flags &= ~kNormalMapRotationNegative; ++	m_flags |= (normalMapRotation < 0) ? kNormalMapRotationNegative : 0; ++ ++	normalRotation = abs(normalRotation); ++	normalRotation = llmin(normalRotation, MAX_MATERIAL_MAP_ROTATION); ++ ++	m_normalRotation = (U16)(abs(normalMapRotation)); ++} +  + void LLRenderMaterialEntry::LLRenderMaterial::asLLSD( LLSD& dest ) const + { +@@ -193,20 +231,45 @@ + 	dest["NormOffsetY"] = (S32)m_normalOffsetY; + 	dest["NormRepeatX"] = m_normalRepeatX; + 	dest["NormRepeatY"] = m_normalRepeatY; +-	dest["NormRotation"] = (S32)m_normalRotation; ++ ++	S32 value = (S32)m_normalMapRotation; ++ ++	// If we don't have the flag for new rotations set, ++	// then we need to convert it now ++	if (!(m_flags & kNewNormalMapRotation)) ++	{ ++		F32 old_radians = ((F32)m_normalMapRotation / 10000.0f) ++		S32 new_val	    = (S32)(old_radians * 100.0f); ++		setNormalMapRotation(new_Val); ++	} ++ ++	dest["NormRotation"] = (m_flags & kNormalMapRotationNegative) ? -(S32)m_normalRotation : (S32)m_normalRotation; +  + 	dest["SpecOffsetX"] = (S32)m_specularOffsetX; + 	dest["SpecOffsetY"] = (S32)m_specularOffsetY; + 	dest["SpecRepeatX"] = m_specularRepeatX; + 	dest["SpecRepeatY"] = m_specularRepeatY; +-	dest["SpecRotation"] = (S32)m_specularRotation; ++ ++ ++	value = (S32)m_specularRotation; ++ ++	// If we don't have the flag for new rotations set, ++	// then we need to convert it now ++	if (!(m_flags & kNewSpecularMapRotation)) ++	{ ++		F32 old_radians = ((F32)m_specularMapRotation / 10000.0f) ++		S32 new_val	    = (S32)(old_radians * 100.0f); ++		setSpecularMapRotation(new_Val); ++	} ++ ++	dest["SpecRotation"] = (m_flags & kSpecularMapRotationNegative) ? -(S32)m_specularRotation : (S32)m_specularRotation; +  + 	dest["SpecMap"] = m_specularMap; + 	dest["SpecColor"] = m_specularLightColor.getValue(); + 	dest["SpecExp"] = (S32)m_specularLightExponent; + 	dest["EnvIntensity"] = (S32)m_environmentIntensity; + 	dest["AlphaMaskCutoff"] = (S32)m_alphaMaskCutoff; +-	dest["DiffuseAlphaMode"] = (S32)m_diffuseAlphaMode; ++	dest["DiffuseAlphaMode"] = (S32)(m_diffuseAlphaMode & 0xF); + 	 + } +  +@@ -217,7 +280,10 @@ + 	m_normalOffsetY = (U16)materialDefinition["NormOffsetY"].asInteger(); + 	m_normalRepeatX = materialDefinition["NormRepeatX"].asInteger(); + 	m_normalRepeatY = materialDefinition["NormRepeatY"].asInteger(); +-	m_normalRotation = (U16)materialDefinition["NormRotation"].asInteger(); ++ ++	S32 normalRotation = materialDefinition["NormRotation"].asInteger(); ++ ++	setNormalMapRotation(normalRotation); +  + 	m_specularMap = materialDefinition["SpecMap"].asUUID(); +  +@@ -225,7 +291,10 @@ + 	m_specularOffsetY = (U16)materialDefinition["SpecOffsetY"].asInteger(); + 	m_specularRepeatX = materialDefinition["SpecRepeatX"].asInteger(); + 	m_specularRepeatY = materialDefinition["SpecRepeatY"].asInteger(); +-	m_specularRotation = (U16)materialDefinition["SpecRotation"].asInteger(); ++ ++	S32 specularRotation = materialDefinition["SpecRotation"].asInteger(); ++ ++	setSpecularMapRotation(specularRotation); +  + 	m_specularLightColor.setValue( materialDefinition["SpecColor"] ); + 	m_specularLightExponent = (U8)materialDefinition["SpecExp"].asInteger(); +diff -r fe4bab01522e indra/llprimitive/llrendermaterialtable.h +--- a/indra/llprimitive/llrendermaterialtable.h	Wed May 15 17:57:21 2013 +0000 ++++ b/indra/llprimitive/llrendermaterialtable.h	Wed May 22 14:23:04 2013 -0700 +@@ -89,11 +89,17 @@ +  + 	void computeID(); +  ++ + 	struct LLRenderMaterial + 	{ + 		void asLLSD( LLSD& dest ) const; + 		void setFromLLSD( const LLSD& materialDefinition ); +  ++		void setNormalMapRotation(S32 v); ++		void setSpecularMapRotation(S32 v); ++ ++		const S32 MAX_MATERIAL_MAP_ROTATION = 62800; ++ + 		// 36 bytes + 		LLUUID m_normalMap; + 		LLUUID m_specularMap; +@@ -119,7 +125,20 @@ + 		U8 m_specularLightExponent; + 		U8 m_environmentIntensity; + 		U8 m_alphaMaskCutoff; +-		U8 m_diffuseAlphaMode; ++		U8 m_diffuseAlphaMode : 4; ++		U8 m_flags            : 4; ++	}; ++ ++	// Flags stored in LLRenderMaterial::m_flags to differentiate 'old' rotation format ++	// which doesn't handle negative or large rotations correctly from new format. ++	// All ancient materials will have these flags unset as the values for diffuseAlphaMode ++	// from which the bits were stolen never used more than the bottom 2 bits. ++	// ++	enum RenderMaterialFlags { ++	 kNewNormalMapRotation 		= 0x1, ++	 kNewSpecularMapRotation 	= 0x2, ++	 kNormalMapRotationNegative 	= 0x4, ++	 kSpecularMapRotationNegative   = 0x8 + 	}; +  + 	friend struct eastl::hash<LLRenderMaterial>; diff --git a/autobuild.xml b/autobuild.xml index 148ca1710b..628d3f6883 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -498,9 +498,9 @@              <key>archive</key>              <map>                <key>hash</key> -	      <string>10352aab979c333a52dbad21b6e6fba9</string> +              <string>10352aab979c333a52dbad21b6e6fba9</string>                <key>url</key> -	      <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/274403/arch/Darwin/installer/fmodex-4.44-darwin-20130419.tar.bz2</string> +              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/274403/arch/Darwin/installer/fmodex-4.44-darwin-20130419.tar.bz2</string>              </map>              <key>name</key>              <string>darwin</string> @@ -510,7 +510,7 @@              <key>archive</key>              <map>                <key>hash</key> -          <string>79e45527aa9fb90b813599dff5ce01a7</string> +              <string>79e45527aa9fb90b813599dff5ce01a7</string>                <key>url</key>                <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/274378/arch/Linux/installer/fmodex-4.44-linux-20130419.tar.bz2</string>              </map> @@ -522,9 +522,9 @@              <key>archive</key>              <map>                <key>hash</key> -	      <string>0980cdf98a322a780ba739e324d0b955</string> +	      <string>91752db72202807cffb33c1ec3fd90fc</string>                <key>url</key> -	      <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/274401/arch/CYGWIN/installer/fmodex-4.44-windows-20130419.tar.bz2</string> +	      <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/276321/arch/CYGWIN/installer/fmodex-4.44-windows-20130521.tar.bz2</string>              </map>              <key>name</key>              <string>windows</string> @@ -747,7 +747,6 @@            </map>          </map>        </map> -        <key>google_breakpad</key>        <map>          <key>license</key> @@ -763,9 +762,9 @@              <key>archive</key>              <map>             <key>hash</key> -	   <string>aff5566e04003de0383941981198e04e</string> +	      <string>aff5566e04003de0383941981198e04e</string>            <key>url</key> -          <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/273073/arch/Darwin/installer/google_breakpad-0.0.0-rev1099-darwin-20130329.tar.bz2</string> +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/273073/arch/Darwin/installer/google_breakpad-0.0.0-rev1099-darwin-20130329.tar.bz2</string>              </map>              <key>name</key>              <string>darwin</string> @@ -777,7 +776,7 @@               <key>hash</key>  	         <string>52257e5eb166a0b69c9c0c38f6e1920e</string>               <key>url</key> -	         <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/273079/arch/Linux/installer/google_breakpad-0.0.0-rev1099-linux-20130329.tar.bz2</string> +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/273079/arch/Linux/installer/google_breakpad-0.0.0-rev1099-linux-20130329.tar.bz2</string>              </map>              <key>name</key>              <string>linux</string> @@ -789,7 +788,7 @@                <key>hash</key>  	      <string>d812a6dfcabe6528198a3191068dac09</string>                <key>url</key> -             <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/273073/arch/CYGWIN/installer/google_breakpad-0.0.0-rev1099-windows-20130329.tar.bz2</string> +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/273073/arch/CYGWIN/installer/google_breakpad-0.0.0-rev1099-windows-20130329.tar.bz2</string>              </map>              <key>name</key>              <string>windows</string> @@ -835,9 +834,45 @@              <key>archive</key>              <map>                <key>hash</key> -              <string>98994d5b0b4b3d43be22aa6a5c36e6fa</string> +              <string>d2542614df9dd99cbb5ff67e76d4a6c1</string>                <key>url</key> -		<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-mock-graham/rev/272961/arch/CYGWIN/installer/gmock-1.6.0-windows-20130327.tar.bz2</string> +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-mock/rev/274899/arch/CYGWIN/installer/gmock-1.6.0-windows-20130426.tar.bz2</string> +            </map> +            <key>name</key> +            <string>windows</string> +          </map> +        </map> +      </map> +      <key>gperftools</key> +      <map> +        <key>license</key> +        <string>bsd</string> +        <key>license_file</key> +        <string>LICENSES/gperftools.txt</string> +        <key>name</key> +        <string>gperftools</string> +        <key>platforms</key> +        <map> +          <key>linux</key> +          <map> +            <key>archive</key> +            <map> +              <key>hash</key> +              <string>8aedfdcf670348c18a9991ae1b384a61</string> +              <key>url</key> +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-perftools/rev/262672/arch/Linux/installer/gperftools-2.0-linux-20120727.tar.bz2</string> +            </map> +            <key>name</key> +            <string>linux</string> +          </map> +          <key>windows</key> +          <map> +            <key>archive</key> +            <map> +              <key>hash</key> +              <string>f62841804acb91e1309603a84f3f0ce8</string> +              <key>url</key> +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-perftools/rev/262672/arch/CYGWIN/installer/gperftools-2.0-windows-20120727.tar.bz2</string>              </map>              <key>name</key>              <string>windows</string> @@ -2532,7 +2567,7 @@                    <string>"Visual Studio 10"</string>                    <string>-DUNATTENDED:BOOL=ON</string>                    <string>-DUSE_KDU=FALSE</string> -                </array> +                  </array>                </map>                <key>name</key>                <string>DebugOS</string> @@ -2620,7 +2655,7 @@                    <string>-DUNATTENDED:BOOL=ON</string>                    <string>-DINSTALL_PROPRIETARY=FALSE</string>                    <string>-DUSE_KDU=FALSE</string> -                </array> +                  </array>                </map>                <key>name</key>                <string>RelWithDebInfoOS</string> @@ -2707,7 +2742,7 @@                    <string>-DUNATTENDED:BOOL=ON</string>                    <string>-DINSTALL_PROPRIETARY=FALSE</string>                    <string>-DUSE_KDU=FALSE</string> -                </array> +                  </array>                </map>                <key>name</key>                <string>ReleaseOS</string> diff --git a/doc/contributions.txt b/doc/contributions.txt index 8c5bb3d576..66ccb404a8 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -404,6 +404,7 @@ Ganymedes Costagravas  Geenz Spad  	STORM-1823  	STORM-1900 +	NORSPEC-229  Gene Frostbite  GeneJ Composer  Geneko Nemeth @@ -647,6 +648,7 @@ Jonathan Yap  	STORM-1872  	STORM-1858  	STORM-1862 +	OPEN-161  Kadah Coba  	STORM-1060      STORM-1843 @@ -1023,6 +1025,7 @@ Ryozu Kojima  	VWR-287  Sachi Vixen  Sahkolihaa Contepomi +	MATBUG-102  Saii Hallard  SaintLEOlions Zimer  Salahzar Stenvaag @@ -1173,6 +1176,7 @@ Techwolf Lupindo  	SNOW-746  	VWR-12385  	VWR-20893 +	OPEN-161  Templar Merlin  tenebrous pau  	VWR-247 @@ -1240,6 +1244,7 @@ Vadim Bigbear  	VWR-2681  Vaalith Jinn      STORM-64 +    MATBUG-8  Vector Hastings  	VWR-8726  Veritas Raymaker diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake index 492ba2adea..a87027f5f6 100755 --- a/indra/cmake/APR.cmake +++ b/indra/cmake/APR.cmake @@ -49,7 +49,7 @@ else (STANDALONE)    set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/apr-1)    if (LINUX) -    list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} uuid) +      list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} uuid)      list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} rt)    endif (LINUX)  endif (STANDALONE) diff --git a/indra/cmake/BuildVersion.cmake b/indra/cmake/BuildVersion.cmake index 0094e313c7..b9ec8f5266 100755 --- a/indra/cmake/BuildVersion.cmake +++ b/indra/cmake/BuildVersion.cmake @@ -18,7 +18,7 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n             find_program(MERCURIAL hg)             if (DEFINED MERCURIAL)                execute_process( -                 COMMAND ${MERCURIAL} parents --template "{rev}" +                 COMMAND ${MERCURIAL} log -r tip --template "{p1rev}"                   OUTPUT_VARIABLE VIEWER_VERSION_REVISION                   OUTPUT_STRIP_TRAILING_WHITESPACE                   ) diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 246b9680e8..10a23ea068 100755 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -12,6 +12,7 @@ set(cmake_SOURCE_FILES      Audio.cmake      BerkeleyDB.cmake      Boost.cmake +    BuildVersion.cmake      CARes.cmake      CMakeCopyIfDifferent.cmake      ConfigurePkgConfig.cmake diff --git a/indra/cmake/DragDrop.cmake b/indra/cmake/DragDrop.cmake index b70aa6b6ee..73ef59b18f 100755 --- a/indra/cmake/DragDrop.cmake +++ b/indra/cmake/DragDrop.cmake @@ -1,20 +1,20 @@  # -*- cmake -*- -set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off") +  set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off") -if (OS_DRAG_DROP) +  if (OS_DRAG_DROP) -  if (WINDOWS) -    add_definitions(-DLL_OS_DRAGDROP_ENABLED=1) -  endif (WINDOWS) +    if (WINDOWS) +      add_definitions(-DLL_OS_DRAGDROP_ENABLED=1) +    endif (WINDOWS) -  if (DARWIN) -    add_definitions(-DLL_OS_DRAGDROP_ENABLED=1) -  endif (DARWIN) +    if (DARWIN) +      add_definitions(-DLL_OS_DRAGDROP_ENABLED=1) +    endif (DARWIN) -  if (LINUX) -    add_definitions(-DLL_OS_DRAGDROP_ENABLED=0) -  endif (LINUX) +    if (LINUX) +      add_definitions(-DLL_OS_DRAGDROP_ENABLED=0) +    endif (LINUX) -endif (OS_DRAG_DROP) +  endif (OS_DRAG_DROP) diff --git a/indra/cmake/Havok.cmake b/indra/cmake/Havok.cmake index 44f81ce332..8b7f01d20b 100755 --- a/indra/cmake/Havok.cmake +++ b/indra/cmake/Havok.cmake @@ -12,14 +12,14 @@ set(HAVOK_DEBUG_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)  set(HAVOK_RELEASE_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)  if (LL_DEBUG_HAVOK) -  if (WIN32) -    # Always link relwithdebinfo to havok-hybrid on windows. -    set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-hybrid) -  else (WIN32) -    set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug) -  endif (WIN32) +   if (WIN32) +      # Always link relwithdebinfo to havok-hybrid on windows. +      set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-hybrid) +   else (WIN32) +      set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug) +   endif (WIN32)  else (LL_DEBUG_HAVOK) -  set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok) +   set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)  endif (LL_DEBUG_HAVOK)  set(HAVOK_LIBS @@ -51,14 +51,14 @@ unset(HK_RELWITHDEBINFO_LIBRARIES)  # *TODO: Figure out why we need to extract like this...  foreach(HAVOK_LIB ${HAVOK_LIBS}) -  find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB}   ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH}) -  find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH}) -  find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}) -   -  if(LINUX) -    set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}") -    set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}") -    set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}") +        find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB}   ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH}) +        find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH}) +        find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}) +         +        if(LINUX) +            set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}") +            set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}") +            set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")      # Try to avoid extracting havok library each time we run cmake.      if("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted") @@ -77,35 +77,35 @@ foreach(HAVOK_LIB ${HAVOK_LIBS})        if(DEBUG_PREBUILT)          MESSAGE(STATUS "${cmd} ${debug_dir}")        endif(DEBUG_PREBUILT) -      exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv) +            exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv)        if(DEBUG_PREBUILT)          MESSAGE(STATUS "${cmd} ${release_dir}")        endif(DEBUG_PREBUILT) -      exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv) +            exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv)        if(DEBUG_PREBUILT)          MESSAGE(STATUS "${cmd} ${relwithdebinfo_dir}")        endif(DEBUG_PREBUILT) -      exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv) +            exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv) -      set(cmd "ar") -      set(arg " -xv") -      set(arg "${arg} ../lib${HAVOK_LIB}.a") +            set(cmd "ar") +            set(arg " -xv") +            set(arg "${arg} ../lib${HAVOK_LIB}.a")        if(DEBUG_PREBUILT)          MESSAGE(STATUS "cd ${debug_dir} && ${cmd} ${arg}")        endif(DEBUG_PREBUILT) -      exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv) +            exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv)        if(DEBUG_PREBUILT)          MESSAGE(STATUS "cd ${release_dir} && ${cmd} ${arg}")        endif(DEBUG_PREBUILT) -      exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv) +            exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv)        if(DEBUG_PREBUILT)          MESSAGE(STATUS "cd ${relwithdebinfo_dir} && ${cmd} ${arg}")        endif(DEBUG_PREBUILT) -      exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv) +            exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv)        # Just assume success for now.        set(havok_${HAVOK_LIB}_extracted 0) @@ -113,9 +113,9 @@ foreach(HAVOK_LIB ${HAVOK_LIBS})      endif(${CMAKE_BINARY_DIR}/temp/havok-source_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0) -    file(GLOB extracted_debug "${debug_dir}/*.o") -    file(GLOB extracted_release "${release_dir}/*.o") -    file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o") +            file(GLOB extracted_debug "${debug_dir}/*.o") +            file(GLOB extracted_release "${release_dir}/*.o") +            file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")      if(DEBUG_PREBUILT)        MESSAGE(STATUS "extracted_debug ${debug_dir}/*.o") @@ -123,15 +123,15 @@ foreach(HAVOK_LIB ${HAVOK_LIBS})        MESSAGE(STATUS "extracted_relwithdebinfo ${relwithdebinfo_dir}/*.o")      endif(DEBUG_PREBUILT) -    list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug}) -    list(APPEND HK_RELEASE_LIBRARIES ${extracted_release}) -    list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo}) -  else(LINUX) -  # Win32 -    list(APPEND HK_DEBUG_LIBRARIES   ${HAVOK_DEBUG_LIB_${HAVOK_LIB}}) -    list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}}) -    list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}}) -  endif (LINUX) +            list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug}) +            list(APPEND HK_RELEASE_LIBRARIES ${extracted_release}) +            list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo}) +        else(LINUX) +        # Win32 +            list(APPEND HK_DEBUG_LIBRARIES   ${HAVOK_DEBUG_LIB_${HAVOK_LIB}}) +            list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}}) +            list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}}) +        endif (LINUX)  endforeach(HAVOK_LIB)  endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake index ab39cbb6be..0d87ff579a 100755 --- a/indra/cmake/LLPrimitive.cmake +++ b/indra/cmake/LLPrimitive.cmake @@ -2,6 +2,8 @@  # these should be moved to their own cmake file  include(Prebuilt) +include(Boost) +  use_prebuilt_binary(colladadom)  use_prebuilt_binary(pcre)  use_prebuilt_binary(libxml) @@ -15,10 +17,7 @@ if (WINDOWS)          optimized llprimitive          debug libcollada14dom22-d          optimized libcollada14dom22 -        debug libboost_filesystem-mt-gd -        optimized libboost_filesystem-mt -        debug libboost_system-mt-gd -        optimized libboost_system-mt +        ${BOOST_SYSTEM_LIBRARIES}          )  else (WINDOWS)      set(LLPRIMITIVE_LIBRARIES  diff --git a/indra/cmake/LLRender.cmake b/indra/cmake/LLRender.cmake index ae71ee4c0d..868922451f 100755 --- a/indra/cmake/LLRender.cmake +++ b/indra/cmake/LLRender.cmake @@ -11,8 +11,8 @@ set(LLRENDER_INCLUDE_DIRS  if (BUILD_HEADLESS)    set(LLRENDER_HEADLESS_LIBRARIES -    llrenderheadless -    ) +      llrenderheadless +      )  endif (BUILD_HEADLESS)  set(LLRENDER_LIBRARIES      llrender diff --git a/indra/cmake/LLWindow.cmake b/indra/cmake/LLWindow.cmake index 0def507e65..ad732ef650 100755 --- a/indra/cmake/LLWindow.cmake +++ b/indra/cmake/LLWindow.cmake @@ -33,10 +33,10 @@ set(LLWINDOW_INCLUDE_DIRS  if (BUILD_HEADLESS)    set(LLWINDOW_HEADLESS_LIBRARIES -    llwindowheadless -    ) +      llwindowheadless +      )  endif (BUILD_HEADLESS) -set(LLWINDOW_LIBRARIES -    llwindow -    ) +  set(LLWINDOW_LIBRARIES +      llwindow +      ) diff --git a/indra/cmake/VisualLeakDetector.cmake b/indra/cmake/VisualLeakDetector.cmake index 27e93e28bb..6a20148b47 100755 --- a/indra/cmake/VisualLeakDetector.cmake +++ b/indra/cmake/VisualLeakDetector.cmake @@ -1,12 +1,12 @@  # -*- cmake -*- -set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off") +  set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off") -if (INCLUDE_VLD_CMAKE) +  if (INCLUDE_VLD_CMAKE) -  if (WINDOWS) -    add_definitions(-DINCLUDE_VLD=1) -  endif (WINDOWS) +    if (WINDOWS) +      add_definitions(-DINCLUDE_VLD=1) +    endif (WINDOWS) -endif (INCLUDE_VLD_CMAKE) +  endif (INCLUDE_VLD_CMAKE) diff --git a/indra/lib/python/indra/util/llversion.py b/indra/lib/python/indra/util/llversion.py deleted file mode 100755 index ba6f567b60..0000000000 --- a/indra/lib/python/indra/util/llversion.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env python -"""\ -@file  llversion.py -@brief Parses llcommon/llversionserver.h and llcommon/llversionviewer.h -       for the version string and channel string. -       Parses hg info for branch and revision. - -$LicenseInfo:firstyear=2006&license=mit$ - -Copyright (c) 2006-2009, Linden Research, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -$/LicenseInfo$ -""" - -import re, sys, os, subprocess - -# Methods for gathering version information from -# llversionviewer.h and llversionserver.h - -def get_src_root(): -    indra_lib_python_indra_path = os.path.dirname(__file__) -    return os.path.abspath(os.path.realpath(indra_lib_python_indra_path + "/../../../../../")) - -def get_version_file_contents(version_type): -    filepath = get_src_root() + '/indra/llcommon/llversion%s.h' % version_type -    file = open(filepath,"r") -    file_str = file.read() -    file.close() -    return file_str - -def get_version(version_type): -    file_str = get_version_file_contents(version_type) -    m = re.search('const S32 LL_VERSION_MAJOR = (\d+);', file_str) -    VER_MAJOR = m.group(1) -    m = re.search('const S32 LL_VERSION_MINOR = (\d+);', file_str) -    VER_MINOR = m.group(1) -    m = re.search('const S32 LL_VERSION_PATCH = (\d+);', file_str) -    VER_PATCH = m.group(1) -    m = re.search('const S32 LL_VERSION_BUILD = (\d+);', file_str) -    VER_BUILD = m.group(1) -    version = "%(VER_MAJOR)s.%(VER_MINOR)s.%(VER_PATCH)s.%(VER_BUILD)s" % locals() -    return version - -def get_channel(version_type): -    file_str = get_version_file_contents(version_type) -    m = re.search('const char \* const LL_CHANNEL = "(.+)";', file_str) -    return m.group(1) -     -def get_viewer_version(): -    return get_version('viewer') - -def get_server_version(): -    return get_version('server') - -def get_viewer_channel(): -    return get_channel('viewer') - -def get_server_channel(): -    return get_channel('server') - -# Methods for gathering hg information -def get_hg_repo(): -    child = subprocess.Popen(["hg","showconfig","paths.default"], stdout=subprocess.PIPE) -    output, error = child.communicate() -    status = child.returncode -    if status: -        print >> sys.stderr, error -        sys.exit(1) -    if not output: -        print >> sys.stderr, 'ERROR: cannot find repo we cloned from' -        sys.exit(1) -    return output - -def get_hg_changeset(): -    # The right thing to do would be to use the *global* revision id: -    #     "hg id -i" -    # For the moment though, we use the parent revision: -    child = subprocess.Popen(["hg","parents","--template","{rev}"], stdout=subprocess.PIPE) -    output, error = child.communicate() -    status = child.returncode -    if status: -        print >> sys.stderr, error -        sys.exit(1) -    lines = output.splitlines() -    if len(lines) > 1: -        print >> sys.stderr, 'ERROR: working directory has %d parents' % len(lines) -    return lines[0] - -def using_hg(): -    return os.path.isdir(os.path.join(get_src_root(), '.hg')) diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt index 41b92b00e0..c0fc1b2be0 100755 --- a/indra/linux_crash_logger/CMakeLists.txt +++ b/indra/linux_crash_logger/CMakeLists.txt @@ -26,6 +26,10 @@ include_directories(SYSTEM      ${LLCOMMON_SYSTEM_INCLUDE_DIRS}      ${LLXML_SYSTEM_INCLUDE_DIRS}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    )  set(linux_crash_logger_SOURCE_FILES      linux_crash_logger.cpp diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp index 8a17819083..93c2f15a53 100644 --- a/indra/llappearance/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -597,19 +597,31 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )  			norm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR);  			scaled_normals[vert_index_mesh].add(norm);  			norm = scaled_normals[vert_index_mesh]; + +			// guard against degenerate input data before we create NaNs below! +			//  			norm.normalize3fast();  			normals[vert_index_mesh] = norm;  			// calculate new binormals  			LLVector4a binorm = mMorphData->mBinormals[vert_index_morph]; + +			// guard against degenerate input data before we create NaNs below! +			// +			if (!binorm.isFinite3() || (binorm.dot3(binorm).getF32() <= F_APPROXIMATELY_ZERO)) +			{ +				binorm.set(1,0,0,1); +			} +  			binorm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR);  			scaled_binormals[vert_index_mesh].add(binorm);  			LLVector4a tangent;  			tangent.setCross3(scaled_binormals[vert_index_mesh], norm);  			LLVector4a& normalized_binormal = binormals[vert_index_mesh]; -			normalized_binormal.setCross3(norm, tangent);  + +			normalized_binormal.setCross3(norm, tangent); 			  			normalized_binormal.normalize3fast(); -			 +  			tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight;  		} diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp index 45fc3186f4..e9b74b8f41 100644 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ b/indra/llaudio/llaudioengine_fmodex.cpp @@ -67,7 +67,7 @@ inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string)  {  	if(result == FMOD_OK)  		return false; -	llwarns << string << " Error: " << FMOD_ErrorString(result) << llendl; +	lldebugs << string << " Error: " << FMOD_ErrorString(result) << llendl;  	return true;  } @@ -258,19 +258,29 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)  	int r_numbuffers, r_samplerate, r_channels, r_bits;  	unsigned int r_bufferlength; -	char r_name[256];  	mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers); +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_bufferlength=" << r_bufferlength << " bytes" << LL_ENDL; +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_numbuffers=" << r_numbuffers << LL_ENDL; +  	mSystem->getSoftwareFormat(&r_samplerate, NULL, &r_channels, NULL, NULL, &r_bits); -	mSystem->getDriverInfo(0, r_name, 255, 0); -	r_name[255] = '\0'; -	int latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate); +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_samplerate=" << r_samplerate << "Hz" << LL_ENDL; +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_channels=" << r_channels << LL_ENDL; +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_bits =" << r_bits << LL_ENDL; + +	char r_name[512]; +	mSystem->getDriverInfo(0, r_name, 511, 0); +	r_name[511] = '\0'; +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_name=\"" << r_name << "\"" <<  LL_ENDL; -	LL_INFOS("AppInit") << "FMOD device: "<< r_name << "\n" -		<< "FMOD Ex parameters: " << r_samplerate << " Hz * " << r_channels << " * " <<r_bits <<" bit\n" -		<< "\tbuffer " << r_bufferlength << " * " << r_numbuffers << " (" << latency <<"ms)" << LL_ENDL; +	int latency = 100; // optimistic default - i suspect if sample rate is 0, everything breaks.  +	if ( r_samplerate != 0 ) +		latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate); +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): latency=" << latency << "ms" << LL_ENDL;  	mInited = true; +	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): initialization complete." << LL_ENDL; +  	return true;  } @@ -310,8 +320,8 @@ void LLAudioEngine_FMODEX::shutdown()  	llinfos << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << llendl;  	if ( mSystem ) // speculative fix for MAINT-2657  	{ -		mSystem->close(); -		mSystem->release(); +	mSystem->close(); +	mSystem->release();  	}  	llinfos << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << llendl; diff --git a/indra/llaudio/llwindgen.h b/indra/llaudio/llwindgen.h index 719b0ecbf2..ec58f76f5f 100755 --- a/indra/llaudio/llwindgen.h +++ b/indra/llaudio/llwindgen.h @@ -57,7 +57,7 @@ public:  	const U32 getInputSamplingRate() { return mInputSamplingRate; }  	const F32 getNextSample();  	const F32 getClampedSample(bool clamp, F32 sample); - +	  	// newbuffer = the buffer passed from the previous DSP unit.  	// numsamples = length in samples-per-channel at this mix time.  	// NOTE: generates L/R interleaved stereo @@ -133,11 +133,11 @@ public:  				MIXBUFFERFORMAT_T	sample_left = (MIXBUFFERFORMAT_T)getClampedSample(clip, mLastSample - (F32)sample_right);  				*cursamplep = sample_left; -				++cursamplep; +					++cursamplep;  				*cursamplep = sample_right; -				++cursamplep; +					++cursamplep; +				}  			} -		}  		return newbuffer;  	} diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index c6da205815..67a98d5fb8 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -986,9 +986,9 @@ bool windows_post_minidump_callback(const wchar_t* dump_path,  	}  	llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl; -    // *NOTE:Mani - this code is stolen from LLApp, where its never actually used. +   // *NOTE:Mani - this code is stolen from LLApp, where its never actually used.  	//OSMessageBox("Attach Debugger Now", "Error", OSMB_OK); -    // *TODO: Translate the signals/exceptions into cross-platform stuff +   // *TODO: Translate the signals/exceptions into cross-platform stuff  	// Windows implementation  	llinfos << "Entering Windows Exception Handler..." << llendl; diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index d1c44c9403..a0802c6adf 100755 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -226,9 +226,7 @@ void LLVolatileAPRPool::clearVolatileAPRPool()  		llassert_always(mNumActiveRef > 0) ;  	} -	//paranoia check if the pool is jammed. -	//will remove the check before going to release. -	llassert_always(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ; +	llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;  }  BOOL LLVolatileAPRPool::isFull() diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h index 7542a8dece..5d2fccc5ba 100755 --- a/indra/llcommon/llavatarname.h +++ b/indra/llcommon/llavatarname.h @@ -63,7 +63,7 @@ public:  	// For normal names, returns "James Linden (james.linden)"  	// When display names are disabled returns just "James Linden"  	std::string getCompleteName() const; - +	  	// Returns "James Linden" or "bobsmith123 Resident" for backwards  	// compatibility with systems like voice and muting  	// *TODO: Eliminate this in favor of username only diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index a629f71d4b..baaddcaed1 100755 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -60,7 +60,7 @@ bool LLCoros::cleanup(const LLSD&)          // since last tick?          if (mi->second->exited())          { -            LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL; +			   LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL;              // The erase() call will invalidate its passed iterator value --              // so increment mi FIRST -- but pass its original value to              // erase(). This is what postincrement is all about. @@ -94,7 +94,7 @@ std::string LLCoros::generateDistinctName(const std::string& prefix) const      {          if (mCoros.find(name) == mCoros.end())          { -            LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL; +			   LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL;              return name;          }      } diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 9b0141eb76..d2af004cde 100755 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -201,10 +201,7 @@ namespace {  		virtual void recordMessage(LLError::ELevel level,  								   const std::string& message)  		{ -			llutf16string utf16str = -				wstring_to_utf16str(utf8str_to_wstring(message)); -			utf16str += '\n'; -			OutputDebugString(utf16str.c_str()); +			LL_WINDOWS_OUTPUT_DEBUG(message);  		}  	};  #endif @@ -1401,5 +1398,27 @@ namespace LLError     {         sIndex = 0 ;     } + +#if LL_WINDOWS +	void LLOutputDebugUTF8(const std::string& s) +	{ +		// Be careful when calling OutputDebugString as it throws DBG_PRINTEXCEPTION_C  +		// which works just fine under the windows debugger, but can cause users who +		// have enabled SEHOP exception chain validation to crash due to interactions +		// between the Win 32-bit exception handling and boost coroutine fiber stacks. BUG-2707 +		// +		if (IsDebuggerPresent()) +		{ +			// Need UTF16 for Unicode OutputDebugString +			// +			if (s.size()) +			{ +				OutputDebugString(utf8str_to_utf16str(s).c_str()); +				OutputDebugString(TEXT("\n")); +			} +		} +	} +#endif +  } diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index b65b410153..0b723aeb5d 100755 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -34,7 +34,6 @@  #include "llerrorlegacy.h"  #include "stdtypes.h" -  /** Error Logging Facility  	Information for most users: @@ -199,8 +198,20 @@ namespace LLError         static void clear() ;  	   static void end(std::ostringstream* _out) ;     };  + +#if LL_WINDOWS +	void LLOutputDebugUTF8(const std::string& s); +#endif +  } +#if LL_WINDOWS +	// Macro accepting a std::string for display in windows debugging console +	#define LL_WINDOWS_OUTPUT_DEBUG(a) LLError::LLOutputDebugUTF8(a) +#else +	#define LL_WINDOWS_OUTPUT_DEBUG(a) +#endif +  //this is cheaper than llcallstacks if no need to output other variables to call stacks.   #define llpushcallstacks LLError::LLCallStacks::push(__FUNCTION__, __LINE__)  #define llcallstacks \ diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index 9b15804e97..024fdd1b4d 100755 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -561,7 +561,7 @@ std::vector<LLFastTimer::NamedTimer*>& LLFastTimer::NamedTimer::getChildren()  	return mChildren;  } -// static +//static  LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer()  {          return *NamedTimerFactory::instance().getRootTimer(); diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 864b6e6975..c3a0f0bfe0 100755 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -438,7 +438,7 @@ llstdio_filebuf::int_type llstdio_filebuf::overflow(llstdio_filebuf::int_type __  				_M_set_buffer(0);  				__ret = traits_type::not_eof(__c);  			} -		} +	}  		else if (_M_buf_size > 1)  		{  			// Overflow in 'uncommitted' mode: set _M_writing, set @@ -496,11 +496,11 @@ bool llstdio_filebuf::_convert_to_external(char_type* __ibuf,  		if (__r == codecvt_base::ok || __r == codecvt_base::partial)  			__blen = __bend - __buf;  		else if (__r == codecvt_base::noconv) -		{ +	{  			// Same as the always_noconv case above.  			__buf = reinterpret_cast<char*>(__ibuf);  			__blen = __ilen; -		} +	}  		else  			__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external "  									"conversion error")); @@ -643,9 +643,9 @@ llstdio_filebuf::int_type llstdio_filebuf::underflow()  							_M_ext_end, _M_ext_next,  							this->eback(),  							this->eback() + __buflen, __iend); -				} +}  				if (__r == codecvt_base::noconv) -				{ +{  					size_t __avail = _M_ext_end - _M_ext_buf;  					__ilen = std::min(__avail, __buflen);  					traits_type::copy(this->eback(), @@ -806,15 +806,15 @@ std::streamsize llstdio_filebuf::xsputn(char_type* __s, std::streamsize __n)  				__ret = fwrite(__buf, 1, __buffill, _M_file.file());  			}  			if (__ret == __buffill) -			{ +	{  				__ret += fwrite(reinterpret_cast<const char*>(__s), 1,  								__n, _M_file.file()); -			} +	}  			if (__ret == __buffill + __n)  			{  				_M_set_buffer(0);  				_M_writing = true; -			} +}  			if (__ret > __buffill)  				__ret -= __buffill;  			else @@ -848,7 +848,7 @@ llifstream::llifstream() : _M_filebuf(),  #endif  // explicit -llifstream::llifstream(const std::string& _Filename,  +llifstream::llifstream(const std::string& _Filename,  		ios_base::openmode _Mode) : _M_filebuf(),  #if LL_WINDOWS  	std::istream(&_M_filebuf) @@ -877,7 +877,7 @@ llifstream::llifstream(const char* _Filename,  	if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)  	{  		_Myios::setstate(ios_base::failbit); -	} +}  }  #else  	std::istream() @@ -951,8 +951,8 @@ void llifstream::close()  #else  		this->setstate(ios_base::failbit);  #endif +		}  	} -}  /************** output file stream ********************************/ @@ -1042,7 +1042,7 @@ void llofstream::open(const char* _Filename, ios_base::openmode _Mode)  #if LL_WINDOWS  	llutf16string wideName = utf8str_to_utf16str( _Filename );  	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0) -	{ +{  		_Myios::setstate(ios_base::failbit);  	}  	else diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 9d70db96ea..d59e68367e 100755 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -35,7 +35,7 @@   * Attempts to mostly mirror the POSIX style IO functions.   */ -typedef FILE LLFILE; +typedef FILE	LLFILE;  #include <fstream>  #include <sys/stat.h> @@ -237,7 +237,7 @@ public:  			ios_base::openmode _Mode = ios_base::in,  			//size_t _Size = static_cast<size_t>(BUFSIZ));  			size_t _Size = static_cast<size_t>(1)); - +	  	/**  	 *  @brief  Create a stream using an open file descriptor.  	 *  @param  fd    An open file descriptor. diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp index cef743a7be..614a2d5636 100755 --- a/indra/llcommon/llsdserialize_xml.cpp +++ b/indra/llcommon/llsdserialize_xml.cpp @@ -406,7 +406,7 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)  		}  		if (mEmitErrors)  		{ -			llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl; +		llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl;  		}  		data = LLSD();  		return LLSDParser::PARSE_FAILURE; @@ -487,7 +487,7 @@ S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data)  	{  		if (mEmitErrors)  		{ -			llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl; +		llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;  		}  		return LLSDParser::PARSE_FAILURE;  	} diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp index 6f1e7d46b8..f188865eb0 100755 --- a/indra/llcommon/tests/llprocess_test.cpp +++ b/indra/llcommon/tests/llprocess_test.cpp @@ -969,10 +969,7 @@ namespace tut                        childout.getline(), "ok");          // important to get the implicit flush from std::endl          py.mPy->getWritePipe().get_ostream() << "go" << std::endl; -        for (i = 0; i < timeout && py.mPy->isRunning() && ! childout.contains("\n"); ++i) -        { -            yield(); -        } +        waitfor(*py.mPy);          ensure("script never replied", childout.contains("\n"));          ensure_equals("child didn't ack", childout.getline(), "ack");          ensure_equals("bad child termination", py.mPy->getStatus().mState, LLProcess::EXITED); diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 0526793d3a..79d0a44551 100755 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -46,6 +46,7 @@ class LLRotation;  // of this writing, July 08, 2010) about getting it implemented before you resort to  // LLVector3/LLVector4.   ///////////////////////////////// +class LLVector4a;  LL_ALIGN_PREFIX(16)  class LLVector4a @@ -236,6 +237,11 @@ public:  	// Note that this does not consider zero length vectors!  	inline void normalize3fast(); +	// Normalize this vector with respect to the x, y, and z components only. Accurate only to 10-12 bits of precision. W component is destroyed +	// Same as above except substitutes default vector contents if the vector is non-finite or degenerate due to zero length. +	// +	inline void normalize3fast_checked(LLVector4a* d = 0); +  	// Return true if this vector is normalized with respect to x,y,z up to tolerance  	inline LLBool32 isNormalized3( F32 tolerance = 1e-3 ) const; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 3f06e6b99e..c4e1f0c84c 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1392,7 +1392,7 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en  	pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t);  	pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t);  	pt->mTexT  = t; -	 +  	// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02  	twist.setQuat  (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);  	// Rotate the point around the circle's center. @@ -1446,7 +1446,7 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en  	pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t);  	pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t);  	pt->mTexT  = t; -	 +  	// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02  	twist.setQuat  (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);  	// Rotate the point around the circle's center. @@ -1594,7 +1594,7 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,  			S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions());  			if (is_sculpted) -				sides = sculpt_size; +				sides = llmax(sculpt_size, 1);  			genNGon(params, sides);  		} @@ -1644,6 +1644,7 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,  			mPath[i].mScale.mV[0] = lerp(1,params.getScale().mV[0],t);  			mPath[i].mScale.mV[1] = lerp(1,params.getScale().mV[1],t);  			mPath[i].mTexT  = t; +  			mPath[i].mRot.setQuat(F_PI * params.getTwist() * t,1,0,0);  		} @@ -2079,9 +2080,9 @@ void LLVolume::regen()  	createVolumeFaces();  } -void LLVolume::genBinormals(S32 face) +void LLVolume::genTangents(S32 face)  { -	mVolumeFaces[face].createBinormals(); +	mVolumeFaces[face].createTangents();  }  LLVolume::~LLVolume() @@ -2442,6 +2443,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  			LLVector4a pos_range;  			pos_range.setSub(max_pos, min_pos);  			LLVector2 tc_range2 = max_tc - min_tc; +  			LLVector4a tc_range;  			tc_range.set(tc_range2[0], tc_range2[1], tc_range2[0], tc_range2[1]);  			LLVector4a min_tc4(min_tc[0], min_tc[1], min_tc[0], min_tc[1]); @@ -4392,7 +4394,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,  				segments.push_back(vertices.size());  #if DEBUG_SILHOUETTE_BINORMALS  				vertices.push_back(face.mVertices[j].getPosition()); -				vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mBinormal*0.1f); +				vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mTangent*0.1f);  				normals.push_back(LLVector3(0,0,1));  				normals.push_back(LLVector3(0,0,1));  				segments.push_back(vertices.size()); @@ -4508,22 +4510,9 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,  	}  } -S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  -								   S32 face, -								   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) -{ -	LLVector4a starta, enda; -	starta.load3(start.mV); -	enda.load3(end.mV); - -	return lineSegmentIntersect(starta, enda, face, intersection, tex_coord, normal, bi_normal); - -} - -  S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,   								   S32 face, -								   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +								   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent_out)  {  	S32 hit_face = -1; @@ -4561,9 +4550,9 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en          if (LLLineSegmentBoxIntersect(start, end, box_center, box_size))  		{ -			if (bi_normal != NULL) // if the caller wants binormals, we may need to generate them +			if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them  			{ -				genBinormals(i); +				genTangents(i);  			}  			if (isUnique()) @@ -4597,7 +4586,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en  								LLVector4a intersect = dir;  								intersect.mul(closest_t);  								intersect.add(start); -								intersection->set(intersect.getF32ptr()); +								*intersection = intersect;  							} @@ -4612,19 +4601,42 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en  							if (normal!= NULL)  							{ -								LLVector4* norm = (LLVector4*) face.mNormals; - -								*normal		= ((1.f - a - b)  * LLVector3(norm[idx0]) +  -									a              * LLVector3(norm[idx1]) + -									b              * LLVector3(norm[idx2])); +								LLVector4a* norm = face.mNormals; +								 +								LLVector4a n1,n2,n3; +								n1 = norm[idx0]; +								n1.mul(1.f-a-b); +								 +								n2 = norm[idx1]; +								n2.mul(a); +								 +								n3 = norm[idx2]; +								n3.mul(b); + +								n1.add(n2); +								n1.add(n3); +								 +								*normal		= n1;   							} -							if (bi_normal != NULL) +							if (tangent_out != NULL)  							{ -								LLVector4* binormal = (LLVector4*) face.mBinormals; -								*bi_normal = ((1.f - a - b)  * LLVector3(binormal[idx0]) +  -										a              * LLVector3(binormal[idx1]) + -										b              * LLVector3(binormal[idx2])); +								LLVector4a* tangents = face.mTangents; +								 +								LLVector4a t1,t2,t3; +								t1 = tangents[idx0]; +								t1.mul(1.f-a-b); +								 +								t2 = tangents[idx1]; +								t2.mul(a); +								 +								t3 = tangents[idx2]; +								t3.mul(b); + +								t1.add(t2); +								t1.add(t3); +								 +								*tangent_out = t1;   							}  						}  					} @@ -4637,7 +4649,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en  					face.createOctree();  				} -				LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal); +				LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out);  				intersect.traverse(face.mOctree);  				if (intersect.mHitFace)  				{ @@ -5183,7 +5195,7 @@ LLVolumeFace::LLVolumeFace() :  	mNumIndices(0),  	mPositions(NULL),  	mNormals(NULL), -	mBinormals(NULL), +	mTangents(NULL),  	mTexCoords(NULL),  	mIndices(NULL),  	mWeights(NULL), @@ -5206,7 +5218,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)  	mNumIndices(0),  	mPositions(NULL),  	mNormals(NULL), -	mBinormals(NULL), +	mTangents(NULL),  	mTexCoords(NULL),  	mIndices(NULL),  	mWeights(NULL), @@ -5264,15 +5276,15 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)  		} -		if (src.mBinormals) +		if (src.mTangents)  		{ -			allocateBinormals(src.mNumVertices); -			LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) src.mBinormals, vert_size); +			allocateTangents(src.mNumVertices); +			LLVector4a::memcpyNonAliased16((F32*) mTangents, (F32*) src.mTangents, vert_size);  		}  		else  		{ -			ll_aligned_free_16(mBinormals); -			mBinormals = NULL; +			ll_aligned_free_16(mTangents); +			mTangents = NULL;  		}  		if (src.mWeights) @@ -5316,8 +5328,8 @@ void LLVolumeFace::freeData()  	mTexCoords = NULL;  	ll_aligned_free_16(mIndices);  	mIndices = NULL; -	ll_aligned_free_16(mBinormals); -	mBinormals = NULL; +	ll_aligned_free_16(mTangents); +	mTangents = NULL;  	ll_aligned_free_16(mWeights);  	mWeights = NULL; @@ -5897,7 +5909,7 @@ void LLVolumeFace::cacheOptimize()  	}  	LLVector4a* binorm = NULL; -	if (mBinormals) +	if (mTangents)  	{  		binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);  	} @@ -5922,9 +5934,9 @@ void LLVolumeFace::cacheOptimize()  			{  				wght[cur_idx] = mWeights[idx];  			} -			if (mBinormals) +			if (mTangents)  			{ -				binorm[cur_idx] = mBinormals[idx]; +				binorm[cur_idx] = mTangents[idx];  			}  			cur_idx++; @@ -5940,13 +5952,13 @@ void LLVolumeFace::cacheOptimize()  	ll_aligned_free_16(mNormals);  	ll_aligned_free_16(mTexCoords);  	ll_aligned_free_16(mWeights); -	ll_aligned_free_16(mBinormals); +	ll_aligned_free_16(mTangents);  	mPositions = pos;  	mNormals = norm;  	mTexCoords = tc;  	mWeights = wght; -	mBinormals = binorm; +	mTangents = binorm;  	//std::string result = llformat("ACMR pre/post: %.3f/%.3f  --  %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks);  	//llinfos << result << llendl; @@ -6027,7 +6039,7 @@ void LLVolumeFace::swapData(LLVolumeFace& rhs)  {  	llswap(rhs.mPositions, mPositions);  	llswap(rhs.mNormals, mNormals); -	llswap(rhs.mBinormals, mBinormals); +	llswap(rhs.mTangents, mTangents);  	llswap(rhs.mTexCoords, mTexCoords);  	llswap(rhs.mIndices,mIndices);  	llswap(rhs.mNumVertices, mNumVertices); @@ -6116,22 +6128,11 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  			corners[2].mTexCoord=swap;  		} -		LLVector4a binormal; -		 -		calc_binormal_from_triangle( binormal, -			corners[0].getPosition(), corners[0].mTexCoord, -			corners[1].getPosition(), corners[1].mTexCoord, -			corners[2].getPosition(), corners[2].mTexCoord); -		 -		binormal.normalize3fast(); -  		S32 size = (grid_size+1)*(grid_size+1);  		resizeVertices(size); -		allocateBinormals(size); - +		  		LLVector4a* pos = (LLVector4a*) mPositions;  		LLVector4a* norm = (LLVector4a*) mNormals; -		LLVector4a* binorm = (LLVector4a*) mBinormals;  		LLVector2* tc = (LLVector2*) mTexCoords;  		for(int gx = 0;gx<grid_size+1;gx++) @@ -6150,8 +6151,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  				*pos++ = newVert.getPosition();  				*norm++ = baseVert.getNormal();  				*tc++ = newVert.mTexCoord; -				*binorm++ = binormal; - +				  				if (gx == 0 && gy == 0)  				{  					min = newVert.getPosition(); @@ -6227,8 +6227,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK))  	{  		resizeVertices(num_vertices+1); -		allocateBinormals(num_vertices+1);	 - +		  		if (!partial_build)  		{  			resizeIndices(num_indices+3); @@ -6237,8 +6236,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	else  	{  		resizeVertices(num_vertices); -		allocateBinormals(num_vertices); - +		  		if (!partial_build)  		{  			resizeIndices(num_indices); @@ -6272,8 +6270,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	LLVector2* tc = (LLVector2*) mTexCoords;  	LLVector4a* pos = (LLVector4a*) mPositions;  	LLVector4a* norm = (LLVector4a*) mNormals; -	LLVector4a* binorm = (LLVector4a*) mBinormals; - +	  	// Copy the vertices into the array  	for (S32 i = 0; i < num_vertices; i++)  	{ @@ -6309,31 +6306,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	cuv = (min_uv + max_uv)*0.5f; -	LLVector4a binormal; -	calc_binormal_from_triangle(binormal, -		*mCenter, cuv, -		pos[0], tc[0], -		pos[1], tc[1]); -	binormal.normalize3fast(); - -	LLVector4a normal; -	LLVector4a d0, d1; -	 - -	d0.setSub(*mCenter, pos[0]); -	d1.setSub(*mCenter, pos[1]); - -	if (mTypeMask & TOP_MASK) -	{ -		normal.setCross3(d0, d1); -	} -	else -	{ -		normal.setCross3(d1, d0); -	} - -	normal.normalize3fast(); -  	VertexData vd;  	vd.setPosition(*mCenter);  	vd.mTexCoord = cuv; @@ -6342,15 +6314,10 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	{  		pos[num_vertices] = *mCenter;  		tc[num_vertices] = cuv; +  		num_vertices++;  	} -	for (S32 i = 0; i < num_vertices; i++) -	{ -		binorm[i].load4a(binormal.getF32ptr()); -		norm[i].load4a(normal.getF32ptr()); -	} -  	if (partial_build)  	{  		return TRUE; @@ -6585,63 +6552,68 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	} -		 + +	LLVector4a d0,d1; + +	d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]); +	d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]); + +	LLVector4a normal; +	normal.setCross3(d0,d1); + +	if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO) +	{ +		normal.normalize3fast(); +	} +	else +	{ //degenerate, make up a value +		normal.set(0,0,1); +	} + +	llassert(llfinite(normal.getF32ptr()[0])); +	llassert(llfinite(normal.getF32ptr()[1])); +	llassert(llfinite(normal.getF32ptr()[2])); + +	llassert(!llisnan(normal.getF32ptr()[0])); +	llassert(!llisnan(normal.getF32ptr()[1])); +	llassert(!llisnan(normal.getF32ptr()[2])); +	 +	for (S32 i = 0; i < num_vertices; i++) +	{ +		norm[i].load4a(normal.getF32ptr()); +	} +  	return TRUE;  } -void LLVolumeFace::createBinormals() +void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, +        const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent); + +void LLVolumeFace::createTangents()  { -	if (!mBinormals) +	if (!mTangents)  	{ -		allocateBinormals(mNumVertices); +		allocateTangents(mNumVertices); -		//generate binormals -		LLVector4a* pos = mPositions; -		LLVector2* tc = (LLVector2*) mTexCoords; -		LLVector4a* binorm = (LLVector4a*) mBinormals; +		//generate tangents +		//LLVector4a* pos = mPositions; +		//LLVector2* tc = (LLVector2*) mTexCoords; +		LLVector4a* binorm = (LLVector4a*) mTangents; -		LLVector4a* end = mBinormals+mNumVertices; +		LLVector4a* end = mTangents+mNumVertices;  		while (binorm < end)  		{  			(*binorm++).clear();  		} -		binorm = mBinormals; +		binorm = mTangents; -		for (U32 i = 0; i < mNumIndices/3; i++)  -		{	//for each triangle -			const U16& i0 = mIndices[i*3+0]; -			const U16& i1 = mIndices[i*3+1]; -			const U16& i2 = mIndices[i*3+2]; -						 -			//calculate binormal -			LLVector4a binormal; -			calc_binormal_from_triangle(binormal, -										pos[i0], tc[i0], -										pos[i1], tc[i1], -										pos[i2], tc[i2]); - - -			//add triangle normal to vertices -			binorm[i0].add(binormal); -			binorm[i1].add(binormal); -			binorm[i2].add(binormal); - -			//even out quad contributions -			if (i % 2 == 0)  -			{ -				binorm[i2].add(binormal); -			} -			else  -			{ -				binorm[i1].add(binormal); -			} -		} +		CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents); -		//normalize binormals +		//normalize tangents  		for (U32 i = 0; i < mNumVertices; i++)   		{ -			binorm[i].normalize3fast(); +			//binorm[i].normalize3fast();  			//bump map/planar projection code requires normals to be normalized  			mNormals[i].normalize3fast();  		} @@ -6652,10 +6624,10 @@ void LLVolumeFace::resizeVertices(S32 num_verts)  {  	ll_aligned_free_16(mPositions);  	ll_aligned_free_16(mNormals); -	ll_aligned_free_16(mBinormals); +	ll_aligned_free_16(mTangents);  	ll_aligned_free_16(mTexCoords); -	mBinormals = NULL; +	mTangents = NULL;  	if (num_verts)  	{ @@ -6705,9 +6677,9 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con  	ll_assert_aligned(mTexCoords,16); -	//just clear binormals -	ll_aligned_free_16(mBinormals); -	mBinormals = NULL; +	//just clear tangents +	ll_aligned_free_16(mTangents); +	mTangents = NULL;  	mPositions[mNumVertices] = pos;  	mNormals[mNumVertices] = norm; @@ -6716,10 +6688,10 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con  	mNumVertices++;	  } -void LLVolumeFace::allocateBinormals(S32 num_verts) +void LLVolumeFace::allocateTangents(S32 num_verts)  { -	ll_aligned_free_16(mBinormals); -	mBinormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); +	ll_aligned_free_16(mTangents); +	mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);  }  void LLVolumeFace::allocateWeights(S32 num_verts) @@ -6956,7 +6928,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  			if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2 && s > 0)  			{ -  				pos[cur_vertex].load3(mesh[i].mPos.mV);  				tc[cur_vertex] = LLVector2(ss,tt); @@ -6987,7 +6958,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  		}  	} -  	//get bounding box for this side  	LLVector4a& face_min = mExtents[0];  	LLVector4a& face_max = mExtents[1]; @@ -7093,6 +7063,14 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  		n[1]->add(c);  		n[2]->add(c); +		llassert(llfinite(c.getF32ptr()[0])); +		llassert(llfinite(c.getF32ptr()[1])); +		llassert(llfinite(c.getF32ptr()[2])); + +		llassert(!llisnan(c.getF32ptr()[0])); +		llassert(!llisnan(c.getF32ptr()[1])); +		llassert(!llisnan(c.getF32ptr()[2])); +  		//even out quad contributions  		n[i%2+1]->add(c);  	} @@ -7231,53 +7209,114 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  	return TRUE;  } -// Finds binormal based on three vertices with texture coordinates. -// Fills in dummy values if the triangle has degenerate texture coordinates. -void calc_binormal_from_triangle(LLVector4a& binormal, +//adapted from Lengyel, Eric. Computing Tangent Space Basis Vectors for an Arbitrary Mesh. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html +void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, +        const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) +{ +    //LLVector4a *tan1 = new LLVector4a[vertexCount * 2]; +	LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); + +    LLVector4a* tan2 = tan1 + vertexCount; + +	memset(tan1, 0, vertexCount*2*sizeof(LLVector4a)); +         +    for (U32 a = 0; a < triangleCount; a++) +    { +        U32 i1 = *index_array++; +        U32 i2 = *index_array++; +        U32 i3 = *index_array++; +         +        const LLVector4a& v1 = vertex[i1]; +        const LLVector4a& v2 = vertex[i2]; +        const LLVector4a& v3 = vertex[i3]; +         +        const LLVector2& w1 = texcoord[i1]; +        const LLVector2& w2 = texcoord[i2]; +        const LLVector2& w3 = texcoord[i3]; +         +		const F32* v1ptr = v1.getF32ptr(); +		const F32* v2ptr = v2.getF32ptr(); +		const F32* v3ptr = v3.getF32ptr(); +		 +        float x1 = v2ptr[0] - v1ptr[0]; +        float x2 = v3ptr[0] - v1ptr[0]; +        float y1 = v2ptr[1] - v1ptr[1]; +        float y2 = v3ptr[1] - v1ptr[1]; +        float z1 = v2ptr[2] - v1ptr[2]; +        float z2 = v3ptr[2] - v1ptr[2]; +         +        float s1 = w2.mV[0] - w1.mV[0]; +        float s2 = w3.mV[0] - w1.mV[0]; +        float t1 = w2.mV[1] - w1.mV[1]; +        float t2 = w3.mV[1] - w1.mV[1]; +         +		F32 rd = s1*t2-s2*t1; + +		float r = ((rd*rd) > FLT_EPSILON) ? 1.0F / rd : 1024.f; //some made up large ratio for division by zero + +		llassert(llfinite(r)); +		llassert(!llisnan(r)); + +		LLVector4a sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, +				(t2 * z1 - t1 * z2) * r); +		LLVector4a tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, +				(s1 * z2 - s2 * z1) * r); +         +		tan1[i1].add(sdir); +		tan1[i2].add(sdir); +		tan1[i3].add(sdir); +         +		tan2[i1].add(tdir); +		tan2[i2].add(tdir); +		tan2[i3].add(tdir); +    } +     +    for (U32 a = 0; a < vertexCount; a++) +    { +        LLVector4a n = normal[a]; + +		const LLVector4a& t = tan1[a]; + +		llassert(tan1[a].getLength3().getF32() >= 0.f); +		llassert(tan2[a].getLength3().getF32() >= 0.f); + +		LLVector4a ncrosst; +		ncrosst.setCross3(n,t); + +        // Gram-Schmidt orthogonalize +        n.mul(n.dot3(t).getF32()); + +		LLVector4a tsubn; +		tsubn.setSub(t,n); + +		if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO) +		{ +			tsubn.normalize3fast(); +		 +			// Calculate handedness +			F32 handedness = ncrosst.dot3(tan2[a]).getF32() < 0.f ? -1.f : 1.f; +		 +			tsubn.getF32ptr()[3] = handedness; -	const LLVector4a& pos0, -	const LLVector2& tex0, -	const LLVector4a& pos1, -	const LLVector2& tex1, -	const LLVector4a& pos2, -	const LLVector2& tex2) -{ -	LLVector4a rx0( pos0[VX], tex0.mV[VX], tex0.mV[VY] ); -	LLVector4a rx1( pos1[VX], tex1.mV[VX], tex1.mV[VY] ); -	LLVector4a rx2( pos2[VX], tex2.mV[VX], tex2.mV[VY] ); -	 -	LLVector4a ry0( pos0[VY], tex0.mV[VX], tex0.mV[VY] ); -	LLVector4a ry1( pos1[VY], tex1.mV[VX], tex1.mV[VY] ); -	LLVector4a ry2( pos2[VY], tex2.mV[VX], tex2.mV[VY] ); +			tangent[a] = tsubn; -	LLVector4a rz0( pos0[VZ], tex0.mV[VX], tex0.mV[VY] ); -	LLVector4a rz1( pos1[VZ], tex1.mV[VX], tex1.mV[VY] ); -	LLVector4a rz2( pos2[VZ], tex2.mV[VX], tex2.mV[VY] ); -	 -	LLVector4a lhs, rhs; +			/* +			These are going off on invalid input and hindering other debugging. +			llassert(llfinite(tangent[a].getF32ptr()[0])); +			llassert(llfinite(tangent[a].getF32ptr()[1])); +			llassert(llfinite(tangent[a].getF32ptr()[2])); -	LLVector4a r0;  -	lhs.setSub(rx0, rx1); rhs.setSub(rx0, rx2); -	r0.setCross3(lhs, rhs); -		 -	LLVector4a r1; -	lhs.setSub(ry0, ry1); rhs.setSub(ry0, ry2); -	r1.setCross3(lhs, rhs); +			llassert(!llisnan(tangent[a].getF32ptr()[0])); +			llassert(!llisnan(tangent[a].getF32ptr()[1])); +			llassert(!llisnan(tangent[a].getF32ptr()[2]));*/ +		} +		else +		{ //degenerate, make up a value +			tangent[a].set(0,0,1,1); +		} +    } +     +	ll_aligned_free_16(tan1); +} -	LLVector4a r2; -	lhs.setSub(rz0, rz1); rhs.setSub(rz0, rz2); -	r2.setCross3(lhs, rhs); -	if( r0[VX] && r1[VX] && r2[VX] ) -	{ -		binormal.set( -				-r0[VZ] / r0[VX], -				-r1[VZ] / r1[VX], -				-r2[VZ] / r2[VX]); -		// binormal.normVec(); -	} -	else -	{ -		binormal.set( 0, 1 , 0 ); -	} -} diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index c845556557..164b8d6652 100755 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -844,12 +844,12 @@ private:  public:  	BOOL create(LLVolume* volume, BOOL partial_build = FALSE); -	void createBinormals(); +	void createTangents();  	void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform);  	void resizeVertices(S32 num_verts); -	void allocateBinormals(S32 num_verts); +	void allocateTangents(S32 num_verts);  	void allocateWeights(S32 num_verts);  	void resizeIndices(S32 num_indices);  	void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx); @@ -916,7 +916,7 @@ public:  	LLVector4a* mPositions;  	LLVector4a* mNormals; -	LLVector4a* mBinormals; +	LLVector4a* mTangents;  	LLVector2*  mTexCoords;  	U16* mIndices; @@ -980,7 +980,7 @@ public:  	void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }  	void regen(); -	void genBinormals(S32 face); +	void genTangents(S32 face);  	BOOL isConvex() const;  	BOOL isCap(S32 face); @@ -1008,21 +1008,14 @@ public:  	//get the face index of the face that intersects with the given line segment at the point   	//closest to start.  Moves end to the point of intersection.  Returns -1 if no intersection.  	//Line segment must be in volume space. -	S32 lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +	S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  							 S32 face = -1,                          // which face to check, -1 = ALL_SIDES -							 LLVector3* intersection = NULL,         // return the intersection point +							 LLVector4a* intersection = NULL,         // return the intersection point  							 LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -							 LLVector3* normal = NULL,               // return the surface normal at the intersection point -							 LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point +							 LLVector4a* normal = NULL,               // return the surface normal at the intersection point +							 LLVector4a* tangent = NULL             // return the surface tangent at the intersection point  		); -	S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  -								   S32 face = 1, -								   LLVector3* intersection = NULL, -								   LLVector2* tex_coord = NULL, -								   LLVector3* normal = NULL, -								   LLVector3* bi_normal = NULL); -	  	LLFaceID generateFaceMask();  	BOOL isFaceMaskValid(LLFaceID face_mask); @@ -1081,21 +1074,12 @@ public:  std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); -void calc_binormal_from_triangle( -		LLVector4a& binormal, -		const LLVector4a& pos0, -		const LLVector2& tex0, -		const LLVector4a& pos1, -		const LLVector2& tex1, -		const LLVector4a& pos2, -		const LLVector2& tex2); -  BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size);  BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size);  BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size); -BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, -							F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided); +//BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, +//							F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided);  BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,  							F32& intersection_a, F32& intersection_b, F32& intersection_t); diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index cc83cb7235..0728b49c1f 100755 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -94,14 +94,14 @@ void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTria  LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,   							   const LLVolumeFace* face, F32* closest_t, -							   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +							   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)     : mFace(face),       mStart(start),  	 mDir(dir),  	 mIntersection(intersection),  	 mTexCoord(tex_coord),  	 mNormal(normal), -	 mBinormal(bi_normal), +	 mTangent(tangent),  	 mClosestT(closest_t),  	 mHitFace(false)  { @@ -112,13 +112,7 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>  {  	LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0); -	/*const F32* start = mStart.getF32(); -	const F32* end = mEnd.getF32(); -	const F32* center = vl->mBounds[0].getF32(); -	const F32* size = vl->mBounds[1].getF32();*/ - -	//if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1])) -	if (LLLineSegmentBoxIntersect(mStart.getF32ptr(), mEnd.getF32ptr(), vl->mBounds[0].getF32ptr(), vl->mBounds[1].getF32ptr())) +	if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1]))  	{  		node->accept(this);  		for (S32 i = 0; i < node->getChildCount(); ++i) @@ -152,34 +146,60 @@ void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* n  					LLVector4a intersect = mDir;  					intersect.mul(*mClosestT);  					intersect.add(mStart); -					mIntersection->set(intersect.getF32ptr()); +					*mIntersection = intersect;  				} +				U32 idx0 = tri->mIndex[0]; +				U32 idx1 = tri->mIndex[1]; +				U32 idx2 = tri->mIndex[2];  				if (mTexCoord != NULL)  				{  					LLVector2* tc = (LLVector2*) mFace->mTexCoords; -					*mTexCoord = ((1.f - a - b)  * tc[tri->mIndex[0]] + -						a              * tc[tri->mIndex[1]] + -						b              * tc[tri->mIndex[2]]); +					*mTexCoord = ((1.f - a - b)  * tc[idx0] + +						a              * tc[idx1] + +						b              * tc[idx2]);  				}  				if (mNormal != NULL)  				{ -					LLVector4* norm = (LLVector4*) mFace->mNormals; - -					*mNormal    = ((1.f - a - b)  * LLVector3(norm[tri->mIndex[0]]) +  -						a              * LLVector3(norm[tri->mIndex[1]]) + -						b              * LLVector3(norm[tri->mIndex[2]])); +					LLVector4a* norm = mFace->mNormals; +								 +					LLVector4a n1,n2,n3; +					n1 = norm[idx0]; +					n1.mul(1.f-a-b); +								 +					n2 = norm[idx1]; +					n2.mul(a); +								 +					n3 = norm[idx2]; +					n3.mul(b); + +					n1.add(n2); +					n1.add(n3); +								 +					*mNormal		= n1;   				} -				if (mBinormal != NULL) +				if (mTangent != NULL)  				{ -					LLVector4* binormal = (LLVector4*) mFace->mBinormals; -					*mBinormal = ((1.f - a - b)  * LLVector3(binormal[tri->mIndex[0]]) +  -							a              * LLVector3(binormal[tri->mIndex[1]]) + -							b              * LLVector3(binormal[tri->mIndex[2]])); +					LLVector4a* tangents = mFace->mTangents; +								 +					LLVector4a t1,t2,t3; +					t1 = tangents[idx0]; +					t1.mul(1.f-a-b); +								 +					t2 = tangents[idx1]; +					t2.mul(a); +								 +					t3 = tangents[idx2]; +					t3.mul(b); + +					t1.add(t2); +					t1.add(t3); +								 +					*mTangent = t1;   				}  			}  		} diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index 9ae34a0c4e..80d6ced36d 100755 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -137,16 +137,16 @@ public:  	LLVector4a mStart;  	LLVector4a mDir;  	LLVector4a mEnd; -	LLVector3* mIntersection; +	LLVector4a* mIntersection;  	LLVector2* mTexCoord; -	LLVector3* mNormal; -	LLVector3* mBinormal; +	LLVector4a* mNormal; +	LLVector4a* mTangent;  	F32* mClosestT;  	bool mHitFace;  	LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,   								   const LLVolumeFace* face, F32* closest_t, -								   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal); +								   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent);  	void traverse(const LLOctreeNode<LLVolumeTriangle>* node); diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index e7147253e7..5740584edb 100755 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -248,7 +248,7 @@ if (LL_TESTS)      ${LLVFS_LIBRARIES}      ${LLMATH_LIBRARIES}      ${LLCOMMON_LIBRARIES} -    ${GOOGLEMOCK_LIBRARIES} +      ${GOOGLEMOCK_LIBRARIES}      )    LL_ADD_INTEGRATION_TEST( diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp index 5a67035ed1..7f74247a13 100755 --- a/indra/llmessage/llares.cpp +++ b/indra/llmessage/llares.cpp @@ -99,8 +99,7 @@ void LLAres::QueryResponder::queryError(int code)  LLAres::LLAres() :      chan_(NULL), -    mInitSuccess(false), -    mListener(new LLAresListener(this)) +    mInitSuccess(false)  {  	if (ares_library_init( ARES_LIB_INIT_ALL ) != ARES_SUCCESS ||  		ares_init(&chan_) != ARES_SUCCESS) @@ -109,6 +108,8 @@ LLAres::LLAres() :  		return;  	} +	mListener = boost::shared_ptr< LLAresListener >(new LLAresListener(this)); +  	mInitSuccess = true;  } @@ -161,12 +162,26 @@ void LLAres::getSrvRecords(const std::string &name, SrvResponder *resp)  }  void LLAres::rewriteURI(const std::string &uri, UriRewriteResponder *resp) -{ -	llinfos << "Rewriting " << uri << llendl; +{	 +	if (resp && uri.size()) +	{ +		LLURI* pURI = new LLURI(uri); + +		resp->mUri = *pURI; + +		delete pURI; + +		if (!resp->mUri.scheme().size() || !resp->mUri.hostName().size()) +		{ +			return; +		} + +		//llinfos << "LLAres::rewriteURI (" << uri << ") search: '" << "_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName() << "'" << llendl; -	resp->mUri = LLURI(uri); -	search("_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName(), -		   RES_SRV, resp); +		search("_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName(), RES_SRV, resp); + +		 +	}  }  LLQueryResponder::LLQueryResponder() diff --git a/indra/llmessage/llareslistener.cpp b/indra/llmessage/llareslistener.cpp index 58b8a05a9e..0a4effac19 100755 --- a/indra/llmessage/llareslistener.cpp +++ b/indra/llmessage/llareslistener.cpp @@ -93,5 +93,12 @@ private:  void LLAresListener::rewriteURI(const LLSD& data)  { -    mAres->rewriteURI(data["uri"], new UriRewriteResponder(data)); +	if (mAres) +	{ +		mAres->rewriteURI(data["uri"], new UriRewriteResponder(data)); +	} +	else +	{ +		llinfos << "LLAresListener::rewriteURI requested without Ares present. Ignoring: " << data << llendl; +	}  } diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 3561459bb4..6110b035dc 100755 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -224,7 +224,7 @@ static void request(  	{  		if (responder)  		{ -			responder->completed(U32_MAX, "No pump", LLSD()); +		responder->completed(U32_MAX, "No pump", LLSD());  		}  		delete body_injector;  		return; @@ -238,9 +238,9 @@ static void request(  		{  			responder->completed(498, "Internal Error - curl failure", LLSD());  		} -		delete req; +		delete req ;  		delete body_injector; -		return; +		return ;  	}  	req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req); diff --git a/indra/llmessage/llhttpclientadapter.cpp b/indra/llmessage/llhttpclientadapter.cpp index 0b59209af1..dcd2d79d67 100755 --- a/indra/llmessage/llhttpclientadapter.cpp +++ b/indra/llmessage/llhttpclientadapter.cpp @@ -45,8 +45,8 @@ void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr respo  	LLSD empty_pragma_header = headers;  	if (!empty_pragma_header.has("Pragma"))  	{ -		// as above -		empty_pragma_header["Pragma"] = " "; +	// as above +	empty_pragma_header["Pragma"] = " ";  	}  	LLHTTPClient::get(url, responder, empty_pragma_header);  } diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 627d591839..de9e2fe294 100755 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -314,11 +314,11 @@ LLIOPipe::EStatus LLURLRequest::process_impl(  		 const F32 TIMEOUT_ADJUSTMENT = 2.0f;  		 mDetail->mByteAccumulator = 0;  		 pump->adjustTimeoutSeconds(TIMEOUT_ADJUSTMENT); -		 lldebugs << "LLURLRequest adjustTimeoutSeconds for request: " << mDetail->mURL << llendl; -		 if (mState == STATE_INITIALIZED) -		 { -			  llinfos << "LLURLRequest adjustTimeoutSeconds called during upload" << llendl; -		 } +		lldebugs << "LLURLRequest adjustTimeoutSeconds for request: " << mDetail->mURL << llendl; +		if (mState == STATE_INITIALIZED) +		{ +			llinfos << "LLURLRequest adjustTimeoutSeconds called during upload" << llendl; +		}  	}  	switch(mState) diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp index 87cbafa404..559001d079 100755 --- a/indra/llmessage/tests/llhttpclient_test.cpp +++ b/indra/llmessage/tests/llhttpclient_test.cpp @@ -241,7 +241,7 @@ namespace tut  		ensureStatusOK();  		ensure_equals("echoed result matches", getResult(), sd);  	} -		 +  	template<> template<>  		void HTTPClientTestObject::test<4>()  	{ diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 1768a06a27..0dd13916bf 100755 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -24,6 +24,8 @@ include_directories(SYSTEM      )  set(llprimitive_SOURCE_FILES +    llmaterialid.cpp +    llmaterial.cpp      llmaterialtable.cpp      llmediaentry.cpp      llmodel.cpp @@ -41,6 +43,8 @@ set(llprimitive_HEADER_FILES      CMakeLists.txt      legacy_object_types.h +    llmaterial.h +    llmaterialid.h      llmaterialtable.h      llmediaentry.h      llmodel.h diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp new file mode 100644 index 0000000000..cf4c645cfd --- /dev/null +++ b/indra/llprimitive/llmaterial.cpp @@ -0,0 +1,227 @@ +/** + * @file llmaterial.cpp + * @brief Material definition + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llmaterial.h" + +/** + * Materials cap parameters + */ +#define MATERIALS_CAP_NORMAL_MAP_FIELD            "NormMap" +#define MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD   "NormOffsetX" +#define MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD   "NormOffsetY" +#define MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD   "NormRepeatX" +#define MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD   "NormRepeatY" +#define MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD   "NormRotation" + +#define MATERIALS_CAP_SPECULAR_MAP_FIELD          "SpecMap" +#define MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD "SpecOffsetX" +#define MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD "SpecOffsetY" +#define MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD "SpecRepeatX" +#define MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD "SpecRepeatY" +#define MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD "SpecRotation" + +#define MATERIALS_CAP_SPECULAR_COLOR_FIELD        "SpecColor" +#define MATERIALS_CAP_SPECULAR_EXP_FIELD          "SpecExp" +#define MATERIALS_CAP_ENV_INTENSITY_FIELD         "EnvIntensity" +#define MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD     "AlphaMaskCutoff" +#define MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD    "DiffuseAlphaMode" + +const LLColor4U LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR(255,255,255,255); + +/** + * Materials constants + */ + +const F32 MATERIALS_MULTIPLIER                   = 10000.f; + +/** + * Helper functions + */ + +template<typename T> T getMaterialField(const LLSD& data, const std::string& field, const LLSD::Type field_type) +{ +	if ( (data.has(field)) && (field_type == data[field].type()) ) +	{ +		return (T)data[field]; +	} +	llerrs << "Missing or mistyped field '" << field << "' in material definition" << llendl; +	return (T)LLSD(); +} + +// GCC didn't like the generic form above for some reason +template<> LLUUID getMaterialField(const LLSD& data, const std::string& field, const LLSD::Type field_type) +{ +	if ( (data.has(field)) && (field_type == data[field].type()) ) +	{ +		return data[field].asUUID(); +	} +	llerrs << "Missing or mistyped field '" << field << "' in material definition" << llendl; +	return LLUUID::null; +} + +/** + * LLMaterial class + */ + +const LLMaterial LLMaterial::null; + +LLMaterial::LLMaterial() +	: mNormalOffsetX(0.0f) +	, mNormalOffsetY(0.0f) +	, mNormalRepeatX(1.0f) +	, mNormalRepeatY(1.0f) +	, mNormalRotation(0.0f) +	, mSpecularOffsetX(0.0f) +	, mSpecularOffsetY(0.0f) +	, mSpecularRepeatX(1.0f) +	, mSpecularRepeatY(1.0f) +	, mSpecularRotation(0.0f) +	, mSpecularLightColor(LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR) +	, mSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT) +	, mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY) +	, mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) +	, mAlphaMaskCutoff(0) +{ +} + +LLMaterial::LLMaterial(const LLSD& material_data) +{ +	fromLLSD(material_data); +} + +LLSD LLMaterial::asLLSD() const +{ +	LLSD material_data; + +	material_data[MATERIALS_CAP_NORMAL_MAP_FIELD] = mNormalID; +	material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD] = llround(mNormalOffsetX * MATERIALS_MULTIPLIER); +	material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD] = llround(mNormalOffsetY * MATERIALS_MULTIPLIER); +	material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD] = llround(mNormalRepeatX * MATERIALS_MULTIPLIER); +	material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD] = llround(mNormalRepeatY * MATERIALS_MULTIPLIER); +	material_data[MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD] = llround(mNormalRotation * MATERIALS_MULTIPLIER); + +	material_data[MATERIALS_CAP_SPECULAR_MAP_FIELD] = mSpecularID; +	material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD] = llround(mSpecularOffsetX * MATERIALS_MULTIPLIER); +	material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD] = llround(mSpecularOffsetY * MATERIALS_MULTIPLIER); +	material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD] = llround(mSpecularRepeatX * MATERIALS_MULTIPLIER); +	material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD] = llround(mSpecularRepeatY * MATERIALS_MULTIPLIER); +	material_data[MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD] = llround(mSpecularRotation * MATERIALS_MULTIPLIER); + +	material_data[MATERIALS_CAP_SPECULAR_COLOR_FIELD]     = mSpecularLightColor.getValue(); +	material_data[MATERIALS_CAP_SPECULAR_EXP_FIELD]       = mSpecularLightExponent; +	material_data[MATERIALS_CAP_ENV_INTENSITY_FIELD]      = mEnvironmentIntensity; +	material_data[MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD] = mDiffuseAlphaMode; +	material_data[MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD]  = mAlphaMaskCutoff; + +	return material_data; +} + +void LLMaterial::fromLLSD(const LLSD& material_data) +{ +	mNormalID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_NORMAL_MAP_FIELD, LLSD::TypeUUID); +	mNormalOffsetX  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; +	mNormalOffsetY  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; +	mNormalRepeatX  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; +	mNormalRepeatY  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; +	mNormalRotation = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; + +	mSpecularID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_SPECULAR_MAP_FIELD, LLSD::TypeUUID); +	mSpecularOffsetX  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; +	mSpecularOffsetY  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; +	mSpecularRepeatX  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; +	mSpecularRepeatY  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; +	mSpecularRotation = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; + +	mSpecularLightColor.setValue(getMaterialField<LLSD>(material_data, MATERIALS_CAP_SPECULAR_COLOR_FIELD, LLSD::TypeArray)); +	mSpecularLightExponent = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_EXP_FIELD,       LLSD::TypeInteger); +	mEnvironmentIntensity  = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ENV_INTENSITY_FIELD,      LLSD::TypeInteger); +	mDiffuseAlphaMode      = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD, LLSD::TypeInteger); +	mAlphaMaskCutoff       = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD,  LLSD::TypeInteger); +} + +bool LLMaterial::isNull() const +{ +	return (*this == null); +} + +bool LLMaterial::operator == (const LLMaterial& rhs) const +{ +	return  +		(mNormalID == rhs.mNormalID) && (mNormalOffsetX == rhs.mNormalOffsetX) && (mNormalOffsetY == rhs.mNormalOffsetY) && +		(mNormalRepeatX == rhs.mNormalRepeatX) && (mNormalRepeatY == rhs.mNormalRepeatY) && (mNormalRotation == rhs.mNormalRotation) && +		(mSpecularID == rhs.mSpecularID) && (mSpecularOffsetX == rhs.mSpecularOffsetX) && (mSpecularOffsetY == rhs.mSpecularOffsetY) && +		(mSpecularRepeatX == rhs.mSpecularRepeatX) && (mSpecularRepeatY == rhs.mSpecularRepeatY) && (mSpecularRotation == rhs.mSpecularRotation) && +		(mSpecularLightColor == rhs.mSpecularLightColor) && (mSpecularLightExponent == rhs.mSpecularLightExponent) && +		(mEnvironmentIntensity == rhs.mEnvironmentIntensity) && (mDiffuseAlphaMode == rhs.mDiffuseAlphaMode) && (mAlphaMaskCutoff == rhs.mAlphaMaskCutoff); +} + +bool LLMaterial::operator != (const LLMaterial& rhs) const +{ +	return !(*this == rhs); +} + + +U32 LLMaterial::getShaderMask(U32 alpha_mode) +{ //NEVER incorporate this value into the message system -- this function will vary depending on viewer implementation +	U32 ret = 0; + +	//two least significant bits are "diffuse alpha mode" +	if (alpha_mode != DIFFUSE_ALPHA_MODE_DEFAULT) +	{ +		ret = alpha_mode; +	} +	else +	{ +		ret = getDiffuseAlphaMode(); +	} + +	llassert(ret < SHADER_COUNT); + +	//next bit is whether or not specular map is present +	const U32 SPEC_BIT = 0x4; + +	if (getSpecularID().notNull()) +	{ +		ret |= SPEC_BIT; +	} + +	llassert(ret < SHADER_COUNT); +	 +	//next bit is whether or not normal map is present +	const U32 NORM_BIT = 0x8; +	if (getNormalID().notNull()) +	{ +		ret |= NORM_BIT; +	} + +	llassert(ret < SHADER_COUNT); + +	return ret; +} + + diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h new file mode 100644 index 0000000000..9f52a3f6c1 --- /dev/null +++ b/indra/llprimitive/llmaterial.h @@ -0,0 +1,155 @@ +/** + * @file llmaterial.h + * @brief Material definition + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLMATERIAL_H +#define LL_LLMATERIAL_H + +#include <boost/shared_ptr.hpp> + +#include "llmaterialid.h" +#include "llsd.h" +#include "v4coloru.h" +#include "llpointer.h" +#include "llrefcount.h" + +class LLMaterial : public LLRefCount +{ +public: + +	typedef enum +	{ +		DIFFUSE_ALPHA_MODE_NONE = 0, +		DIFFUSE_ALPHA_MODE_BLEND = 1, +		DIFFUSE_ALPHA_MODE_MASK = 2, +		DIFFUSE_ALPHA_MODE_EMISSIVE = 3, +		DIFFUSE_ALPHA_MODE_DEFAULT = 4, +	} eDiffuseAlphaMode; + +	typedef enum +	{ +		SHADER_COUNT = 16, +		ALPHA_SHADER_COUNT = 4 +	} eShaderCount; + +	 +	 +	static const U8			DEFAULT_SPECULAR_LIGHT_EXPONENT = ((U8)(0.2f * 255)); +	static const LLColor4U	DEFAULT_SPECULAR_LIGHT_COLOR; +	static const U8			DEFAULT_ENV_INTENSITY = 0; + +	LLMaterial(); +	LLMaterial(const LLSD& material_data); + +	LLSD asLLSD() const; +	void fromLLSD(const LLSD& material_data); + +	const LLUUID& getNormalID() const { return mNormalID; } +	void		setNormalID(const LLUUID& normal_id) { mNormalID = normal_id; } +	void		getNormalOffset(F32& offset_x, F32& offset_y) const { offset_x = mNormalOffsetX; offset_y = mNormalOffsetY; } +	F32		getNormalOffsetX() const { return mNormalOffsetX; } +	F32		getNormalOffsetY() const { return mNormalOffsetY; } + +	void		setNormalOffset(F32 offset_x, F32 offset_y) { mNormalOffsetX = offset_x; mNormalOffsetY = offset_y; } +	void		setNormalOffsetX(F32 offset_x) { mNormalOffsetX = offset_x; } +	void		setNormalOffsetY(F32 offset_y) { mNormalOffsetY = offset_y; } + +	void		getNormalRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mNormalRepeatX; repeat_y = mNormalRepeatY; } +	F32		getNormalRepeatX() const { return mNormalRepeatX; } +	F32		getNormalRepeatY() const { return mNormalRepeatY; } + +	void		setNormalRepeat(F32 repeat_x, F32 repeat_y) { mNormalRepeatX = repeat_x; mNormalRepeatY = repeat_y; } +	void		setNormalRepeatX(F32 repeat_x) { mNormalRepeatX = repeat_x; } +	void		setNormalRepeatY(F32 repeat_y) { mNormalRepeatY = repeat_y; } + +	F32		getNormalRotation() const { return mNormalRotation; } +	void		setNormalRotation(F32 rot) { mNormalRotation = rot; } + +	const LLUUID& getSpecularID() const { return mSpecularID; } +	void		setSpecularID(const LLUUID& specular_id)  { mSpecularID = specular_id; } +	void		getSpecularOffset(F32& offset_x, F32& offset_y) const { offset_x = mSpecularOffsetX; offset_y = mSpecularOffsetY; } +	F32		getSpecularOffsetX() const { return mSpecularOffsetX; } +	F32		getSpecularOffsetY() const { return mSpecularOffsetY; } + +	void		setSpecularOffset(F32 offset_x, F32 offset_y) { mSpecularOffsetX = offset_x; mSpecularOffsetY = offset_y; } +	void		setSpecularOffsetX(F32 offset_x) { mSpecularOffsetX = offset_x; } +	void		setSpecularOffsetY(F32 offset_y) { mSpecularOffsetY = offset_y; } + +	void		getSpecularRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mSpecularRepeatX; repeat_y = mSpecularRepeatY; } +	F32		getSpecularRepeatX() const { return mSpecularRepeatX; } +	F32		getSpecularRepeatY() const { return mSpecularRepeatY; } + +	void		setSpecularRepeat(F32 repeat_x, F32 repeat_y) { mSpecularRepeatX = repeat_x; mSpecularRepeatY = repeat_y; } +	void		setSpecularRepeatX(F32 repeat_x) { mSpecularRepeatX = repeat_x; } +	void		setSpecularRepeatY(F32 repeat_y) { mSpecularRepeatY = repeat_y; } + +	F32		getSpecularRotation() const { return mSpecularRotation; } +	void		setSpecularRotation(F32 rot) { mSpecularRotation = rot; } + +	const LLColor4U getSpecularLightColor() const { return mSpecularLightColor; } +	void		setSpecularLightColor(const LLColor4U& color) { mSpecularLightColor = color; } +	U8			getSpecularLightExponent() const { return mSpecularLightExponent; } +	void		setSpecularLightExponent(U8 exponent) { mSpecularLightExponent = exponent; } +	U8			getEnvironmentIntensity() const { return mEnvironmentIntensity; } +	void		setEnvironmentIntensity(U8 intensity) { mEnvironmentIntensity = intensity; } +	U8			getDiffuseAlphaMode() const { return mDiffuseAlphaMode; } +	void		setDiffuseAlphaMode(U8 alpha_mode) { mDiffuseAlphaMode = alpha_mode; } +	U8			getAlphaMaskCutoff() const { return mAlphaMaskCutoff; } +	void		setAlphaMaskCutoff(U8 cutoff) { mAlphaMaskCutoff = cutoff; } + +	bool		isNull() const; +	static const LLMaterial null; + +	bool		operator == (const LLMaterial& rhs) const; +	bool		operator != (const LLMaterial& rhs) const; + +	U32			getShaderMask(U32 alpha_mode = DIFFUSE_ALPHA_MODE_DEFAULT); + +protected: +	LLUUID		mNormalID; +	F32			mNormalOffsetX; +	F32			mNormalOffsetY; +	F32			mNormalRepeatX; +	F32			mNormalRepeatY; +	F32			mNormalRotation; + +	LLUUID		mSpecularID; +	F32			mSpecularOffsetX; +	F32			mSpecularOffsetY; +	F32			mSpecularRepeatX; +	F32			mSpecularRepeatY; +	F32			mSpecularRotation; + +	LLColor4U	mSpecularLightColor; +	U8			mSpecularLightExponent; +	U8			mEnvironmentIntensity; +	U8			mDiffuseAlphaMode; +	U8			mAlphaMaskCutoff; +}; + +typedef LLPointer<LLMaterial> LLMaterialPtr; + +#endif // LL_LLMATERIAL_H + diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp new file mode 100644 index 0000000000..820f62c43c --- /dev/null +++ b/indra/llprimitive/llmaterialid.cpp @@ -0,0 +1,183 @@ +/**  +* @file llmaterialid.cpp +* @brief Implementation of llmaterialid +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#include "linden_common.h" + +#include "llmaterialid.h" + +#include <string> + +#include "llformat.h" + +const LLMaterialID LLMaterialID::null; + +LLMaterialID::LLMaterialID() +{ +	clear(); +} + +LLMaterialID::LLMaterialID(const LLSD& pMaterialID) +{ +	llassert(pMaterialID.isBinary()); +	parseFromBinary(pMaterialID.asBinary()); +} + +LLMaterialID::LLMaterialID(const LLSD::Binary& pMaterialID) +{ +	parseFromBinary(pMaterialID); +} + +LLMaterialID::LLMaterialID(const void* pMemory) +{ +	set(pMemory); +} + +LLMaterialID::LLMaterialID(const LLMaterialID& pOtherMaterialID) +{ +	copyFromOtherMaterialID(pOtherMaterialID); +} + +LLMaterialID::~LLMaterialID() +{ +} + +bool LLMaterialID::operator == (const LLMaterialID& pOtherMaterialID) const +{ +	return (compareToOtherMaterialID(pOtherMaterialID) == 0); +} + +bool LLMaterialID::operator != (const LLMaterialID& pOtherMaterialID) const +{ +	return (compareToOtherMaterialID(pOtherMaterialID) != 0); +} + +bool LLMaterialID::operator < (const LLMaterialID& pOtherMaterialID) const +{ +	return (compareToOtherMaterialID(pOtherMaterialID) < 0); +} + +bool LLMaterialID::operator <= (const LLMaterialID& pOtherMaterialID) const +{ +	return (compareToOtherMaterialID(pOtherMaterialID) <= 0); +} + +bool LLMaterialID::operator > (const LLMaterialID& pOtherMaterialID) const +{ +	return (compareToOtherMaterialID(pOtherMaterialID) > 0); +} + +bool LLMaterialID::operator >= (const LLMaterialID& pOtherMaterialID) const +{ +	return (compareToOtherMaterialID(pOtherMaterialID) >= 0); +} + +LLMaterialID& LLMaterialID::operator = (const LLMaterialID& pOtherMaterialID) +{ +	copyFromOtherMaterialID(pOtherMaterialID); +	return (*this); +} + +bool LLMaterialID::isNull() const +{ +	return (compareToOtherMaterialID(LLMaterialID::null) == 0); +} + +const U8* LLMaterialID::get() const +{ +	return mID; +} + +void LLMaterialID::set(const void* pMemory) +{ +	llassert(pMemory != NULL); + +	// assumes that the required size of memory is available +	memcpy(mID, pMemory, MATERIAL_ID_SIZE * sizeof(U8)); +} + +void LLMaterialID::clear() +{ +	memset(mID, 0, MATERIAL_ID_SIZE * sizeof(U8)); +} + +LLSD LLMaterialID::asLLSD() const +{ +	LLSD::Binary materialIDBinary; + +	materialIDBinary.resize(MATERIAL_ID_SIZE * sizeof(U8)); +	memcpy(materialIDBinary.data(), mID, MATERIAL_ID_SIZE * sizeof(U8)); + +	LLSD materialID = materialIDBinary; +	return materialID; +} + +std::string LLMaterialID::asString() const +{ +	std::string materialIDString; +	for (unsigned int i = 0U; i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32)); ++i) +	{ +		if (i != 0U) +		{ +			materialIDString += "-"; +		} +		const U32 *value = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]); +		materialIDString += llformat("%08x", *value); +	} +	return materialIDString; +} + +std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id) +{ +	s << material_id.asString(); +	return s; +} + + +void LLMaterialID::parseFromBinary (const LLSD::Binary& pMaterialID) +{ +	llassert(pMaterialID.size() == (MATERIAL_ID_SIZE * sizeof(U8))); +	memcpy(mID, &pMaterialID[0], MATERIAL_ID_SIZE * sizeof(U8)); +} + +void LLMaterialID::copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID) +{ +	memcpy(mID, pOtherMaterialID.get(), MATERIAL_ID_SIZE * sizeof(U8)); +} + +int LLMaterialID::compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const +{ +	int retVal = 0; + +	for (unsigned int i = 0U; (retVal == 0) && (i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32))); ++i) +	{ +		const U32 *thisValue = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]); +		const U32 *otherValue = reinterpret_cast<const U32*>(&pOtherMaterialID.get()[i * sizeof(U32)]); +		retVal = ((*thisValue < *otherValue) ? -1 : ((*thisValue > *otherValue) ? 1 : 0)); +	} + +	return retVal; +} diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h new file mode 100644 index 0000000000..0a95204085 --- /dev/null +++ b/indra/llprimitive/llmaterialid.h @@ -0,0 +1,76 @@ +/**  +* @file   llmaterialid.h +* @brief  Header file for llmaterialid +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ +#ifndef LL_LLMATERIALID_H +#define LL_LLMATERIALID_H + +#define MATERIAL_ID_SIZE 16 + +#include <string> + +class LLMaterialID +{ +public: +	LLMaterialID(); +	LLMaterialID(const LLSD& pMaterialID); +	LLMaterialID(const LLSD::Binary& pMaterialID); +	LLMaterialID(const void* pMemory); +	LLMaterialID(const LLMaterialID& pOtherMaterialID); +	~LLMaterialID(); + +	bool          operator == (const LLMaterialID& pOtherMaterialID) const; +	bool          operator != (const LLMaterialID& pOtherMaterialID) const; + +	bool          operator < (const LLMaterialID& pOtherMaterialID) const; +	bool          operator <= (const LLMaterialID& pOtherMaterialID) const; +	bool          operator > (const LLMaterialID& pOtherMaterialID) const; +	bool          operator >= (const LLMaterialID& pOtherMaterialID) const; + +	LLMaterialID& operator = (const LLMaterialID& pOtherMaterialID); + +	bool          isNull() const; + +	const U8*     get() const; +	void          set(const void* pMemory); +	void          clear(); + +	LLSD          asLLSD() const; +	std::string   asString() const; + +	friend std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id); + +	static const LLMaterialID null; + +private: +	void parseFromBinary(const LLSD::Binary& pMaterialID); +	void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID); +	int  compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const; + +	U8 mID[MATERIAL_ID_SIZE]; +} ; + +#endif // LL_LLMATERIALID_H + diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index c340fc2d35..2fa77177f5 100755 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -39,6 +39,7 @@  #include "llsdutil_math.h"  #include "llprimtexturelist.h"  #include "imageids.h" +#include "llmaterialid.h"  /**   * exported constants @@ -314,6 +315,15 @@ S32  LLPrimitive::setTERotation(const U8 index, const F32 r)  	return mTextureList.setRotation(index, r);  } +S32 LLPrimitive::setTEMaterialID(const U8 index, const LLMaterialID& pMaterialID) +{ +	return mTextureList.setMaterialID(index, pMaterialID); +} + +S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams) +{ +	return mTextureList.setMaterialParams(index, pMaterialParams); +}  //===============================================================  S32  LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump) @@ -364,6 +374,23 @@ S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow)  	return mTextureList.setGlow(index, glow);  } +void LLPrimitive::setAllTESelected(bool sel) +{ +	for (int i = 0, cnt = getNumTEs(); i < cnt; i++) +	{ +		setTESelected(i, sel); +	} +} +	 +void LLPrimitive::setTESelected(const U8 te, bool sel) +{ +	LLTextureEntry* tep = getTE(te); +	if ( (tep) && (tep->setSelected(sel)) && (!sel) && (tep->hasPendingMaterialUpdate()) ) +	{ +		LLMaterialID material_id = tep->getMaterialID(); +		setTEMaterialID(te, material_id); +	} +}  LLPCode LLPrimitive::legacyToPCode(const U8 legacy)  { @@ -1044,7 +1071,7 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat  	while ((cur_ptr < buffer_end) && (*cur_ptr != 0))  	{ -//		llinfos << "TE exception" << llendl; +		LL_DEBUGS("TEFieldDecode") << "TE exception" << LL_ENDL;  		i = 0;  		while (*cur_ptr & 0x80)  		{ @@ -1059,14 +1086,16 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat  			if (i & 0x01)  			{  				htonmemcpy(data_ptr+(j*data_size),cur_ptr,type,data_size); -//				char foo[64]; -//				sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1)); -//				llinfos << "Assigning " << foo << " to face " << j << llendl;			 +				LL_DEBUGS("TEFieldDecode") << "Assigning " ; +				char foo[64]; +				sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1)); +				LL_CONT << foo << " to face " << j << LL_ENDL;  			}  			i = i >> 1;  		}  		cur_ptr += data_size;		  	} +	llassert(cur_ptr <= buffer_end); // buffer underrun  	return (S32)(cur_ptr - start_loc);  } @@ -1088,6 +1117,7 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const  	U8	   bump[MAX_TES];  	U8	   media_flags[MAX_TES];      U8     glow[MAX_TES]; +	U8     material_data[MAX_TES*16];  	const U32 MAX_TE_BUFFER = 4096;  	U8 packed_buffer[MAX_TE_BUFFER]; @@ -1125,6 +1155,9 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const  			bump[face_index] = te->getBumpShinyFullbright();  			media_flags[face_index] = te->getMediaTexGen();  			glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF)); + +			// Directly sending material_ids is not safe! +			memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16);	/* Flawfinder: ignore */   		}  		cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID); @@ -1146,6 +1179,8 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const  		cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);  		*cur_ptr++ = 0;  		cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8); +		*cur_ptr++ = 0; +		cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);  	}     	mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer)); @@ -1167,6 +1202,7 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const  	U8	   bump[MAX_TES];  	U8	   media_flags[MAX_TES];      U8     glow[MAX_TES]; +	U8     material_data[MAX_TES*16];  	const U32 MAX_TE_BUFFER = 4096;  	U8 packed_buffer[MAX_TE_BUFFER]; @@ -1204,6 +1240,9 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const  			bump[face_index] = te->getBumpShinyFullbright();  			media_flags[face_index] = te->getMediaTexGen();              glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF)); + +			// Directly sending material_ids is not safe! +			memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16);	/* Flawfinder: ignore */   		}  		cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID); @@ -1225,6 +1264,8 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const  		cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);  		*cur_ptr++ = 0;  		cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8); +		*cur_ptr++ = 0; +		cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);  	}  	dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry"); @@ -1234,6 +1275,9 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const  S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec)  {  	S32 retval = 0; +   // temp buffer for material ID processing +   // data will end up in tec.material_id[]	 +   U8 material_data[LLTEContents::MAX_TES*16];  	if (block_num < 0)  	{ @@ -1282,14 +1326,29 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name  	cur_ptr++;  	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.glow, 1, tec.face_count, MVT_U8); +	if (cur_ptr < tec.packed_buffer + tec.size) +	{ +		cur_ptr++; +		cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)material_data, 16, tec.face_count, MVT_LLUUID); +	} +	else +	{ +		memset(material_data, 0, sizeof(material_data)); +	} +	 +	for (U32 i = 0; i < tec.face_count; i++) +	{ +		tec.material_ids[i].set(&material_data[i * 16]); +	} +	  	retval = 1;  	return retval; -} - +	} +	  S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec)  {  	S32 retval = 0; - +	  	LLColor4 color;  	LLColor4U coloru;  	for (U32 i = 0; i < tec.face_count; i++) @@ -1302,6 +1361,9 @@ S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec)  		retval |= setTEBumpShinyFullbright(i, tec.bump[i]);  		retval |= setTEMediaTexGen(i, tec.media_flags[i]);  		retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF); +		 +                retval |= setTEMaterialID(i, tec.material_ids[i]); +		  		coloru = LLColor4U(tec.colors + 4*i);  		// Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) @@ -1336,6 +1398,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)  	// Avoid construction of 32 UUIDs per call  	static LLUUID image_ids[MAX_TES]; +	static LLMaterialID material_ids[MAX_TES];  	U8     image_data[MAX_TES*16];  	U8	   colors[MAX_TES*4]; @@ -1347,6 +1410,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)  	U8	   bump[MAX_TES];  	U8	   media_flags[MAX_TES];      U8     glow[MAX_TES]; +	U8     material_data[MAX_TES*16];  	const U32 MAX_TE_BUFFER = 4096;  	U8 packed_buffer[MAX_TE_BUFFER]; @@ -1389,10 +1453,20 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)  	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);  	cur_ptr++;  	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8); +	if (cur_ptr < packed_buffer + size) +	{ +		cur_ptr++; +		cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)material_data, 16, face_count, MVT_LLUUID); +	} +	else +	{ +		memset(material_data, 0, sizeof(material_data)); +	}  	for (i = 0; i < face_count; i++)  	{  		memcpy(image_ids[i].mData,&image_data[i*16],16);	/* Flawfinder: ignore */ 	 +		material_ids[i].set(&material_data[i * 16]);  	}  	LLColor4 color; @@ -1406,6 +1480,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)  		retval |= setTEBumpShinyFullbright(i, bump[i]);  		retval |= setTEMediaTexGen(i, media_flags[i]);  		retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF); +		retval |= setTEMaterialID(i, material_ids[i]);  		coloru = LLColor4U(colors + 4*i);  		// Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 6a8b59c81c..47a21beaaf 100755 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -42,6 +42,7 @@ class LLMessageSystem;  class LLVolumeParams;  class LLColor4;  class LLColor3; +class LLMaterialID;  class LLTextureEntry;  class LLDataPacker;  class LLVolumeMgr; @@ -309,7 +310,8 @@ struct LLTEContents  	U8	   bump[MAX_TES];  	U8	   media_flags[MAX_TES];      U8     glow[MAX_TES]; -	 +	LLMaterialID material_ids[MAX_TES]; +  	static const U32 MAX_TE_BUFFER = 4096;  	U8 packed_buffer[MAX_TE_BUFFER]; @@ -359,6 +361,7 @@ public:  	LLTextureEntry* getTE(const U8 te_num) const;  	virtual void setNumTEs(const U8 num_tes); +	virtual void setAllTESelected(bool sel);  	virtual void setAllTETextures(const LLUUID &tex_id);  	virtual void setTE(const U8 index, const LLTextureEntry& te);  	virtual S32 setTEColor(const U8 te, const LLColor4 &color); @@ -381,7 +384,10 @@ public:  	virtual S32 setTEFullbright(const U8 te, const U8 fullbright);  	virtual S32 setTEMediaFlags(const U8 te, const U8 flags);  	virtual S32 setTEGlow(const U8 te, const F32 glow); +	virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); +	virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);  	virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed +	virtual void setTESelected(const U8 te, bool sel);  	void copyTEs(const LLPrimitive *primitive);  	S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const; diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp index 7ef87ed382..537e7a6695 100755 --- a/indra/llprimitive/llprimtexturelist.cpp +++ b/indra/llprimitive/llprimtexturelist.cpp @@ -27,6 +27,7 @@  #include "linden_common.h"  #include "llprimtexturelist.h" +#include "llmaterialid.h"  #include "lltextureentry.h"  // static  @@ -358,6 +359,24 @@ S32 LLPrimTextureList::setGlow(const U8 index, const F32 glow)  	return TEM_CHANGE_NONE;  } +S32 LLPrimTextureList::setMaterialID(const U8 index, const LLMaterialID& pMaterialID) +{ +	if (index < mEntryList.size()) +	{ +		return mEntryList[index]->setMaterialID(pMaterialID); +	} +	return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams) +{ +	if (index < mEntryList.size()) +	{ +		return mEntryList[index]->setMaterialParams(pMaterialParams); +	} +	return TEM_CHANGE_NONE; +} +  S32 LLPrimTextureList::size() const  {  	return mEntryList.size(); diff --git a/indra/llprimitive/llprimtexturelist.h b/indra/llprimitive/llprimtexturelist.h index 3cfa52f1d5..d7fabbbb79 100755 --- a/indra/llprimitive/llprimtexturelist.h +++ b/indra/llprimitive/llprimtexturelist.h @@ -31,9 +31,11 @@  #include "lluuid.h"  #include "v3color.h"  #include "v4color.h" +#include "llmaterial.h"  class LLTextureEntry; +class LLMaterialID;  // this is a list of LLTextureEntry*'s because in practice the list's elements  // are of some derived class: LLFooTextureEntry @@ -102,6 +104,8 @@ public:  	S32 setFullbright(const U8 index, const U8 t);  	S32 setMediaFlags(const U8 index, const U8 media_flags);  	S32 setGlow(const U8 index, const F32 glow); +	S32 setMaterialID(const U8 index, const LLMaterialID& pMaterialID); +	S32 setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);  	S32 size() const; diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 34eff17519..597f078490 100755 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -29,6 +29,7 @@  #include "lluuid.h"  #include "llmediaentry.h"  #include "lltextureentry.h" +#include "llmaterialid.h"  #include "llsdutil_math.h"  #include "v4color.h" @@ -60,18 +61,24 @@ LLTextureEntry* LLTextureEntry::newTextureEntry()  //===============================================================  LLTextureEntry::LLTextureEntry()    : mMediaEntry(NULL) +  , mSelected(false) +  , mMaterialUpdatePending(false)  {  	init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);  }  LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)    : mMediaEntry(NULL) +  , mSelected(false) +  , mMaterialUpdatePending(false)  {  	init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);  }  LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)    : mMediaEntry(NULL) +  , mSelected(false) +  , mMaterialUpdatePending(false)  {  	mID = rhs.mID;  	mScaleS = rhs.mScaleS; @@ -83,6 +90,8 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)  	mBump = rhs.mBump;  	mMediaFlags = rhs.mMediaFlags;  	mGlow = rhs.mGlow; +	mMaterialID = rhs.mMaterialID; +	mMaterial = rhs.mMaterial;  	if (rhs.mMediaEntry != NULL) {  		// Make a copy  		mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry); @@ -103,6 +112,8 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)  		mBump = rhs.mBump;  		mMediaFlags = rhs.mMediaFlags;  		mGlow = rhs.mGlow; +		mMaterialID = rhs.mMaterialID; +		mMaterial = rhs.mMaterial;  		if (mMediaEntry != NULL) {  			delete mMediaEntry;  		} @@ -130,6 +141,7 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of  	mBump = bump;  	mMediaFlags = 0x0;      mGlow = 0; +	mMaterialID.clear();  	setColor(LLColor4(1.f, 1.f, 1.f, 1.f));  	if (mMediaEntry != NULL) { @@ -159,6 +171,7 @@ bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const  	if (mBump != rhs.mBump) return (true);  	if (mMediaFlags != rhs.mMediaFlags) return (true);  	if (mGlow != rhs.mGlow) return (true); +	if (mMaterialID != rhs.mMaterialID) return (true);  	return(false);  } @@ -174,6 +187,7 @@ bool LLTextureEntry::operator==(const LLTextureEntry &rhs) const  	if (mBump != rhs.mBump) return (false);  	if (mMediaFlags != rhs.mMediaFlags) return false;  	if (mGlow != rhs.mGlow) return false; +	if (mMaterialID != rhs.mMaterialID) return (false);  	return(true);  } @@ -523,6 +537,34 @@ S32 LLTextureEntry::setGlow(F32 glow)  	return TEM_CHANGE_NONE;  } +S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID) +{ +	if ( (mMaterialID != pMaterialID) || (mMaterialUpdatePending && !mSelected) ) +	{ +		if (mSelected) +		{ +			mMaterialUpdatePending = true; +			mMaterialID = pMaterialID; +			return TEM_CHANGE_NONE; +		} + +		mMaterialUpdatePending = false; +		mMaterialID = pMaterialID; +		return TEM_CHANGE_TEXTURE; +	} +	return TEM_CHANGE_NONE; +} + +S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams) +{ +	if (mSelected) +	{ +		mMaterialUpdatePending = true; +	} +	mMaterial = pMaterialParams; +	return TEM_CHANGE_TEXTURE; +} +  void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)  {      mMediaFlags |= MF_HAS_MEDIA; diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index 437b85e03f..19edcaa27d 100755 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -30,6 +30,8 @@  #include "lluuid.h"  #include "v4color.h"  #include "llsd.h" +#include "llmaterialid.h" +#include "llmaterial.h"  // These bits are used while unpacking TEM messages to tell which aspects of  // the texture entry changed. @@ -98,6 +100,10 @@ public:  	void init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump); +	bool hasPendingMaterialUpdate() const { return mMaterialUpdatePending; } +	bool isSelected() const { return mSelected; } +	bool setSelected(bool sel) { bool prev_sel = mSelected; mSelected = sel; return prev_sel; } +  	// These return a TEM_ flag from above to indicate if something changed.  	S32  setID (const LLUUID &tex_id);  	S32  setColor(const LLColor4 &color); @@ -121,11 +127,19 @@ public:  	S32	 setTexGen(U8 texGen);  	S32  setMediaTexGen(U8 media);      S32  setGlow(F32 glow); +	S32  setMaterialID(const LLMaterialID& pMaterialID); +	S32  setMaterialParams(const LLMaterialPtr pMaterialParams);  	virtual const LLUUID &getID() const { return mID; }  	const LLColor4 &getColor() const { return mColor; }  	void getScale(F32 *s, F32 *t) const { *s = mScaleS; *t = mScaleT; } +	F32  getScaleS() const { return mScaleS; } +	F32  getScaleT() const { return mScaleT; } +  	void getOffset(F32 *s, F32 *t) const { *s = mOffsetS; *t = mOffsetT; } +	F32  getOffsetS() const { return mOffsetS; } +	F32  getOffsetT() const { return mOffsetT; } +  	F32  getRotation() const { return mRotation; }  	void getRotation(F32 *theta) const { *theta = mRotation; } @@ -136,9 +150,11 @@ public:   	U8	 getBumpShinyFullbright() const { return mBump; }  	U8	 getMediaFlags() const { return mMediaFlags & TEM_MEDIA_MASK; } -	U8	 getTexGen() const	{ return mMediaFlags & TEM_TEX_GEN_MASK; } +	LLTextureEntry::e_texgen	 getTexGen() const	{ return LLTextureEntry::e_texgen(mMediaFlags & TEM_TEX_GEN_MASK); }  	U8	 getMediaTexGen() const { return mMediaFlags; }      F32  getGlow() const { return mGlow; } +	const LLMaterialID& getMaterialID() const { return mMaterialID; }; +	const LLMaterialPtr getMaterialParams() const { return mMaterial; };      // *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.      // CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData() @@ -188,11 +204,15 @@ public:  	static const char* TEXTURE_MEDIA_DATA_KEY;  protected: +	bool                mSelected;  	LLUUID				mID;					// Texture GUID  	LLColor4			mColor;  	U8					mBump;					// Bump map, shiny, and fullbright  	U8					mMediaFlags;			// replace with web page, movie, etc.  	F32                 mGlow; +	bool                mMaterialUpdatePending; +	LLMaterialID        mMaterialID; +	LLMaterialPtr		mMaterial;  	// Note the media data is not sent via the same message structure as the rest of the TE  	LLMediaEntry*		mMediaEntry;			// The media data for the face diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 669b70aa43..dba12d048e 100755 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -92,7 +92,7 @@ if (BUILD_HEADLESS)    set_property(TARGET llrenderheadless      PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1 -    ) +      )    target_link_libraries(llrenderheadless      ${LLCOMMON_LIBRARIES} diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 6c798aa4ed..088ba95b75 100755 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -86,7 +86,7 @@ void APIENTRY gl_debug_callback(GLenum source,  	}  	else  	{ -		llwarns << "----- GL WARNING -------" << llendl;		 +		llwarns << "----- GL WARNING -------" << llendl;  	}  	llwarns << "Type: " << std::hex << type << llendl;  	llwarns << "ID: " << std::hex << id << llendl; @@ -216,6 +216,11 @@ PFNGLGETQUERYIVARBPROC glGetQueryivARB = NULL;  PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB = NULL;  PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB = NULL; +// GL_ARB_timer_query +PFNGLQUERYCOUNTERPROC glQueryCounter = NULL; +PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v = NULL; +PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v = NULL; +  // GL_ARB_point_parameters  PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB = NULL;  PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB = NULL; @@ -421,6 +426,7 @@ LLGLManager::LLGLManager() :  	mHasFragmentShader(FALSE),  	mNumTextureImageUnits(0),  	mHasOcclusionQuery(FALSE), +	mHasTimerQuery(FALSE),  	mHasOcclusionQuery2(FALSE),  	mHasPointParameters(FALSE),  	mHasDrawBuffers(FALSE), @@ -445,7 +451,9 @@ LLGLManager::LLGLManager() :  	mIsGFFX(FALSE),  	mATIOffsetVerticalLines(FALSE),  	mATIOldDriver(FALSE), - +#if LL_DARWIN +	mIsMobileGF(FALSE), +#endif  	mHasRequirements(TRUE),  	mHasSeparateSpecularColor(FALSE), @@ -637,6 +645,13 @@ bool LLGLManager::initGL()  		{  			mIsGF3 = TRUE;  		} +#if LL_DARWIN +		else if ((mGLRenderer.find("9400M") != std::string::npos) +			  || (mGLRenderer.find("9600M") != std::string::npos)) +		{ +			mIsMobileGF = TRUE; +		} +#endif  	}  	else if (mGLVendor.find("INTEL") != std::string::npos @@ -745,12 +760,13 @@ bool LLGLManager::initGL()  	{ //using multisample textures on ATI results in black screen for some reason  		mHasTextureMultisample = FALSE;  	} -#endif +  	if (mIsIntel && mGLVersion <= 3.f)  	{ //never try to use framebuffer objects on older intel drivers (crashy)  		mHasFramebufferObject = FALSE;  	} +#endif  	if (mHasFramebufferObject)  	{ @@ -947,13 +963,15 @@ void LLGLManager::initExtensions()  	mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts);  	mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression");  	mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts); +	mHasTimerQuery = ExtensionExists("GL_ARB_timer_query", gGLHExts.mSysExts);  	mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);  	mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);  	mHasVertexArrayObject = ExtensionExists("GL_ARB_vertex_array_object", gGLHExts.mSysExts);  	mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);  	mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);  	mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts); -	mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts); +	//mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts); +	mHasDepthClamp = FALSE;  	// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad  #ifdef GL_ARB_framebuffer_object  	mHasFramebufferObject = ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts); @@ -963,6 +981,15 @@ void LLGLManager::initExtensions()  							ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts) &&  							ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);  #endif +#ifdef GL_EXT_texture_sRGB +	mHassRGBTexture = ExtensionExists("GL_EXT_texture_sRGB", gGLHExts.mSysExts); +#endif +	 +#ifdef GL_ARB_framebuffer_sRGB +	mHassRGBFramebuffer = ExtensionExists("GL_ARB_framebuffer_sRGB", gGLHExts.mSysExts); +#else +	mHassRGBFramebuffer = ExtensionExists("GL_EXT_framebuffer_sRGB", gGLHExts.mSysExts); +#endif  	mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f; @@ -1253,6 +1280,13 @@ void LLGLManager::initExtensions()  		glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectivARB");  		glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectuivARB");  	} +	if (mHasTimerQuery) +	{ +		llinfos << "initExtensions() TimerQuery-related procs..." << llendl; +		glQueryCounter = (PFNGLQUERYCOUNTERPROC) GLH_EXT_GET_PROC_ADDRESS("glQueryCounter"); +		glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjecti64v"); +		glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectui64v"); +	}  	if (mHasPointParameters)  	{  		llinfos << "initExtensions() PointParameters-related procs..." << llendl; diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index d70e764769..60597fd090 100755 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -98,6 +98,7 @@ public:  	BOOL mHasFragmentShader;  	S32  mNumTextureImageUnits;  	BOOL mHasOcclusionQuery; +	BOOL mHasTimerQuery;  	BOOL mHasOcclusionQuery2;  	BOOL mHasPointParameters;  	BOOL mHasDrawBuffers; @@ -115,6 +116,8 @@ public:  	BOOL mHasARBEnvCombine;  	BOOL mHasCubeMap;  	BOOL mHasDebugOutput; +	BOOL mHassRGBTexture; +	BOOL mHassRGBFramebuffer;  	// Vendor-specific extensions  	BOOL mIsATI; @@ -126,6 +129,11 @@ public:  	BOOL mATIOffsetVerticalLines;  	BOOL mATIOldDriver; +#if LL_DARWIN +	// Needed to distinguish problem cards on older Macs that break with Materials +	BOOL mIsMobileGF; +#endif +	  	// Whether this version of GL is good enough for SL to use  	BOOL mHasRequirements; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 509de51f4d..dace572953 100755 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -116,6 +116,11 @@ extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;  extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;  extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB; +// GL_ARB_timer_query +extern PFNGLQUERYCOUNTERPROC glQueryCounter; +extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v; +extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v; +  // GL_ARB_point_parameters  extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;  extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB; @@ -378,6 +383,11 @@ extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;  extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;  extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB; +// GL_ARB_timer_query +extern PFNGLQUERYCOUNTERPROC glQueryCounter; +extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v; +extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v; +  // GL_ARB_point_parameters  extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;  extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB; @@ -619,6 +629,12 @@ extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;  extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;  extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB; +// GL_ARB_timer_query +extern PFNGLQUERYCOUNTERPROC glQueryCounter; +extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v; +extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v; + +  // GL_ARB_point_parameters  extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;  extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 7cbf39096e..62191b4c1a 100755 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -53,6 +53,12 @@ GLhandleARB LLGLSLShader::sCurBoundShader = 0;  LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;  S32 LLGLSLShader::sIndexedTextureChannels = 0;  bool LLGLSLShader::sNoFixedFunction = false; +bool LLGLSLShader::sProfileEnabled = false; +std::set<LLGLSLShader*> LLGLSLShader::sInstances; +U64 LLGLSLShader::sTotalTimeElapsed = 0; +U32 LLGLSLShader::sTotalTrianglesDrawn = 0; +U64 LLGLSLShader::sTotalSamplesDrawn = 0; +U32 LLGLSLShader::sTotalDrawCalls = 0;  //UI shader -- declared here so llui_libtest will link properly  LLGLSLShader	gUIProgram; @@ -87,19 +93,194 @@ LLShaderFeatures::LLShaderFeatures()  //===============================  // LLGLSL Shader implementation  //=============================== + +//static +void LLGLSLShader::initProfile() +{ +	sProfileEnabled = true; +	sTotalTimeElapsed = 0; +	sTotalTrianglesDrawn = 0; +	sTotalSamplesDrawn = 0; +	sTotalDrawCalls = 0; + +	for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) +	{ +		(*iter)->clearStats(); +	} +} + + +struct LLGLSLShaderCompareTimeElapsed +{ +		bool operator()(const LLGLSLShader* const& lhs, const LLGLSLShader* const& rhs) +		{ +			return lhs->mTimeElapsed < rhs->mTimeElapsed; +		} +}; + +//static +void LLGLSLShader::finishProfile() +{ +	sProfileEnabled = false; + +	std::vector<LLGLSLShader*> sorted; + +	for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) +	{ +		sorted.push_back(*iter); +	} + +	std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed()); + +	for (std::vector<LLGLSLShader*>::iterator iter = sorted.begin(); iter != sorted.end(); ++iter) +	{ +		(*iter)->dumpStats(); +	} + +	llinfos << "-----------------------------------" << llendl; +	llinfos << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed/1000000.f) << llendl; +	llinfos << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn/1000000.f) << llendl; +	llinfos << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn/1000000.f) << llendl; +} + +void LLGLSLShader::clearStats() +{ +	mTrianglesDrawn = 0; +	mTimeElapsed = 0; +	mSamplesDrawn = 0; +	mDrawCalls = 0; +} + +void LLGLSLShader::dumpStats() +{ +	if (mDrawCalls > 0) +	{ +		llinfos << "=============================================" << llendl; +		llinfos << mName << llendl; +		for (U32 i = 0; i < mShaderFiles.size(); ++i) +		{ +			llinfos << mShaderFiles[i].first << llendl; +		} +		llinfos << "=============================================" << llendl; + +		F32 ms = mTimeElapsed/1000000.f; +		F32 seconds = ms/1000.f; + +		F32 pct_tris = (F32) mTrianglesDrawn/(F32)sTotalTrianglesDrawn*100.f; +		F32 tris_sec = (F32) (mTrianglesDrawn/1000000.0); +		tris_sec /= seconds; + +		F32 pct_samples = (F32) ((F64)mSamplesDrawn/(F64)sTotalSamplesDrawn)*100.f; +		F32 samples_sec = (F32) mSamplesDrawn/1000000000.0; +		samples_sec /= seconds; + +		F32 pct_calls = (F32) mDrawCalls/(F32)sTotalDrawCalls*100.f; +		U32 avg_batch = mTrianglesDrawn/mDrawCalls; + +		llinfos << "Triangles Drawn: " << mTrianglesDrawn <<  " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec ) << llendl; +		llinfos << "Draw Calls: " << mDrawCalls << " " << llformat("(%.2f pct of total, avg %d tris/call)", pct_calls, avg_batch) << llendl; +		llinfos << "SamplesDrawn: " << mSamplesDrawn << " " << llformat("(%.2f pct of total, %.3f billion/sec)", pct_samples, samples_sec) << llendl; +		llinfos << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32) ((F64)mTimeElapsed/(F64)sTotalTimeElapsed)*100.f, ms) << llendl; +	} +} + +//static +void LLGLSLShader::startProfile() +{ +	if (sProfileEnabled && sCurBoundShaderPtr) +	{ +		sCurBoundShaderPtr->placeProfileQuery(); +	} + +} + +//static +void LLGLSLShader::stopProfile(U32 count, U32 mode) +{ +	if (sProfileEnabled) +	{ +		sCurBoundShaderPtr->readProfileQuery(count, mode); +	} +} + +void LLGLSLShader::placeProfileQuery() +{ +#if !LL_DARWIN +	if (mTimerQuery == 0) +	{ +		glGenQueriesARB(1, &mTimerQuery); +	} + +	glBeginQueryARB(GL_SAMPLES_PASSED, 1); +	glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery); +#endif +} + +void LLGLSLShader::readProfileQuery(U32 count, U32 mode) +{ +#if !LL_DARWIN +	glEndQueryARB(GL_TIME_ELAPSED); +	glEndQueryARB(GL_SAMPLES_PASSED); +	 +	U64 time_elapsed = 0; +	glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed); + +	U64 samples_passed = 0; +	glGetQueryObjectui64v(1, GL_QUERY_RESULT, &samples_passed); + +	sTotalTimeElapsed += time_elapsed; +	mTimeElapsed += time_elapsed; + +	sTotalSamplesDrawn += samples_passed; +	mSamplesDrawn += samples_passed; + +	U32 tri_count = 0; +	switch (mode) +	{ +		case LLRender::TRIANGLES: tri_count = count/3; break; +		case LLRender::TRIANGLE_FAN: tri_count = count-2; break; +		case LLRender::TRIANGLE_STRIP: tri_count = count-2; break; +		default: tri_count = count; break; //points lines etc just use primitive count +	} + +	mTrianglesDrawn += tri_count; +	sTotalTrianglesDrawn += tri_count; + +	sTotalDrawCalls++; +	mDrawCalls++; +#endif +} + + +  LLGLSLShader::LLGLSLShader() -	: mProgramObject(0), mActiveTextureChannels(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT), mUniformsDirty(FALSE) +	: mProgramObject(0),  +	  mAttributeMask(0), +	  mTotalUniformSize(0), +	  mActiveTextureChannels(0),  +	  mShaderLevel(0),  +	  mShaderGroup(SG_DEFAULT),  +	  mUniformsDirty(FALSE), +	  mTimerQuery(0)  { +	 +} +LLGLSLShader::~LLGLSLShader() +{ +	  }  void LLGLSLShader::unload()  { +	sInstances.erase(this); +  	stop_glerror();  	mAttribute.clear();  	mTexture.clear();  	mUniform.clear();  	mShaderFiles.clear(); +	mDefines.clear();  	if (mProgramObject)  	{ @@ -133,6 +314,8 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,  								U32 varying_count,  								const char** varyings)  { +	sInstances.insert(this); +  	//reloading, reset matrix hash values  	for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)  	{ @@ -150,7 +333,7 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,  	vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();  	for ( ; fileIter != mShaderFiles.end(); fileIter++ )  	{ -		GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mFeatures.mIndexedTextureChannels); +		GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels);  		LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;  		if (shaderhandle > 0)  		{ @@ -285,6 +468,8 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)  	if (res)  	{ //read back channel locations +		mAttributeMask = 0; +  		//read back reserved channels first  		for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)  		{ @@ -293,6 +478,7 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)  			if (index != -1)  			{  				mAttribute[i] = index; +				mAttributeMask |= 1 << i;  				LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;  			}  		} @@ -325,11 +511,56 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)  	GLenum type;  	GLsizei length; -	GLint size; +	GLint size = -1;  	char name[1024];		/* Flawfinder: ignore */  	name[0] = 0; +  	glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name); +#if !LL_DARWIN +	if (size > 0) +	{ +		switch(type) +		{ +			case GL_FLOAT_VEC2: size *= 2; break; +			case GL_FLOAT_VEC3: size *= 3; break; +			case GL_FLOAT_VEC4: size *= 4; break; +			case GL_DOUBLE: size *= 2; break; +			case GL_DOUBLE_VEC2: size *= 2; break; +			case GL_DOUBLE_VEC3: size *= 6; break; +			case GL_DOUBLE_VEC4: size *= 8; break; +			case GL_INT_VEC2: size *= 2; break; +			case GL_INT_VEC3: size *= 3; break; +			case GL_INT_VEC4: size *= 4; break; +			case GL_UNSIGNED_INT_VEC2: size *= 2; break; +			case GL_UNSIGNED_INT_VEC3: size *= 3; break; +			case GL_UNSIGNED_INT_VEC4: size *= 4; break; +			case GL_BOOL_VEC2: size *= 2; break; +			case GL_BOOL_VEC3: size *= 3; break; +			case GL_BOOL_VEC4: size *= 4; break; +			case GL_FLOAT_MAT2: size *= 4; break; +			case GL_FLOAT_MAT3: size *= 9; break; +			case GL_FLOAT_MAT4: size *= 16; break; +			case GL_FLOAT_MAT2x3: size *= 6; break; +			case GL_FLOAT_MAT2x4: size *= 8; break; +			case GL_FLOAT_MAT3x2: size *= 6; break; +			case GL_FLOAT_MAT3x4: size *= 12; break; +			case GL_FLOAT_MAT4x2: size *= 8; break; +			case GL_FLOAT_MAT4x3: size *= 12; break; +			case GL_DOUBLE_MAT2: size *= 8; break; +			case GL_DOUBLE_MAT3: size *= 18; break; +			case GL_DOUBLE_MAT4: size *= 32; break; +			case GL_DOUBLE_MAT2x3: size *= 12; break; +			case GL_DOUBLE_MAT2x4: size *= 16; break; +			case GL_DOUBLE_MAT3x2: size *= 12; break; +			case GL_DOUBLE_MAT3x4: size *= 24; break; +			case GL_DOUBLE_MAT4x2: size *= 16; break; +			case GL_DOUBLE_MAT4x3: size *= 24; break; +		} +		mTotalUniformSize += size; +	} +#endif +  	S32 location = glGetUniformLocationARB(mProgramObject, name);  	if (location != -1)  	{ @@ -372,11 +603,21 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)  			}  		}  	} - } +} + +void LLGLSLShader::addPermutation(std::string name, std::string value) +{ +	mDefines[name] = value; +} + +void LLGLSLShader::removePermutation(std::string name) +{ +	mDefines[name].erase(); +}  GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)  { -	if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB || +	if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) ||  		type == GL_SAMPLER_2D_MULTISAMPLE)  	{	//this here is a texture  		glUniform1iARB(location, mActiveTextureChannels); @@ -390,6 +631,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)  {  	BOOL res = TRUE; +	mTotalUniformSize = 0;  	mActiveTextureChannels = 0;  	mUniform.clear();  	mUniformMap.clear(); @@ -413,6 +655,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)  	unbind(); +	LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << llendl;  	return res;  } @@ -471,6 +714,58 @@ void LLGLSLShader::bindNoShader(void)  	}  } +S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode) +{ +	S32 channel = 0; +	channel = getUniformLocation(uniform); +	 +	return bindTexture(channel, texture, mode); +} + +S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode) +{ +	if (uniform < 0 || uniform >= (S32)mTexture.size()) +	{ +		UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; +		return -1; +	} +	 +	uniform = mTexture[uniform]; +	 +	if (uniform > -1) +	{ +		gGL.getTexUnit(uniform)->bind(texture, mode); +	} +	 +	return uniform; +} + +S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode) +{ +	S32 channel = 0; +	channel = getUniformLocation(uniform); +	 +	return unbindTexture(channel); +} + +S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode) +{ +	if (uniform < 0 || uniform >= (S32)mTexture.size()) +	{ +		UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; +		return -1; +	} +	 +	uniform = mTexture[uniform]; +	 +	if (uniform > -1) +	{ +		gGL.getTexUnit(uniform)->unbind(mode); +	} +	 +	return uniform; +} +  S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)  {  	if (uniform < 0 || uniform >= (S32)mTexture.size()) diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index cf21101e35..3c775cde27 100755 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -67,14 +67,29 @@ public:  		SG_WATER  	}; +	static std::set<LLGLSLShader*> sInstances; +	static bool sProfileEnabled; +  	LLGLSLShader(); +	~LLGLSLShader();  	static GLhandleARB sCurBoundShader;  	static LLGLSLShader* sCurBoundShaderPtr;  	static S32 sIndexedTextureChannels;  	static bool sNoFixedFunction; +	static void initProfile(); +	static void finishProfile(); + +	static void startProfile(); +	static void stopProfile(U32 count, U32 mode); +  	void unload(); +	void clearStats(); +	void dumpStats(); +	void placeProfileQuery(); +	void readProfileQuery(U32 count, U32 mode); +  	BOOL createShader(std::vector<std::string> * attributes,  						std::vector<std::string> * uniforms,  						U32 varying_count = 0, @@ -123,12 +138,22 @@ public:  	GLint getAttribLocation(U32 attrib);  	GLint mapUniformTextureChannel(GLint location, GLenum type); +	void addPermutation(std::string name, std::string value); +	void removePermutation(std::string name); +	  	//enable/disable texture channel for specified uniform  	//if given texture uniform is active in the shader,   	//the corresponding channel will be active upon return  	//returns channel texture is enabled in from [0-MAX)  	S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); -	S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);  +	S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); +	 +	// bindTexture returns the texture unit we've bound the texture to. +	// You can reuse the return value to unbind a texture when required. +	S32 bindTexture(const std::string& uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); +	S32 bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); +	S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); +	S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);      BOOL link(BOOL suppress_errors = FALSE);  	void bind(); @@ -142,10 +167,12 @@ public:  	GLhandleARB mProgramObject;  	std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel +	U32 mAttributeMask;  //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())  	std::vector<GLint> mUniform;   //lookup table of uniform enum to uniform location  	std::map<std::string, GLint> mUniformMap;  //lookup map of uniform name to uniform location  	std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value  	std::vector<GLint> mTexture; +	S32 mTotalUniformSize;  	S32 mActiveTextureChannels;  	S32 mShaderLevel;  	S32 mShaderGroup; @@ -153,6 +180,18 @@ public:  	LLShaderFeatures mFeatures;  	std::vector< std::pair< std::string, GLenum > > mShaderFiles;  	std::string mName; +	boost::unordered_map<std::string, std::string> mDefines; + +	//statistcis for profiling shader performance +	U32 mTimerQuery; +	U64 mTimeElapsed; +	static U64 sTotalTimeElapsed; +	U32 mTrianglesDrawn; +	static U32 sTotalTrianglesDrawn; +	U64 mSamplesDrawn; +	static U64 sTotalSamplesDrawn; +	U32 mDrawCalls; +	static U32 sTotalDrawCalls;  };  //UI shader (declared here so llui_libtest will link properly) diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 5c171d372c..38764eba23 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -748,12 +748,16 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  				S32 height = getHeight(mCurrentDiscardLevel);  				S32 nummips = mMaxDiscardLevel - mCurrentDiscardLevel + 1;  				S32 w = width, h = height; + + +				const U8* new_data = 0; +				(void)new_data; +  				const U8* prev_mip_data = 0;  				const U8* cur_mip_data = 0;  #ifdef SHOW_ASSERT  				S32 cur_mip_size = 0;  #endif -				  				mMipLevels = nummips;  				for (int m=0; m<nummips; m++) @@ -773,14 +777,22 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  						llassert(cur_mip_size == bytes*4);  #endif  						U8* new_data = new U8[bytes]; + +#ifdef SHOW_ASSERT +						llassert(prev_mip_data); +						llassert(cur_mip_size == bytes*4);  						llassert_always(new_data); +#endif +  						LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);  						cur_mip_data = new_data;  #ifdef SHOW_ASSERT  						cur_mip_size = bytes;   #endif +  					}  					llassert(w > 0 && h > 0 && cur_mip_data); +					(void)cur_mip_data;  					{  // 						LLFastTimer t1(FTM_TEMP4);  						if(mFormatSwapBytes) @@ -1119,30 +1131,30 @@ void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip  			default:  			{  				if (type == LLTexUnit::TT_CUBE_MAP || mip_levels == -1) -				{ //unknown internal format or unknown number of mip levels, not safe to reuse -					glDeleteTextures(numTextures, textures); -				} -				else -				{ -					for (S32 i = 0; i < numTextures; ++i) -					{ //remove texture from VRAM by setting its size to zero +		{ //unknown internal format or unknown number of mip levels, not safe to reuse +			glDeleteTextures(numTextures, textures); +		} +		else +		{ +			for (S32 i = 0; i < numTextures; ++i) +			{ //remove texture from VRAM by setting its size to zero -						for (S32 j = 0; j <= mip_levels; j++) -						{ -							gGL.getTexUnit(0)->bindManual(type, textures[i]); +				for (S32 j = 0; j <= mip_levels; j++) +				{ +					gGL.getTexUnit(0)->bindManual(type, textures[i]);  							U32 internal_type = LLTexUnit::getInternalType(type);  							glTexImage2D(internal_type, j, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);  							stop_glerror(); -						} +				} -						llassert(std::find(sDeadTextureList[type][format].begin(), -							sDeadTextureList[type][format].end(), textures[i]) ==  -							sDeadTextureList[type][format].end()); +				llassert(std::find(sDeadTextureList[type][format].begin(), +								   sDeadTextureList[type][format].end(), textures[i]) ==  +								   sDeadTextureList[type][format].end()); -						sDeadTextureList[type][format].push_back(textures[i]); -					}	 -				}				 -			} +				sDeadTextureList[type][format].push_back(textures[i]); +			}	 +		} +	}  			break;  		}  	} diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 78a310e525..98222939e7 100755 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -262,6 +262,14 @@ class LLRender  	friend class LLTexUnit;  public: +	enum eTexIndex +	{ +		DIFFUSE_MAP = 0, +		NORMAL_MAP, +		SPECULAR_MAP, +		NUM_TEXTURE_CHANNELS, +	}; +	  	typedef enum {  		TRIANGLES = 0,  		TRIANGLE_STRIP, diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index b6a9a6b653..fea4ee2819 100755 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -521,7 +521,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)  	}   } -GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels) +GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines, S32 texture_index_channels)  {  	GLenum error = GL_NO_ERROR;  	if (gDebugGL) @@ -650,13 +650,15 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  			text[count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");  		}  	} - -	//copy preprocessor definitions into buffer -	for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter) +	 +	if (defines) +	{ +		for (boost::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter)  	{  		std::string define = "#define " + iter->first + " " + iter->second + "\n";  		text[count++] = (GLcharARB *) strdup(define.c_str());  	} +	}  	if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)  	{ @@ -693,6 +695,8 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  		}  		*/ +		text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 1\n"); +  		//uniform declartion  		for (S32 i = 0; i < texture_index_channels; ++i)  		{ @@ -750,6 +754,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  			llerrs << "Indexed texture rendering requires GLSL 1.30 or later." << llendl;  		}  	} +	else +	{ +		text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 0\n"); +	}  	//copy file into memory  	while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(text) )  @@ -806,7 +814,6 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  				//an error occured, print log  				LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;  				dumpObjectLog(ret); -  #if LL_WINDOWS  				std::stringstream ostr;  				//dump shader source for debugging @@ -824,8 +831,20 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  				}  				LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl; -#endif // LL_WINDOWS - +#else +				std::string str; +				 +				for (GLuint i = 0; i < count; i++) { +					str.append(text[i]); +					 +					if (i % 128 == 0) +					{ +						LL_WARNS("ShaderLoading") << str << llendl; +						str = ""; +					} +				} +#endif +				  				ret = 0;  			}  		} @@ -854,7 +873,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  		if (shader_level > 1)  		{  			shader_level--; -			return loadShaderFile(filename,shader_level,type,texture_index_channels); +			return loadShaderFile(filename,shader_level,type, defines, texture_index_channels);  		}  		LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;	  	} @@ -958,7 +977,7 @@ void LLShaderMgr::initAttribsAndUniforms()  	mReservedAttribs.push_back("texcoord3");  	mReservedAttribs.push_back("diffuse_color");  	mReservedAttribs.push_back("emissive"); -	mReservedAttribs.push_back("binormal"); +	mReservedAttribs.push_back("tangent");  	mReservedAttribs.push_back("weight");  	mReservedAttribs.push_back("weight4");  	mReservedAttribs.push_back("clothing"); @@ -1055,6 +1074,7 @@ void LLShaderMgr::initAttribsAndUniforms()  	mReservedUniforms.push_back("minimum_alpha"); +	mReservedUniforms.push_back("emissive_brightness");  	mReservedUniforms.push_back("shadow_matrix");  	mReservedUniforms.push_back("env_mat"); @@ -1115,6 +1135,12 @@ void LLShaderMgr::initAttribsAndUniforms()  	mReservedUniforms.push_back("lightMap");  	mReservedUniforms.push_back("bloomMap");  	mReservedUniforms.push_back("projectionMap"); +	 +	mReservedUniforms.push_back("global_gamma"); +	mReservedUniforms.push_back("texture_gamma"); +	 +	mReservedUniforms.push_back("specular_color"); +	mReservedUniforms.push_back("env_intensity");  	llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 7a16b7c20f..c049e935b8 100755 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -109,6 +109,7 @@ public:  		GLOW_DELTA,  		MINIMUM_ALPHA, +		EMISSIVE_BRIGHTNESS,  		DEFERRED_SHADOW_MATRIX,  		DEFERRED_ENV_MAT, @@ -164,6 +165,13 @@ public:  		DEFERRED_LIGHT,  		DEFERRED_BLOOM,  		DEFERRED_PROJECTION, +		 +		GLOBAL_GAMMA, +		TEXTURE_GAMMA, +		 +		SPECULAR_COLOR, +		ENVIRONMENT_INTENSITY, +		  		END_RESERVED_UNIFORMS  	} eGLSLReservedUniforms; @@ -176,7 +184,7 @@ public:  	void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);  	BOOL	linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);  	BOOL	validateProgramObject(GLhandleARB obj); -	GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels = -1); +	GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);  	// Implemented in the application to actually point to the shader directory.  	virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 4909b43e8a..01541026b1 100755 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -342,13 +342,32 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =  	sizeof(LLVector2), // TYPE_TEXCOORD3,  	sizeof(LLColor4U), // TYPE_COLOR,  	sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently -	sizeof(LLVector4), // TYPE_BINORMAL, +	sizeof(LLVector4), // TYPE_TANGENT,  	sizeof(F32),	   // TYPE_WEIGHT,  	sizeof(LLVector4), // TYPE_WEIGHT4,  	sizeof(LLVector4), // TYPE_CLOTHWEIGHT,  	sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes  }; +static std::string vb_type_name[] = +{ +	"TYPE_VERTEX", +	"TYPE_NORMAL", +	"TYPE_TEXCOORD0", +	"TYPE_TEXCOORD1", +	"TYPE_TEXCOORD2", +	"TYPE_TEXCOORD3", +	"TYPE_COLOR", +	"TYPE_EMISSIVE", +	"TYPE_TANGENT", +	"TYPE_WEIGHT", +	"TYPE_WEIGHT4", +	"TYPE_CLOTHWEIGHT", +	"TYPE_TEXTURE_INDEX", +	"TYPE_MAX", +	"TYPE_INDEX",	 +}; +  U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =   {  	GL_TRIANGLES, @@ -523,16 +542,16 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)  				}  			} -			if (sLastMask & MAP_BINORMAL) +			if (sLastMask & MAP_TANGENT)  			{ -				if (!(data_mask & MAP_BINORMAL)) +				if (!(data_mask & MAP_TANGENT))  				{  					glClientActiveTextureARB(GL_TEXTURE2_ARB);  					glDisableClientState(GL_TEXTURE_COORD_ARRAY);  					glClientActiveTextureARB(GL_TEXTURE0_ARB);  				}  			} -			else if (data_mask & MAP_BINORMAL) +			else if (data_mask & MAP_TANGENT)  			{  				glClientActiveTextureARB(GL_TEXTURE2_ARB);  				glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -593,8 +612,9 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con  		glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);  		glNormalPointer(GL_FLOAT, 0, norm[0].mV);  	} - +	LLGLSLShader::startProfile();  	glDrawArrays(sGLMode[mode], 0, count); +	LLGLSLShader::stopProfile(count, mode);  }  //static @@ -631,7 +651,9 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto  		glVertexPointer(3, GL_FLOAT, 16, pos);  	} +	LLGLSLShader::startProfile();  	glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp); +	LLGLSLShader::stopProfile(num_indices, mode);  }  void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const @@ -731,9 +753,14 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi  	U16* idx = ((U16*) getIndicesPointer())+indices_offset;  	stop_glerror(); +	LLGLSLShader::startProfile();  	glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,   		idx); +	LLGLSLShader::stopProfile(count, mode);  	stop_glerror(); + +	 +  	placeFence();  } @@ -777,8 +804,10 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const  	}  	stop_glerror(); +	LLGLSLShader::startProfile();  	glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,  		((U16*) getIndicesPointer()) + indices_offset); +	LLGLSLShader::stopProfile(count, mode);  	stop_glerror();  	placeFence();  } @@ -820,9 +849,12 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const  	{  		LLFastTimer t2(FTM_GL_DRAW_ARRAYS); -		stop_glerror(); -		glDrawArrays(sGLMode[mode], first, count); -	} +	stop_glerror(); +	LLGLSLShader::startProfile(); +	glDrawArrays(sGLMode[mode], first, count); +	LLGLSLShader::stopProfile(count, mode); +        } +  	stop_glerror();  	placeFence();  } @@ -1322,7 +1354,7 @@ void LLVertexBuffer::setupVertexArray()  		2, //TYPE_TEXCOORD3,  		4, //TYPE_COLOR,  		4, //TYPE_EMISSIVE, -		3, //TYPE_BINORMAL, +		4, //TYPE_TANGENT,  		1, //TYPE_WEIGHT,  		4, //TYPE_WEIGHT4,  		4, //TYPE_CLOTHWEIGHT, @@ -1339,7 +1371,7 @@ void LLVertexBuffer::setupVertexArray()  		GL_FLOAT, //TYPE_TEXCOORD3,  		GL_UNSIGNED_BYTE, //TYPE_COLOR,  		GL_UNSIGNED_BYTE, //TYPE_EMISSIVE, -		GL_FLOAT,   //TYPE_BINORMAL, +		GL_FLOAT,   //TYPE_TANGENT,  		GL_FLOAT, //TYPE_WEIGHT,  		GL_FLOAT, //TYPE_WEIGHT4,  		GL_FLOAT, //TYPE_CLOTHWEIGHT, @@ -1356,7 +1388,7 @@ void LLVertexBuffer::setupVertexArray()  		false, //TYPE_TEXCOORD3,  		false, //TYPE_COLOR,  		false, //TYPE_EMISSIVE, -		false, //TYPE_BINORMAL, +		false, //TYPE_TANGENT,  		false, //TYPE_WEIGHT,  		false, //TYPE_WEIGHT4,  		false, //TYPE_CLOTHWEIGHT, @@ -1373,7 +1405,7 @@ void LLVertexBuffer::setupVertexArray()  		GL_FALSE, //TYPE_TEXCOORD3,  		GL_TRUE, //TYPE_COLOR,  		GL_TRUE, //TYPE_EMISSIVE, -		GL_FALSE,   //TYPE_BINORMAL, +		GL_FALSE,   //TYPE_TANGENT,  		GL_FALSE, //TYPE_WEIGHT,  		GL_FALSE, //TYPE_WEIGHT4,  		GL_FALSE, //TYPE_CLOTHWEIGHT, @@ -2038,14 +2070,21 @@ bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 inde  {  	return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count, map_range);  } - +bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range) +{ +	return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index, count, map_range); +}  bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)  {  	return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);  } -bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)  { -	return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index, count, map_range); +	return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count, map_range); +} +bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector4a>& strider, S32 index, S32 count, bool map_range) +{ +	return VertexBufferStrider<LLVector4a,TYPE_TANGENT>::get(*this, strider, index, count, map_range);  }  bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range)  { @@ -2200,7 +2239,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)  			if ((data_mask & required_mask) != required_mask)  			{ -				llerrs << "Shader consumption mismatches data provision." << llendl; +				llwarns << "Shader consumption mismatches data provision." << llendl;  			}  		}  	} @@ -2318,6 +2357,14 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  	if (gDebugGL && ((data_mask & mTypeMask) != data_mask))  	{ +		for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i) +		{ +			U32 mask = 1 << i; +			if (mask & data_mask && !(mask & mTypeMask)) +			{ //bit set in data_mask, but not set in mTypeMask +				llwarns << "Missing required component " << vb_type_name[i] << llendl; +			} +		}  		llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;  	} @@ -2347,11 +2394,11 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  			void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);  			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);  		} -		if (data_mask & MAP_BINORMAL) +		if (data_mask & MAP_TANGENT)  		{ -			S32 loc = TYPE_BINORMAL; -			void* ptr = (void*)(base + mOffsets[TYPE_BINORMAL]); -			glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr); +			S32 loc = TYPE_TANGENT; +			void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]); +			glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);  		}  		if (data_mask & MAP_TEXCOORD0)  		{ @@ -2429,10 +2476,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));  			glClientActiveTextureARB(GL_TEXTURE0_ARB);  		} -		if (data_mask & MAP_BINORMAL) +		if (data_mask & MAP_TANGENT)  		{  			glClientActiveTextureARB(GL_TEXTURE2_ARB); -			glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); +			glTexCoordPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));  			glClientActiveTextureARB(GL_TEXTURE0_ARB);  		}  		if (data_mask & MAP_TEXCOORD0) diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 11fa4ab6a0..04806c1d8c 100755 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -174,7 +174,7 @@ public:  		TYPE_TEXCOORD3,  		TYPE_COLOR,  		TYPE_EMISSIVE, -		TYPE_BINORMAL, +		TYPE_TANGENT,  		TYPE_WEIGHT,  		TYPE_WEIGHT4,  		TYPE_CLOTHWEIGHT, @@ -192,7 +192,7 @@ public:  		MAP_COLOR = (1<<TYPE_COLOR),  		MAP_EMISSIVE = (1<<TYPE_EMISSIVE),  		// These use VertexAttribPointer and should possibly be made generic -		MAP_BINORMAL = (1<<TYPE_BINORMAL), +		MAP_TANGENT = (1<<TYPE_TANGENT),  		MAP_WEIGHT = (1<<TYPE_WEIGHT),  		MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),  		MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT), @@ -250,8 +250,10 @@ public:  	bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false); +	bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); -	bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); +	bool getTangentStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); +	bool getTangentStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getTextureIndexStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false); diff --git a/indra/llui/lllocalcliprect.cpp b/indra/llui/lllocalcliprect.cpp index 0620e0f52d..f3a526faeb 100755 --- a/indra/llui/lllocalcliprect.cpp +++ b/indra/llui/lllocalcliprect.cpp @@ -33,7 +33,7 @@  LLScreenClipRect::LLScreenClipRect(const LLRect& rect, BOOL enabled) -	:	mScissorState(GL_SCISSOR_TEST), +:	mScissorState(GL_SCISSOR_TEST),  	mEnabled(enabled)  {  	if (mEnabled) @@ -100,10 +100,10 @@ void LLScreenClipRect::updateScissorRegion()  // LLLocalClipRect  //---------------------------------------------------------------------------  LLLocalClipRect::LLLocalClipRect(const LLRect& rect, BOOL enabled /* = TRUE */) -	:	LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX,  -	rect.mTop + LLFontGL::sCurOrigin.mY,  -	rect.mRight + LLFontGL::sCurOrigin.mX,  -	rect.mBottom + LLFontGL::sCurOrigin.mY), enabled) +:	LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX,  +					rect.mTop + LLFontGL::sCurOrigin.mY,  +					rect.mRight + LLFontGL::sCurOrigin.mX,  +					rect.mBottom + LLFontGL::sCurOrigin.mY), enabled)  {}  LLLocalClipRect::~LLLocalClipRect() diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp index 3ad5ad7d42..6322da9123 100755 --- a/indra/llui/llxuiparser.cpp +++ b/indra/llui/llxuiparser.cpp @@ -1309,10 +1309,8 @@ bool LLXUIParser::writeSDValue(Parser& parser, const void* val_ptr, name_stack_t  void LLXUIParser::parserWarning(const std::string& message)  {  #ifdef LL_WINDOWS -	// use Visual Studo friendly formatting of output message for easy access to originating xml -	llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()).c_str()); -	utf16str += '\n'; -	OutputDebugString(utf16str.c_str()); +	// use Visual Studio friendly formatting of output message for easy access to originating xml +	LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()));  #else  	Parser::parserWarning(message);  #endif @@ -1321,9 +1319,8 @@ void LLXUIParser::parserWarning(const std::string& message)  void LLXUIParser::parserError(const std::string& message)  {  #ifdef LL_WINDOWS -	llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()).c_str()); -	utf16str += '\n'; -	OutputDebugString(utf16str.c_str()); +        // use Visual Studio friendly formatting of output message for easy access to originating xml +	LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()));  #else  	Parser::parserError(message);  #endif @@ -1640,10 +1637,8 @@ bool LLSimpleXUIParser::processText()  void LLSimpleXUIParser::parserWarning(const std::string& message)  {  #ifdef LL_WINDOWS -	// use Visual Studo friendly formatting of output message for easy access to originating xml -	llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str()); -	utf16str += '\n'; -	OutputDebugString(utf16str.c_str()); +	// use Visual Studio friendly formatting of output message for easy access to originating xml +	LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()));  #else  	Parser::parserWarning(message);  #endif @@ -1652,9 +1647,8 @@ void LLSimpleXUIParser::parserWarning(const std::string& message)  void LLSimpleXUIParser::parserError(const std::string& message)  {  #ifdef LL_WINDOWS -	llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str()); -	utf16str += '\n'; -	OutputDebugString(utf16str.c_str()); +        // use Visual Studio friendly formatting of output message for easy access to originating xml +	LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()));  #else  	Parser::parserError(message);  #endif diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp index 462d1cce06..6184095957 100755 --- a/indra/llvfs/lldir_win32.cpp +++ b/indra/llvfs/lldir_win32.cpp @@ -131,7 +131,7 @@ LLDir_Win32::LLDir_Win32()  		mAppRODataDir = mExecutableDir;  	} -	llinfos << "mAppRODataDir = " << mAppRODataDir << llendl; +//	llinfos << "mAppRODataDir = " << mAppRODataDir << llendl;  	mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp index 03d2cc25e3..306d7d8ec7 100755 --- a/indra/llvfs/llvfile.cpp +++ b/indra/llvfs/llvfile.cpp @@ -135,7 +135,7 @@ U8* LLVFile::readFile(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, S  		data = NULL;  	}  	else -	{		 +	{  		data = (U8*) ll_aligned_malloc_16(file_size);  		file.read(data, file_size);	/* Flawfinder: ignore */  diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index ad010164eb..4c6e706119 100755 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -165,7 +165,7 @@ if (BUILD_HEADLESS)    set(llwindowheadless_HEADER_FILES         llwindowmesaheadless.h         llmousehandler.h -       ) +    )    add_library (llwindowheadless      ${llwindow_SOURCE_FILES}      ${llwindowheadless_SOURCE_FILES} @@ -180,12 +180,12 @@ if (llwindow_HEADER_FILES)    list(APPEND llwindow_SOURCE_FILES ${llwindow_HEADER_FILES})  endif (llwindow_HEADER_FILES) -list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES}) +  list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES}) -add_library (llwindow -  ${llwindow_SOURCE_FILES} -  ${viewer_SOURCE_FILES} -  ) +  add_library (llwindow +    ${llwindow_SOURCE_FILES} +    ${viewer_SOURCE_FILES} +    )  if (SDL_FOUND)    set_property(TARGET llwindow @@ -193,5 +193,5 @@ if (SDL_FOUND)      )  endif (SDL_FOUND) -target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES}) +  target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES}) diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt index cf96f26a77..17400a203e 100755 --- a/indra/llxml/CMakeLists.txt +++ b/indra/llxml/CMakeLists.txt @@ -42,7 +42,7 @@ list(APPEND llxml_SOURCE_FILES ${llxml_HEADER_FILES})  add_library (llxml ${llxml_SOURCE_FILES})  # Libraries on which this library depends, needed for Linux builds  # Sort by high-level to low-level -target_link_libraries(llxml +target_link_libraries( llxml      ${LLVFS_LIBRARIES}      ${LLMATH_LIBRARIES}      ${LLCOMMON_LIBRARIES} diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l index b2c49083cb..1bb38bbf65 100755 --- a/indra/lscript/lscript_compile/indra.l +++ b/indra/lscript/lscript_compile/indra.l @@ -79,11 +79,9 @@ void parse_string();  #define yyfree indra_free -#if defined(__cplusplus) -extern "C" { int yylex( void ); } -extern "C" { int yyparse( void ); } -extern "C" { int yyerror(const char *fmt, ...); } -#endif +int yylex( void ); +int yyparse( void ); +int yyerror(const char *fmt, ...);  %} diff --git a/indra/lscript/lscript_compile/indra.y b/indra/lscript/lscript_compile/indra.y index e4b10ffdd9..a0a034d21c 100755 --- a/indra/lscript/lscript_compile/indra.y +++ b/indra/lscript/lscript_compile/indra.y @@ -2,10 +2,6 @@  	#include "linden_common.h"  	#include "lscript_tree.h" -    #ifdef __cplusplus -    extern "C" { -    #endif -  	int yylex(void);  	int yyparse( void );  	int yyerror(const char *fmt, ...); @@ -20,9 +16,6 @@  	#pragma warning( disable : 4065 )	// warning: switch statement contains 'default' but no 'case' labels  	#endif -    #ifdef __cplusplus -    } -    #endif  %}  %union diff --git a/indra/mac_crash_logger/CrashReporter.nib b/indra/mac_crash_logger/CrashReporter.nib Binary files differindex a30d8d205c..e9d9e05985 100755 --- a/indra/mac_crash_logger/CrashReporter.nib +++ b/indra/mac_crash_logger/CrashReporter.nib diff --git a/indra/media_plugins/winmmshim/winmm_shim.cpp b/indra/media_plugins/winmmshim/winmm_shim.cpp index 47a1e5c018..aac349bf57 100755 --- a/indra/media_plugins/winmmshim/winmm_shim.cpp +++ b/indra/media_plugins/winmmshim/winmm_shim.cpp @@ -56,7 +56,7 @@ void ll_winmm_shim_initialize(){  		// grab winmm.dll from system path, where it should live  		wsprintf(dll_path, "%s\\winmm.dll", system_path);  		HMODULE winmm_handle = ::LoadLibrary(dll_path); -		 +  		if (winmm_handle != NULL)  		{	// we have a dll, let's get out pointers!  			initialized = true; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 183549dfef..e7c62d7ee9 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -4,6 +4,7 @@ project(viewer)  include(00-Common)  include(Boost) +include(BuildVersion)  include(DBusGlib)  include(DirectX)  include(OpenSSL) @@ -173,6 +174,7 @@ set(viewer_SOURCE_FILES      lldrawpoolavatar.cpp      lldrawpoolbump.cpp      lldrawpoolground.cpp +    lldrawpoolmaterials.cpp      lldrawpoolsimple.cpp      lldrawpoolsky.cpp      lldrawpoolterrain.cpp @@ -358,6 +360,7 @@ set(viewer_SOURCE_FILES      llmaniptranslate.cpp      llmarketplacefunctions.cpp      llmarketplacenotifications.cpp +    llmaterialmgr.cpp      llmediactrl.cpp      llmediadataclient.cpp      llmenuoptionpathfindingrebakenavmesh.cpp @@ -755,6 +758,7 @@ set(viewer_HEADER_FILES      lldrawpoolalpha.h      lldrawpoolavatar.h      lldrawpoolbump.h +    lldrawpoolmaterials.h      lldrawpoolground.h      lldrawpoolsimple.h      lldrawpoolsky.h @@ -940,6 +944,7 @@ set(viewer_HEADER_FILES      llmaniptranslate.h      llmarketplacefunctions.h      llmarketplacenotifications.h +    llmaterialmgr.h      llmediactrl.h      llmediadataclient.h      llmenuoptionpathfindingrebakenavmesh.h @@ -1567,7 +1572,7 @@ endif (WINDOWS)  if (OPENAL)    set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL") -endif (OPENAL)           +endif (OPENAL)  if (FMODEX)    set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX") @@ -1987,7 +1992,7 @@ if (DARWIN)    configure_file(       "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"       "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app/Contents/Info.plist" -               ) +    )    add_custom_command(      TARGET ${VIEWER_BINARY_NAME} POST_BUILD @@ -2141,6 +2146,40 @@ if (LL_TESTS)    )    set_source_files_properties( +    llviewerhelputil.cpp +    PROPERTIES +    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" +  ) + +  set_source_files_properties( +    llremoteparcelrequest.cpp +    PROPERTIES +    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" +  ) + +  set_source_files_properties( +    llworldmap.cpp +    llworldmipmap.cpp +    PROPERTIES +    LL_TEST_ADDITIONAL_SOURCE_FILES  +    tests/llviewertexture_stub.cpp +    #llviewertexturelist.cpp +    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" +  ) + +  set_source_files_properties( +    llmediadataclient.cpp +    PROPERTIES +    LL_TEST_ADDITIONAL_LIBRARIES "${LLPRIMITIVE_LIBRARIES}" +  ) + +  set_source_files_properties( +    llagentaccess.cpp +    PROPERTIES +    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" +  ) + +  set_source_files_properties(      lllogininstance.cpp      PROPERTIES      LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 65afb3b886..9575d51bad 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.5.4 +3.6.1 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f356cff9d8..12ca902c59 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2873,6 +2873,17 @@        <key>Value</key>        <integer>0</integer>      </map> +  <key>DefaultBlankNormalTexture</key> +  <map> +    <key>Comment</key> +    <string>Texture used as 'Blank' in texture picker for normal maps. (UUID texture reference)</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>String</string> +    <key>Value</key> +    <string>5b53359e-59dd-d8a2-04c3-9e65134da47a</string> +  </map>  	<key>DefaultFemaleAvatar</key>  	<map>  	  <key>Comment</key> @@ -2895,8 +2906,29 @@  	  <key>Value</key>  	  <string>Male Shape & Outfit</string>  	</map> - -    <key>DefaultObjectTexture</key> +  <key>DefaultObjectNormalTexture</key> +  <map> +    <key>Comment</key> +    <string>Texture used as 'Default' in texture picker for normal map. (UUID texture reference)</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>String</string> +    <key>Value</key> +    <string>85f28839-7a1c-b4e3-d71d-967792970a7b</string> +  </map> +  <key>DefaultObjectSpecularTexture</key> +  <map> +    <key>Comment</key> +    <string>Texture used as 'Default' in texture picker for specular map. (UUID texture reference)</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>String</string> +    <key>Value</key> +    <string>87e0e8f7-8729-1ea8-cfc9-8915773009db</string> +  </map> +  <key>DefaultObjectTexture</key>      <map>        <key>Comment</key>        <string>Texture used as 'Default' in texture picker. (UUID texture reference)</string> @@ -3347,17 +3379,6 @@        <key>Value</key>        <integer>1</integer>      </map> -    <key>EnableTextureAtlas</key> -    <map> -      <key>Comment</key> -      <string>Whether to use texture atlas or not</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>0</integer> -    </map>      <key>EnableUIHints</key>      <map>        <key>Comment</key> @@ -8440,7 +8461,7 @@    <key>RenderSpotLightsInNondeferred</key>    <map>      <key>Comment</key> -    <string>Whether to support projectors as spotlights when Lighting and Shadows is disabled</string> +    <string>Whether to support projectors as spotlights when Advanced Lighting Model is disabled</string>      <key>Persist</key>      <integer>1</integer>      <key>Type</key> @@ -8581,7 +8602,7 @@      <key>Type</key>      <string>U32</string>      <key>Value</key> -    <real>512</real> +    <real>1024</real>    </map>    <key>RenderSpecularResY</key> @@ -8593,7 +8614,7 @@      <key>Type</key>      <string>U32</string>      <key>Value</key> -    <real>128</real> +    <real>256</real>    </map>    <key>RenderSpecularExponent</key> @@ -8611,7 +8632,7 @@    <key>RenderDeferred</key>    <map>      <key>Comment</key> -    <string>Use deferred rendering pipeline.</string> +    <string>Use deferred rendering pipeline (Advanced Lighting Model).</string>      <key>Persist</key>      <integer>1</integer>      <key>Type</key> @@ -8799,7 +8820,7 @@      <key>RenderAutoMaskAlphaNonDeferred</key>      <map>        <key>Comment</key> -      <string>Use alpha masks where appropriate, in the non-deferred (non-'Lighting and Shadows') graphics mode</string> +      <string>Use alpha masks where appropriate when not using the Advanced Lighting Model</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -8810,7 +8831,7 @@      <key>RenderAutoMaskAlphaDeferred</key>      <map>        <key>Comment</key> -      <string>Use alpha masks where appropriate, in the deferred ('Lighting and Shadows') graphics mode</string> +      <string>Use alpha masks where appropriate in the Advanced Lighting Model</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -12461,17 +12482,6 @@        <key>Value</key>        <integer>3</integer>      </map> -    <key>UpdaterWillingToTest</key> -    <map> -      <key>Comment</key> -      <string>Allow upgrades to release candidate viewers with new features and fixes.</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>1</integer> -    </map>      <key>UpdaterServiceCheckPeriod</key>      <map>        <key>Comment</key> @@ -12855,7 +12865,6 @@        <key>Type</key>        <string>LLSD</string>        <key>Value</key> -      <string/>      </map>      <key>VFSOldSize</key>      <map> @@ -14524,5 +14533,16 @@      <key>Value</key>      <integer>7000</integer>    </map> +  <key>DisablePrecacheDelayAfterTeleporting</key> +  <map> +    <key>Comment</key> +    <string>Disables the artificial delay in the viewer that precaches some incoming assets</string> +    <key>Persist</key> +    <integer>0</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map>  </map>  </llsd> diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index dd87ddb330..77a53a71aa 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -25,17 +25,33 @@  #extension GL_ARB_texture_rectangle : enable +#define INDEXED 1 +#define NON_INDEXED 2 +#define NON_INDEXED_NO_COLOR 3 +  #ifdef DEFINE_GL_FRAGCOLOR  out vec4 frag_color;  #else  #define frag_color gl_FragColor  #endif -uniform sampler2DRect depthMap; +#if HAS_SHADOW +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; -vec4 diffuseLookup(vec2 texcoord); +uniform vec2 shadow_res; -uniform vec2 screen_res; +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float shadow_bias; + +#endif + +#ifdef USE_DIFFUSE_TEX +uniform sampler2D diffuseMap; +#endif  vec3 atmosLighting(vec3 light);  vec3 scaleSoftClip(vec3 light); @@ -45,11 +61,77 @@ VARYING vec3 vary_directional;  VARYING vec3 vary_fragcoord;  VARYING vec3 vary_position;  VARYING vec3 vary_pointlight_col; +VARYING vec2 vary_texcoord0; +VARYING vec3 vary_norm; +#ifdef USE_VERTEX_COLOR  VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; +#endif + +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec3 light_attenuation[8];  +uniform vec3 light_diffuse[8]; + +uniform vec2 screen_res; + +vec3 calcDirectionalLight(vec3 n, vec3 l) +{ +	float a = max(dot(n,l),0.0); +	return vec3(a,a,a); +} + +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ +	//get light vector +	vec3 lv = lp.xyz-v; +	 +	//get distance +	float d = dot(lv,lv); +	 +	float da = 0.0; + +	if (d > 0.0 && la > 0.0 && fa > 0.0) +	{ +		//normalize light vector +		lv = normalize(lv); +	 +		//distance attenuation +		float dist2 = d/la; +		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); +		da = pow(da, 2.2) * 2.2; + +		// spotlight coefficient. +		float spot = max(dot(-ln, lv), is_pointlight); +		da *= spot*spot; // GL_SPOT_EXPONENT=2 + +		//angular attenuation +		da *= max(dot(n, lv), 0.0);		 +	} + +	return vec3(da,da,da);	 +} + +#if HAS_SHADOW +float pcfShadow(sampler2DShadow shadowMap, vec4 stc) +{ +	stc.xyz /= stc.w; +	stc.z += shadow_bias; +		 +	stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here +	 +	float cs = shadow2D(shadowMap, stc.xyz).x; +	float shadow = cs; +	 +    shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; +                        +    return shadow*0.2; +} +#endif -uniform mat4 inv_proj;  void main()   { @@ -58,16 +140,119 @@ void main()  	vec4 pos = vec4(vary_position, 1.0); -	vec4 diff= diffuseLookup(vary_texcoord0.xy); -	vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a); +#if HAS_SHADOW +	float shadow = 0.0; +	vec4 spos = pos; +		 +	if (spos.z > -shadow_clip.w) +	{	 +		vec4 lpos; +		 +		vec4 near_split = shadow_clip*-0.75; +		vec4 far_split = shadow_clip*-1.25; +		vec4 transition_domain = near_split-far_split; +		float weight = 0.0; + +		if (spos.z < near_split.z) +		{ +			lpos = shadow_matrix[3]*spos; +			 +			float w = 1.0; +			w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; +			shadow += pcfShadow(shadowMap3, lpos)*w; +			weight += w; +			shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +		} + +		if (spos.z < near_split.y && spos.z > far_split.z) +		{ +			lpos = shadow_matrix[2]*spos; +			 +			float w = 1.0; +			w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; +			w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; +			shadow += pcfShadow(shadowMap2, lpos)*w; +			weight += w; +		} + +		if (spos.z < near_split.x && spos.z > far_split.y) +		{ +			lpos = shadow_matrix[1]*spos; +			 +			float w = 1.0; +			w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; +			w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; +			shadow += pcfShadow(shadowMap1, lpos)*w; +			weight += w; +		} + +		if (spos.z > far_split.x) +		{ +			lpos = shadow_matrix[0]*spos; +							 +			float w = 1.0; +			w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; +				 +			shadow += pcfShadow(shadowMap0, lpos)*w; +			weight += w; +		} +		 + +		shadow /= weight; +	} +	else +	{ +		shadow = 1.0; +	} +#endif + +#ifdef USE_INDEXED_TEX +	vec4 diff = diffuseLookup(vary_texcoord0.xy); +#else +	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); +#endif + +	diff.rgb = pow(diff.rgb, vec3(2.2f, 2.2f, 2.2f)); + +#ifdef USE_VERTEX_COLOR +	float vertex_color_alpha = vertex_color.a;	 +#else +	float vertex_color_alpha = 1.0; +#endif +	 +	vec3 normal = vary_norm;  +	 +	vec3 l = light_position[0].xyz; +	vec3 dlight = calcDirectionalLight(normal, l) * 2.6; +	dlight = dlight * vary_directional.rgb * vary_pointlight_col; + +#if HAS_SHADOW +	vec4 col = vec4(vary_ambient + dlight * shadow, vertex_color_alpha); +#else +	vec4 col = vec4(vary_ambient + dlight, vertex_color_alpha); +#endif +  	vec4 color = diff * col;  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); +	col = vec4(0,0,0,0); + +   #define LIGHT_LOOP(i) col.rgb += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, normal, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + +	LIGHT_LOOP(1) +	LIGHT_LOOP(2) +	LIGHT_LOOP(3) +	LIGHT_LOOP(4) +	LIGHT_LOOP(5) +	LIGHT_LOOP(6) +	LIGHT_LOOP(7) + +	color.rgb += diff.rgb * vary_pointlight_col * col.rgb; -	color.rgb += diff.rgb * vary_pointlight_col.rgb; +	color.rgb = pow(color.rgb, vec3(1.0/2.2));  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl index beb3290187..2ce44d599f 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl @@ -47,9 +47,51 @@ VARYING vec3 vary_position;  VARYING vec3 vary_pointlight_col;  VARYING vec2 vary_texcoord0;  VARYING vec4 vertex_color; +VARYING vec3 vary_norm;  uniform mat4 inv_proj; +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec3 light_attenuation[8];  +uniform vec3 light_diffuse[8]; + +vec3 calcDirectionalLight(vec3 n, vec3 l) +{ +        float a = pow(max(dot(n,l),0.0), 0.7); +        return vec3(a,a,a); +} + +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ +	//get light vector +	vec3 lv = lp.xyz-v; +	 +	//get distance +	float d = dot(lv,lv); +	 +	float da = 0.0; + +	if (d > 0.0 && la > 0.0 && fa > 0.0) +	{ +		//normalize light vector +		lv = normalize(lv); +	 +		//distance attenuation +		float dist2 = d/la; +		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + +		// spotlight coefficient. +		float spot = max(dot(-ln, lv), is_pointlight); +		da *= spot*spot; // GL_SPOT_EXPONENT=2 + +		//angular attenuation +		da *= max(pow(dot(n, lv), 0.7), 0.0);		 +	} + +	return vec3(da,da,da);	 +} +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).a; @@ -72,14 +114,33 @@ void main()  	vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy); -	vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a); +	vec3 n = vary_norm; +	vec3 l = light_position[0].xyz; +	vec3 dlight = calcDirectionalLight(n, l); +	dlight = dlight * vary_directional.rgb * vary_pointlight_col; + +	vec4 col = vec4(vary_ambient + dlight, vertex_color.a);  	vec4 color = diff * col;  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); +	vec3 light_col = vec3(0,0,0); + +  #define LIGHT_LOOP(i) \ +	light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + +	LIGHT_LOOP(1) +	LIGHT_LOOP(2) +	LIGHT_LOOP(3) +	LIGHT_LOOP(4) +	LIGHT_LOOP(5) +	LIGHT_LOOP(6) +	LIGHT_LOOP(7) + +	color.rgb += diff.rgb * vary_pointlight_col * light_col; -	color.rgb += diff.rgb * vary_pointlight_col.rgb; +	color.rgb = pow(color.rgb, vec3(1.0/2.2));  	frag_color = color;  	//frag_color = vec4(1,0,1,1); diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl index 5a0e8ff684..5f93986f1d 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl @@ -46,6 +46,7 @@ VARYING vec3 vary_pointlight_col;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +VARYING vec3 vary_norm;  uniform float near_clip; @@ -104,7 +105,7 @@ void main()  	norm = position.xyz + normal.xyz;  	norm = normalize(( trans*vec4(norm, 1.0) ).xyz-pos.xyz); -	 +	vary_norm = norm;  	vec4 frag_pos = projection_matrix * pos;  	gl_Position = frag_pos; @@ -112,27 +113,18 @@ void main()  	calcAtmospherics(pos.xyz); +	//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));  	vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a); - -	// Collect normal lights -	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z); -	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z); -	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z); -	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z); -	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z); -	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z); - -	vary_pointlight_col = col.rgb*diffuse_color.rgb; - +	vary_pointlight_col = diffuse_color.rgb;  	col.rgb = vec3(0,0,0);  	// Add windlight lights  	col.rgb = atmosAmbient(vec3(0.));  	vary_ambient = col.rgb*diffuse_color.rgb; -	vary_directional = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a))); +	vary_directional.rgb = atmosAffectDirectionalLight(1); -	col.rgb = min(col.rgb*diffuse_color.rgb, 1.0); +	col.rgb = col.rgb*diffuse_color.rgb;  	vertex_color = col; diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index cf38a2f4f7..247ee0a34f 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -23,21 +23,42 @@   * $/LicenseInfo$   */ +#define INDEXED 1 +#define NON_INDEXED 2 +#define NON_INDEXED_NO_COLOR 3 +  uniform mat3 normal_matrix;  uniform mat4 texture_matrix0; +uniform mat4 projection_matrix;  uniform mat4 modelview_matrix;  uniform mat4 modelview_projection_matrix;  ATTRIBUTE vec3 position; + +#ifdef USE_INDEXED_TEX  void passTextureIndex(); +#endif +  ATTRIBUTE vec3 normal; + +#ifdef USE_VERTEX_COLOR  ATTRIBUTE vec4 diffuse_color; +#endif +  ATTRIBUTE vec2 texcoord0; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +#else +#ifdef IS_AVATAR_SKIN +mat4 getSkinnedTransform(); +#endif +#endif +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye); -float calcDirectionalLight(vec3 n, vec3 l); +vec3 calcDirectionalLight(vec3 n, vec3 l);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -50,26 +71,30 @@ VARYING vec3 vary_fragcoord;  VARYING vec3 vary_position;  VARYING vec3 vary_pointlight_col; +#ifdef USE_VERTEX_COLOR  VARYING vec4 vertex_color; +#endif +  VARYING vec2 vary_texcoord0; +VARYING vec3 vary_norm;  uniform float near_clip; -uniform float shadow_offset; -uniform float shadow_bias;  uniform vec4 light_position[8];  uniform vec3 light_direction[8];  uniform vec3 light_attenuation[8];   uniform vec3 light_diffuse[8]; -float calcDirectionalLight(vec3 n, vec3 l) +uniform vec3 sun_dir; + +vec3 calcDirectionalLight(vec3 n, vec3 l)  {          float a = max(dot(n,l),0.0); -        return a; +        return vec3(a,a,a);  } -float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)  {  	//get light vector  	vec3 lv = lp.xyz-v; @@ -96,53 +121,110 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  		da *= max(dot(n, lv), 0.0);		  	} -	return da;	 +	return vec3(da,da,da);	  }  void main()  { +	vec4 pos; +	vec3 norm; +	  	//transform vertex +#ifdef HAS_SKIN +	mat4 trans = getObjectSkinnedTransform(); +	trans = modelview_matrix * trans; +	 +	pos = trans * vec4(position.xyz, 1.0); +	 +	norm = position.xyz + normal.xyz; +	norm = normalize((trans * vec4(norm, 1.0)).xyz - pos.xyz); +	vec4 frag_pos = projection_matrix * pos; +	gl_Position = frag_pos; +#else + +#ifdef IS_AVATAR_SKIN +	mat4 trans = getSkinnedTransform(); +	vec4 pos_in = vec4(position.xyz, 1.0); +	pos.x = dot(trans[0], pos_in); +	pos.y = dot(trans[1], pos_in); +	pos.z = dot(trans[2], pos_in); +	pos.w = 1.0; +	 +	norm.x = dot(trans[0].xyz, normal); +	norm.y = dot(trans[1].xyz, normal); +	norm.z = dot(trans[2].xyz, normal); +	norm = normalize(norm); +	 +	vec4 frag_pos = projection_matrix * pos; +	gl_Position = frag_pos; +#else +	norm = normalize(normal_matrix * normal);  	vec4 vert = vec4(position.xyz, 1.0); -	passTextureIndex(); -	vec4 pos = (modelview_matrix * vert); +	pos = (modelview_matrix * vert);  	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +#endif +#endif + +#ifdef USE_INDEXED_TEX +	passTextureIndex();  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; +#else +	vary_texcoord0 = texcoord0; +#endif -	vec3 norm = normalize(normal_matrix * normal); -	 -	float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz)); -	vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset; -		 +	vary_norm = norm; +	vary_position = pos.xyz; +  	calcAtmospherics(pos.xyz); +#ifndef USE_VERTEX_COLOR +	vec4 diffuse_color = vec4(1,1,1,1); +#endif  	//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));  	vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a); +	 +	vec3 diff = pow(diffuse_color.rgb, vec3(2.2)); + +	 + +	vary_pointlight_col = diff; -	// Collect normal lights -	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z); -	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z); -	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z); -	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z); -	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z); -	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z); -	vary_pointlight_col = col.rgb*diffuse_color.rgb;  	col.rgb = vec3(0,0,0);  	// Add windlight lights -	col.rgb = atmosAmbient(vec3(0.)); +	col.rgb = atmosAmbient(col.rgb); -	vary_ambient = col.rgb*diffuse_color.rgb; -	vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a))); +	float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); +	ambient *= 0.5; +	ambient *= ambient; +	ambient = (1.0-ambient); + +	col.rgb *= ambient; + +	vary_ambient = col.rgb*diff.rgb; + +	vary_directional.rgb = atmosAffectDirectionalLight(1.0f); -	col.rgb = col.rgb*diffuse_color.rgb; +	col.rgb = col.rgb*diff.rgb; +#ifdef USE_VERTEX_COLOR  	vertex_color = col; - -	 +#endif +#ifdef HAS_SKIN +	vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip); +#else + +#ifdef IS_AVATAR_SKIN +	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); +#else  	pos = modelview_projection_matrix * vert;  	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); +#endif +#endif +  } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl index 81961d7746..3f90600ace 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl @@ -39,7 +39,12 @@ void main()  	mat = modelview_matrix * mat;  	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; +  	vec4 p = projection_matrix * vec4(pos, 1.0); +#if !DEPTH_CLAMP  	p.z = max(p.z, -p.w+0.01);  	gl_Position = p; +#else +	gl_Position = p; +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl index 5f395801e5..c8ddefac26 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl @@ -47,6 +47,7 @@ VARYING vec3 vary_directional;  VARYING vec3 vary_fragcoord;  VARYING vec3 vary_pointlight_col;  VARYING vec2 vary_texcoord0; +VARYING vec3 vary_norm;  uniform float near_clip; @@ -112,6 +113,7 @@ void main()  	norm.y = dot(trans[1].xyz, normal);  	norm.z = dot(trans[2].xyz, normal);  	norm = normalize(norm); +	vary_norm = norm;  	vec4 frag_pos = projection_matrix * pos;  	gl_Position = frag_pos; diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index bfd9b9b3eb..bcccbf77d2 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -34,6 +34,12 @@ uniform sampler2D diffuseMap;  VARYING vec3 vary_normal;  VARYING vec2 vary_texcoord0; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec4 diff = texture2D(diffuseMap, vary_texcoord0.xy); @@ -46,6 +52,6 @@ void main()  	frag_data[0] = vec4(diff.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0);  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl index 3686f2f647..b809b73973 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl @@ -31,12 +31,16 @@ out vec4 frag_color;  uniform sampler2D diffuseMap; +#if !DEPTH_CLAMP  VARYING vec4 post_pos; +#endif  void main()   {  	frag_color = vec4(1,1,1,1); +#if !DEPTH_CLAMP  	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl index 23feb09d72..bde1ad4e9f 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl @@ -31,7 +31,9 @@ ATTRIBUTE vec3 position;  ATTRIBUTE vec3 normal;  ATTRIBUTE vec2 texcoord0; +#if !DEPTH_CLAMP  VARYING vec4 post_pos; +#endif  void main()  { @@ -51,9 +53,13 @@ void main()  	norm = normalize(norm);  	pos = projection_matrix * pos; +#if !DEPTH_CLAMP  	post_pos = pos;  	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index f400eb7a5b..eebeb91bf8 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -64,11 +64,46 @@ vec4 getPosition(vec2 pos_screen)  	return pos;  } +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  void main()   {      vec2 tc = vary_fragcoord.xy;  	vec3 norm = texture2DRect(normalMap, tc).xyz; -	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +	norm = decode_normal(norm.xy); // unpack norm +  	vec3 pos = getPosition(tc).xyz;  	vec4 ccol = texture2DRect(lightMap, tc).rgba; diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 23c4ea2fff..595c11fae2 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -39,6 +39,12 @@ VARYING vec3 vary_mat2;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb; @@ -52,5 +58,5 @@ void main()  	frag_data[1] = vertex_color.aaaa; // spec  	//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested  	vec3 nvn = normalize(tnorm); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl index 8ba75010a2..10144f3e16 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl @@ -30,7 +30,7 @@ ATTRIBUTE vec3 position;  ATTRIBUTE vec4 diffuse_color;  ATTRIBUTE vec3 normal;  ATTRIBUTE vec2 texcoord0; -ATTRIBUTE vec3 binormal; +ATTRIBUTE vec4 tangent;  VARYING vec3 vary_mat0;  VARYING vec3 vary_mat1; @@ -52,8 +52,8 @@ void main()  	vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz); -	vec3 b = normalize((mat * vec4(binormal.xyz+position.xyz, 1.0)).xyz-pos.xyz); -	vec3 t = cross(b, n); +	vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz); +	vec3 b = cross(n, t) * tangent.w;  	vary_mat0 = vec3(t.x, b.x, n.x);  	vary_mat1 = vec3(t.y, b.y, n.y); diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index c8d38bb8f7..9f9749394e 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -31,7 +31,7 @@ ATTRIBUTE vec3 position;  ATTRIBUTE vec4 diffuse_color;  ATTRIBUTE vec3 normal;  ATTRIBUTE vec2 texcoord0; -ATTRIBUTE vec3 binormal; +ATTRIBUTE vec4 tangent;  VARYING vec3 vary_mat0;  VARYING vec3 vary_mat1; @@ -46,8 +46,8 @@ void main()  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;  	vec3 n = normalize(normal_matrix * normal); -	vec3 b = normalize(normal_matrix * binormal); -	vec3 t = cross(b, n); +	vec3 t = normalize(normal_matrix * tangent.xyz); +	vec3 b = cross(n, t) * tangent.w;  	vary_mat0 = vec3(t.x, b.x, n.x);  	vary_mat1 = vec3(t.y, b.y, n.y); diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl index c1fa9e4aac..7930b5d18b 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl @@ -37,6 +37,12 @@ VARYING vec3 vary_normal;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color; @@ -49,6 +55,6 @@ void main()  	frag_data[0] = vec4(col.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0); // spec  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl index 4c68123fac..59d109b886 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl @@ -36,6 +36,12 @@ uniform float minimum_alpha;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color; @@ -48,5 +54,5 @@ void main()  	frag_data[0] = vec4(col.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0);  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl index ad65c7d330..37d70a2412 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl @@ -37,6 +37,12 @@ uniform sampler2D diffuseMap;  VARYING vec3 vary_normal;  VARYING vec2 vary_texcoord0; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy); @@ -49,6 +55,6 @@ void main()  	frag_data[0] = vec4(col.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0); // spec  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 86390bdd83..6befb1bd8b 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -35,6 +35,12 @@ VARYING vec3 vary_normal;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb; @@ -42,6 +48,6 @@ void main()  	frag_data[1] = vertex_color.aaaa; // spec  	//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl index 788b966af8..a2c3ec3355 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl @@ -33,13 +33,20 @@ VARYING vec3 vary_normal;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +  void main()   {  	vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;  	frag_data[0] = vec4(col, 0.0);  	frag_data[1] = vertex_color.aaaa; // spec -	//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested +	frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 76d29b1df7..3c026796c8 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -47,6 +47,6 @@ void main()  	passTextureIndex();  	vary_normal = normalize(normal_matrix * normal); - +	  	vertex_color = diffuse_color;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl index 6aa4d7b4ed..ed02c4a481 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl @@ -42,7 +42,7 @@ void main()  	float shadow = 1.0;  	vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color; -	 +	color.rgb = pow(color.rgb, vec3(2.2));  	color.rgb = fullbrightAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 36433a5827..dc1dead656 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -31,6 +31,10 @@ out vec4 frag_color;  #define frag_color gl_FragColor  #endif +#if !HAS_DIFFUSE_LOOKUP +uniform sampler2D diffuseMap; +#endif +  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; @@ -40,14 +44,20 @@ vec3 fullbrightScaleSoftClip(vec3 light);  void main()   { -	float shadow = 1.0; - +#if HAS_DIFFUSE_LOOKUP  	vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color; +#else +	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy)*vertex_color; +#endif + +	color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f));  	color.rgb = fullbrightAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); +	color.rgb = pow(color.rgb, vec3(1.0/2.2)); +  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl new file mode 100644 index 0000000000..b0db9876d3 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl @@ -0,0 +1,72 @@ +/**  + * @file fullbrightShinyF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ +  + + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +#ifndef diffuseLookup +uniform sampler2D diffuseMap; +#endif + +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; +VARYING vec3 vary_texcoord1; + +uniform samplerCube environmentMap; + +vec3 fullbrightShinyAtmosTransport(vec3 light); +vec3 fullbrightScaleSoftClip(vec3 light); + +void main() +{ +#if HAS_DIFFUSE_LOOKUP +	vec4 color = diffuseLookup(vary_texcoord0.xy); +#else +	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy); +#endif + +	 +	color.rgb *= vertex_color.rgb; +	 +	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	 +	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a); + +	color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f)); +	 +	color.rgb = fullbrightShinyAtmosTransport(color.rgb); +	color.rgb = fullbrightScaleSoftClip(color.rgb); + +	color.a = 1.0; + +	color.rgb = pow(color.rgb, vec3(1.0/2.2)); + +	frag_color = color; +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl new file mode 100644 index 0000000000..34bd8d445a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl @@ -0,0 +1,67 @@ +/** + * @file fullbrightShinyV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat3 normal_matrix; +uniform mat4 texture_matrix0; +uniform mat4 texture_matrix1; +uniform mat4 modelview_matrix; +uniform mat4 modelview_projection_matrix; + + +void calcAtmospherics(vec3 inPositionEye); + +uniform vec4 origin; + + + +ATTRIBUTE vec3 position; +void passTextureIndex(); +ATTRIBUTE vec3 normal; +ATTRIBUTE vec4 diffuse_color; +ATTRIBUTE vec2 texcoord0; + +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; +VARYING vec3 vary_texcoord1; + + +void main() +{ +	//transform vertex +	vec4 vert = vec4(position.xyz,1.0); +	passTextureIndex(); +	vec4 pos = (modelview_matrix * vert); +	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +	 +	vec3 norm = normalize(normal_matrix * normal); +	vec3 ref = reflect(pos.xyz, -norm); + +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; +	vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz; + +	calcAtmospherics(pos.xyz); + +	vertex_color = diffuse_color; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index 2e6982d101..3f09a15375 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -57,8 +57,6 @@ void main()  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;  	calcAtmospherics(pos.xyz); -	 -	vertex_color = diffuse_color; -	 +	vertex_color = diffuse_color;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl new file mode 100644 index 0000000000..de2f74b681 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -0,0 +1,695 @@ +/**  + * @file materialF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ +  +#define DIFFUSE_ALPHA_MODE_IGNORE	0 +#define DIFFUSE_ALPHA_MODE_BLEND	1 +#define DIFFUSE_ALPHA_MODE_MASK		2 +#define DIFFUSE_ALPHA_MODE_EMISSIVE 3 + +uniform float emissive_brightness; + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +#if HAS_SUN_SHADOW + +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform vec2 shadow_res; +uniform float shadow_bias; + +float pcfShadow(sampler2DShadow shadowMap, vec4 stc) +{ +	stc.xyz /= stc.w; +	stc.z += shadow_bias; +		 +	stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here +	 +	float cs = shadow2D(shadowMap, stc.xyz).x; +	float shadow = cs; +	 +    shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; +                        +    return shadow*0.2; +} + +#endif + +uniform samplerCube environmentMap; +uniform sampler2D	  lightFunc; + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; +//uniform vec4 camPosWorld; +uniform vec4 gamma; +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform float haze_horizon; +uniform float haze_density; +uniform float cloud_shadow; +uniform float density_multiplier; +uniform float distance_multiplier; +uniform float max_y; +uniform vec4 glow; +uniform float scene_light_strength; +uniform mat3 env_mat; +uniform mat3 ssao_effect_mat; + +uniform vec3 sun_dir; +VARYING vec2 vary_fragcoord; + +VARYING vec3 vary_position; + +vec3 vary_PositionEye; + +vec3 vary_SunlitColor; +vec3 vary_AmblitColor; +vec3 vary_AdditiveColor; +vec3 vary_AtmosAttenuation; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec3 light_attenuation[8];  +uniform vec3 light_diffuse[8]; + +vec3 calcDirectionalLight(vec3 n, vec3 l) +{ +	float a = max(dot(n,l),0.0); +	return vec3(a,a,a); +} + + +vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare) +{ +	//get light vector +	vec3 lv = lp.xyz-v; +	 +	//get distance +	float d = dot(lv,lv); +	 +	float da = 1.0; + +	vec3 col = vec3(0,0,0); + +	if (d > 0.0 && la > 0.0 && fa > 0.0) +	{ +		//normalize light vector +		lv = normalize(lv); +	 +		//distance attenuation +		float dist2 = d/la; +		float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + +		// spotlight coefficient. +		float spot = max(dot(-ln, lv), is_pointlight); +		da *= spot*spot; // GL_SPOT_EXPONENT=2 + +		//angular attenuation +		da *= max(dot(n, lv), 0.0);		 +		 +		float lit = max(da * dist_atten, 0.0); + +		col = light_col*lit*diffuse; + +		if (spec.a > 0.0) +		{ +			//vec3 ref = dot(pos+lv, norm); +			vec3 h = normalize(lv+npos); +			float nh = dot(n, h); +			float nv = dot(n, npos); +			float vh = dot(npos, h); +			float sa = nh; +			float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; + +			float gtdenom = 2 * nh; +			float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); +								 +			if (nh > 0.0) +			{ +				float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +				vec3 speccol = lit*scol*light_col.rgb*spec.rgb; +				col += speccol; + +				float cur_glare = max(speccol.r, speccol.g); +				cur_glare = max(cur_glare, speccol.b); +				glare = max(glare, speccol.r); +				glare += max(cur_glare, 0.0); +				//col += spec.rgb; +			} +		} +	} + +	return max(col, vec3(0.0,0.0,0.0));	 + +} + +vec4 getPosition_d(vec2 pos_screen, float depth) +{ +	vec2 sc = pos_screen.xy*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +vec3 getPositionEye() +{ +	return vary_PositionEye; +} +vec3 getSunlitColor() +{ +	return vary_SunlitColor; +} +vec3 getAmblitColor() +{ +	return vary_AmblitColor; +} +vec3 getAdditiveColor() +{ +	return vary_AdditiveColor; +} +vec3 getAtmosAttenuation() +{ +	return vary_AtmosAttenuation; +} + +void setPositionEye(vec3 v) +{ +	vary_PositionEye = v; +} + +void setSunlitColor(vec3 v) +{ +	vary_SunlitColor = v; +} + +void setAmblitColor(vec3 v) +{ +	vary_AmblitColor = v; +} + +void setAdditiveColor(vec3 v) +{ +	vary_AdditiveColor = v; +} + +void setAtmosAttenuation(vec3 v) +{ +	vary_AtmosAttenuation = v; +} + +void calcAtmospherics(vec3 inPositionEye, float ambFactor) { + +	vec3 P = inPositionEye; +	setPositionEye(P); +	 +	vec3 tmpLightnorm = lightnorm.xyz; + +	vec3 Pn = normalize(P); +	float Plen = length(P); + +	vec4 temp1 = vec4(0); +	vec3 temp2 = vec3(0); +	vec4 blue_weight; +	vec4 haze_weight; +	vec4 sunlight = sunlight_color; +	vec4 light_atten; + +	//sunlight attenuation effect (hue and brightness) due to atmosphere +	//this is used later for sunlight modulation at various altitudes +	light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); +		//I had thought blue_density and haze_density should have equal weighting, +		//but attenuation due to haze_density tends to seem too strong + +	temp1 = blue_density + vec4(haze_density); +	blue_weight = blue_density / temp1; +	haze_weight = vec4(haze_density) / temp1; + +	//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) +	temp2.y = max(0.0, tmpLightnorm.y); +	temp2.y = 1. / temp2.y; +	sunlight *= exp( - light_atten * temp2.y); + +	// main atmospheric scattering line integral +	temp2.z = Plen * density_multiplier; + +	// Transparency (-> temp1) +	// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati +	// compiler gets confused. +	temp1 = exp(-temp1 * temp2.z * distance_multiplier); + +	//final atmosphere attenuation factor +	setAtmosAttenuation(temp1.rgb); +	 +	//compute haze glow +	//(can use temp2.x as temp because we haven't used it yet) +	temp2.x = dot(Pn, tmpLightnorm.xyz); +	temp2.x = 1. - temp2.x; +		//temp2.x is 0 at the sun and increases away from sun +	temp2.x = max(temp2.x, .03);	//was glow.y +		//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) +	temp2.x *= glow.x; +		//higher glow.x gives dimmer glow (because next step is 1 / "angle") +	temp2.x = pow(temp2.x, glow.z); +		//glow.z should be negative, so we're doing a sort of (1 / "angle") function + +	//add "minimum anti-solar illumination" +	temp2.x += .25; +	 +	//increase ambient when there are more clouds +	vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; +	 +	/*  decrease value and saturation (that in HSV, not HSL) for occluded areas +	 * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html +	 * // The following line of code performs the equivalent of: +	 * float ambAlpha = tmpAmbient.a; +	 * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis +	 * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); +	 * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); +	 */ +	tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); + +	//haze color +	setAdditiveColor( +		vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) +	  + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x +		  + tmpAmbient))); + +	//brightness of surface both sunlight and ambient +	setSunlitColor(pow(vec3(sunlight * .5), vec3(2.2)) * 2.2); +	setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(2.2)) * 2.2); +	setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(2.2)) * 2.2); +} + +vec3 atmosLighting(vec3 light) +{ +	light *= getAtmosAttenuation().r; +	light += getAdditiveColor(); +	return (2.0 * light); +} + +vec3 atmosTransport(vec3 light) { +	light *= getAtmosAttenuation().r; +	light += getAdditiveColor() * 2.0; +	return light; +} +vec3 atmosGetDiffuseSunlightColor() +{ +	return getSunlitColor(); +} + +vec3 scaleDownLight(vec3 light) +{ +	return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength)); +} + +vec3 scaleUpLight(vec3 light) +{ +	return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength)); +} + +vec3 atmosAmbient(vec3 light) +{ +	return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f)); +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ +	return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity); +} + +vec3 scaleSoftClip(vec3 light) +{ +	//soft clip effect: +    vec3 zeroes = vec3(0.0f, 0.0f, 0.0f); +    vec3 ones   = vec3(1.0f, 1.0f, 1.0f); + +	light = ones - clamp(light, zeroes, ones); +	light = ones - pow(light, gamma.xxx); + +	return light; +} + +vec3 fullbrightAtmosTransport(vec3 light) { +	float brightness = dot(light.rgb, vec3(0.33333)); + +	return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); +} + +vec3 fullbrightScaleSoftClip(vec3 light) +{ +	//soft clip effect: +	return light; +} + +#else +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData +#endif +#endif + +uniform sampler2D diffuseMap; + +#if HAS_NORMAL_MAP +uniform sampler2D bumpMap; +#endif + +#if HAS_SPECULAR_MAP +uniform sampler2D specularMap; + +VARYING vec2 vary_texcoord2; +#endif + +uniform float env_intensity; +uniform vec4 specular_color;  // specular color RGB and specular exponent (glossiness) in alpha + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) +uniform float minimum_alpha; +#endif + +#if HAS_NORMAL_MAP +VARYING vec3 vary_mat0; +VARYING vec3 vary_mat1; +VARYING vec3 vary_mat2; +VARYING vec2 vary_texcoord1; +#else +VARYING vec3 vary_normal; +#endif + +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; + +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif + +void main()  +{ +	vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy); +	diffcol.rgb *= vertex_color.rgb; + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) +	if (diffcol.a < minimum_alpha) +	{ +		discard; +	} +#endif + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) +	vec3 old_diffcol = diffcol.rgb; +	diffcol.rgb = pow(diffcol.rgb, vec3(2.2)); +#endif + +#if HAS_SPECULAR_MAP +	vec4 spec = texture2D(specularMap, vary_texcoord2.xy); +	spec.rgb *= specular_color.rgb; +#else +	vec4 spec = vec4(specular_color.rgb, 1.0); +#endif + +#if HAS_NORMAL_MAP +	vec4 norm = texture2D(bumpMap, vary_texcoord1.xy); + +	norm.xyz = norm.xyz * 2 - 1; + +	vec3 tnorm = vec3(dot(norm.xyz,vary_mat0), +			  dot(norm.xyz,vary_mat1), +			  dot(norm.xyz,vary_mat2)); +#else +	vec4 norm = vec4(0,0,0,1.0); +	vec3 tnorm = vary_normal; +#endif + +    norm.xyz = tnorm; +    norm.xyz = normalize(norm.xyz); + +	vec4 final_color = diffcol; +	 +#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE) +	final_color.a = emissive_brightness; +#else +	final_color.a = max(final_color.a, emissive_brightness); +#endif + +	vec4 final_specular = spec; +#if HAS_SPECULAR_MAP +	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0); +	final_specular.a = specular_color.a * norm.a; +#else +	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0); +	final_specular.a = specular_color.a; +#endif +	 + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) +		//forward rendering, output just lit RGBA +	vec3 pos = vary_position; + +#if HAS_SUN_SHADOW +	float shadow = 0.0; +	 +	vec4 spos = vec4(pos,1.0); +		 +	if (spos.z > -shadow_clip.w) +	{	 +		vec4 lpos; +		 +		vec4 near_split = shadow_clip*-0.75; +		vec4 far_split = shadow_clip*-1.25; +		vec4 transition_domain = near_split-far_split; +		float weight = 0.0; + +		if (spos.z < near_split.z) +		{ +			lpos = shadow_matrix[3]*spos; +			 +			float w = 1.0; +			w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; +			shadow += pcfShadow(shadowMap3, lpos)*w; +			weight += w; +			shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +		} + +		if (spos.z < near_split.y && spos.z > far_split.z) +		{ +			lpos = shadow_matrix[2]*spos; +			 +			float w = 1.0; +			w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; +			w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; +			shadow += pcfShadow(shadowMap2, lpos)*w; +			weight += w; +		} + +		if (spos.z < near_split.x && spos.z > far_split.y) +		{ +			lpos = shadow_matrix[1]*spos; +			 +			float w = 1.0; +			w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; +			w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; +			shadow += pcfShadow(shadowMap1, lpos)*w; +			weight += w; +		} + +		if (spos.z > far_split.x) +		{ +			lpos = shadow_matrix[0]*spos; +							 +			float w = 1.0; +			w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; +				 +			shadow += pcfShadow(shadowMap0, lpos)*w; +			weight += w; +		} +		 + +		shadow /= weight; +	} +	else +	{ +		shadow = 1.0; +	} +#else +	float shadow = 1.0; +#endif + +	spec = final_specular; +	vec4 diffuse = final_color; +	float envIntensity = final_normal.z; + +    vec3 col = vec3(0.0f,0.0f,0.0f); + +	float bloom = 0.0; +	calcAtmospherics(pos.xyz, 1.0); +	 +	vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); + +	float da =dot(norm.xyz, sun_dir.xyz); +    float final_da = da; +          final_da = min(final_da, shadow); +          final_da = max(final_da, diffuse.a); +          final_da = max(final_da, 0.0f); + +	col.rgb = atmosAmbient(col); +	 +	float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); +	ambient *= 0.5; +	ambient *= ambient; +	ambient = (1.0-ambient); + +	col.rgb *= ambient; + +	col.rgb = col.rgb + atmosAffectDirectionalLight(final_da * 2.6); +	col.rgb *= diffuse.rgb; +	 + +	float glare = 0.0; + +	if (spec.a > 0.0) // specular reflection +	{ +		// the old infinite-sky shiny reflection +		// +				 +		float sa = dot(refnormpersp, sun_dir.xyz); +		vec3 dumbshiny = vary_SunlitColor*shadow*(texture2D(lightFunc, vec2(sa, spec.a)).r); +							 +		// add the two types of shiny together +		vec3 spec_contrib = dumbshiny * spec.rgb; +		bloom = dot(spec_contrib, spec_contrib) / 6; + +		glare = max(spec_contrib.r, spec_contrib.g); +		glare = max(glare, spec_contrib.b); + +		col += spec_contrib; +	} + +	col = mix(col.rgb, old_diffcol.rgb, diffuse.a); + +	if (envIntensity > 0.0) +	{ +		//add environmentmap +		vec3 env_vec = env_mat * refnormpersp; +		float exponent = mix(2.2, 1.0, diffuse.a); + +		vec3 refcol = pow(textureCube(environmentMap, env_vec).rgb, vec3(exponent))*exponent; + +		col = mix(col.rgb, refcol,  +			envIntensity);   + +		float cur_glare = max(refcol.r, refcol.g); +		cur_glare = max(cur_glare, refcol.b); +		cur_glare *= envIntensity*4.0; +		glare += cur_glare; +	} + +	float exponent = mix(1.0, 2.2, diffuse.a); +	col = pow(col, vec3(exponent)); +				 +	 +	col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); +	col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); + +			 +	vec3 npos = normalize(-pos.xyz); + + #define LIGHT_LOOP(i) col.rgb = col.rgb + calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare); + +		LIGHT_LOOP(1) +		LIGHT_LOOP(2) +		LIGHT_LOOP(3) +		LIGHT_LOOP(4) +		LIGHT_LOOP(5) +		LIGHT_LOOP(6) +		LIGHT_LOOP(7) + + +	col.rgb = pow(col.rgb, vec3(1.0/2.2)); + +	frag_color.rgb = col.rgb; +	glare = min(glare, 1.0); +	frag_color.a = max(diffcol.a,glare)*vertex_color.a; + +#else +	frag_data[0] = final_color; +	frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent. +	frag_data[2] = final_normal; // XY = Normal.  Z = Env. intensity. +#endif +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl new file mode 100644 index 0000000000..b25032866b --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -0,0 +1,144 @@ +/**  + * @file bumpV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#define DIFFUSE_ALPHA_MODE_IGNORE 0 +#define DIFFUSE_ALPHA_MODE_BLEND 1 +#define DIFFUSE_ALPHA_MODE_MASK 2 +#define DIFFUSE_ALPHA_MODE_EMISSIVE 3 + +#if HAS_SKIN +uniform mat4 modelview_matrix; +uniform mat4 projection_matrix; +mat4 getObjectSkinnedTransform(); +#else +uniform mat3 normal_matrix; +uniform mat4 modelview_projection_matrix; +#endif + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) + +#if !HAS_SKIN +uniform mat4 modelview_matrix; +#endif + +VARYING vec3 vary_position; + +#endif + +uniform mat4 texture_matrix0; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec4 diffuse_color; +ATTRIBUTE vec3 normal; +ATTRIBUTE vec2 texcoord0; + + +#if HAS_NORMAL_MAP +ATTRIBUTE vec4 tangent; +ATTRIBUTE vec2 texcoord1; + +VARYING vec3 vary_mat0; +VARYING vec3 vary_mat1; +VARYING vec3 vary_mat2; + +VARYING vec2 vary_texcoord1; +#else +VARYING vec3 vary_normal; +#endif + +#if HAS_SPECULAR_MAP +ATTRIBUTE vec2 texcoord2; +VARYING vec2 vary_texcoord2; +#endif +  +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; + +void main() +{ +#if HAS_SKIN +	mat4 mat = getObjectSkinnedTransform(); + +	mat = modelview_matrix * mat; + +	vec3 pos = (mat*vec4(position.xyz,1.0)).xyz; + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) +	vary_position = pos; +#endif + +	gl_Position = projection_matrix*vec4(pos,1.0); + +#else +	//transform vertex +	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);  + +#endif +	 +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; +	 +#if HAS_NORMAL_MAP +	vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; +#endif + +#if HAS_SPECULAR_MAP +	vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy; +#endif + +#if HAS_SKIN +	vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); +#if HAS_NORMAL_MAP +	vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz); +	vec3 b = cross(n, t)*tangent.w; +	 +	vary_mat0 = vec3(t.x, b.x, n.x); +	vary_mat1 = vec3(t.y, b.y, n.y); +	vary_mat2 = vec3(t.z, b.z, n.z); +#else //HAS_NORMAL_MAP +vary_normal  = n; +#endif //HAS_NORMAL_MAP +#else //HAS_SKIN +	vec3 n = normalize(normal_matrix * normal); +#if HAS_NORMAL_MAP +	vec3 t = normalize(normal_matrix * tangent.xyz); +	vec3 b = cross(n,t)*tangent.w; +	//vec3 t = cross(b,n) * binormal.w; +	 +	vary_mat0 = vec3(t.x, b.x, n.x); +	vary_mat1 = vec3(t.y, b.y, n.y); +	vary_mat2 = vec3(t.z, b.z, n.z); +#else //HAS_NORMAL_MAP +	vary_normal = n; +#endif //HAS_NORMAL_MAP +#endif //HAS_SKIN +	 +	vertex_color = diffuse_color; + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) +#if !HAS_SKIN +	vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; +#endif +#endif +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 7e79317543..b35ba549f6 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -56,6 +56,40 @@ uniform float far_z;  uniform mat4 inv_proj; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -79,7 +113,7 @@ void main()  	}  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -	norm = (norm.xyz-0.5)*2.0; // unpack norm +	norm = decode_normal(norm.xy); // unpack norm  	norm = normalize(norm);  	vec4 spec = texture2DRect(specularRect, frag.xy);  	vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb; @@ -110,27 +144,39 @@ void main()  		{  			lv = normalize(lv);  			da = dot(norm, lv); -					 +			  			float fa = light_col[i].a+1.0;  			float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); +			 +			dist_atten = pow(dist_atten, 2.2) * 2.2; +  			dist_atten *= noise;  			float lit = da * dist_atten; -			 +						  			vec3 col = light_col[i].rgb*lit*diff; +			  			//vec3 col = vec3(dist2, light_col[i].a, lit);  			if (spec.a > 0.0)  			{ +				lit = min(da*6.0, 1.0) * dist_atten;  				//vec3 ref = dot(pos+lv, norm); -				 -				float sa = dot(normalize(lv+npos),norm); -				 -				if (sa > 0.0) +				vec3 h = normalize(lv+npos); +				float nh = dot(norm, h); +				float nv = dot(norm, npos); +				float vh = dot(npos, h); +				float sa = nh; +				float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; + +				float gtdenom = 2 * nh; +				float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); +								 +				if (nh > 0.0)  				{ -					sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0); -					sa *= noise; -					col += da*sa*light_col[i].rgb*spec.rgb; +					float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +					col += lit*scol*light_col[i].rgb*spec.rgb; +					//col += spec.rgb;  				}  			} diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index bff87cb6aa..36fb4afa52 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -40,6 +40,7 @@ uniform sampler2DRect normalMap;  uniform samplerCube environmentMap;  uniform sampler2D noiseMap;  uniform sampler2D projectionMap; +uniform sampler2D lightFunc;  uniform mat4 proj_mat; //screen space to light space  uniform float proj_near; //near clip for projection @@ -66,9 +67,49 @@ uniform vec2 screen_res;  uniform mat4 inv_proj; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif + +vec4 correctWithGamma(vec4 col) +{ +	return vec4(pow(col.rgb, vec3(2.2)), col.a); +} +  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -84,6 +125,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -101,6 +143,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -142,7 +185,9 @@ void main()  	}  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -	norm = vec3((norm.xy-0.5)*2.0, norm.z); +	float envIntensity = norm.z; + +	norm = decode_normal(norm.xy);  	norm = normalize(norm);  	float l_dist = -dot(lv, proj_n); @@ -157,6 +202,7 @@ void main()  	float fa = falloff+1.0;  	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +	dist_atten = pow(dist_atten, 2.2) * 2.2;  	if (dist_atten <= 0.0)  	{  		discard; @@ -169,7 +215,8 @@ void main()  	vec3 col = vec3(0,0,0);  	vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; -		 +	vec3 dlit = vec3(0, 0, 0); +	  	float noise = texture2D(noiseMap, frag.xy/128.0).b;  	if (proj_tc.z > 0.0 &&  		proj_tc.x < 1.0 && @@ -187,14 +234,13 @@ void main()  			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); -			vec3 lcol = color.rgb * plcol.rgb * plcol.a; +			dlit = color.rgb * plcol.rgb * plcol.a;  			lit = da * dist_atten * noise; -			col = lcol*lit*diff_tex; +			col = dlit*lit*diff_tex;  			amb_da += (da*0.5)*proj_ambiance;  		} -		  		//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);  		vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); @@ -203,14 +249,39 @@ void main()  		amb_da *= dist_atten * noise;  		amb_da = min(amb_da, 1.0-lit); -			 -		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; +		col += amb_da*color.rgb*diff_tex*amb_plcol.rgb*amb_plcol.a;  	}  	vec4 spec = texture2DRect(specularRect, frag.xy); +	  	if (spec.a > 0.0)  	{ +		dlit *= min(da*6.0, 1.0) * dist_atten; + +		vec3 npos = -normalize(pos); + +		//vec3 ref = dot(pos+lv, norm); +		vec3 h = normalize(lv+npos); +		float nh = dot(norm, h); +		float nv = dot(norm, npos); +		float vh = dot(npos, h); +		float sa = nh; +		float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; + +		float gtdenom = 2 * nh; +		float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); + +		if (nh > 0.0) +		{ +			float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +			col += dlit*scol*spec.rgb; +			//col += spec.rgb; +		} +	}	 + +	if (envIntensity > 0.0) +	{  		vec3 ref = reflect(normalize(pos), norm);  		//project from point pos in direction ref to plane proj_p, proj_n @@ -227,8 +298,9 @@ void main()  			{  				stc.xy /= stc.w; -				float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); +				//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				if (stc.x < 1.0 && @@ -236,8 +308,7 @@ void main()  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); -					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb; +					col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb;										  				}  			}  		} diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 75757b26c8..c6b1eb7c8d 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -54,6 +54,40 @@ uniform vec2 screen_res;  uniform mat4 inv_proj;  uniform vec4 viewport; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -84,7 +118,7 @@ void main()  	}  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -	norm = (norm.xyz-0.5)*2.0; // unpack norm +	norm = decode_normal(norm.xy); // unpack norm  	float da = dot(norm, lv);  	if (da < 0.0)  	{ @@ -100,19 +134,30 @@ void main()  	vec3 col = texture2DRect(diffuseRect, frag.xy).rgb;  	float fa = falloff+1.0;  	float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); +	dist_atten = pow(dist_atten, 2.2) * 2.2;  	float lit = da * dist_atten * noise; -	 +  	col = color.rgb*lit*col;  	vec4 spec = texture2DRect(specularRect, frag.xy);  	if (spec.a > 0.0)  	{ -		float sa = dot(normalize(lv-normalize(pos)),norm); -		if (sa > 0.0) +		lit = min(da*6.0, 1.0) * dist_atten; + +		vec3 npos = -normalize(pos); +		vec3 h = normalize(lv+npos); +		float nh = dot(norm, h); +		float nv = dot(norm, npos); +		float vh = dot(npos, h); +		float sa = nh; +		float fres = pow(1 - dot(h, npos), 5) * 0.4+0.5; +		float gtdenom = 2 * nh; +		float gt = max(0,(min(gtdenom * nv / vh, gtdenom * da / vh))); + +		if (nh > 0.0)  		{ -			sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0); -			sa *= noise; -			col += da*sa*color.rgb*spec.rgb; +			float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +			col += lit*scol*color.rgb*spec.rgb;  		}  	} diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl new file mode 100644 index 0000000000..6f2cfae6d2 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -0,0 +1,46 @@ +/**  + * @file postDeferredGammaCorrect.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ +  +#extension GL_ARB_texture_rectangle : enable + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2DRect diffuseRect; + +uniform vec2 screen_res; +VARYING vec2 vary_fragcoord; + +uniform float texture_gamma; + +void main()  +{ +	vec4 diff = texture2DRect(diffuseRect, vary_fragcoord); +	frag_color = pow(diff, vec4(texture_gamma, texture_gamma, texture_gamma, 1.0f)); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl index bced4a5577..91a96977f0 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl @@ -31,8 +31,12 @@ out vec4 frag_color;  uniform sampler2D diffuseMap; +#if !DEPTH_CLAMP  VARYING float pos_zd2; +#endif +  VARYING float pos_w; +  VARYING float target_pos_x;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; @@ -56,5 +60,7 @@ void main()  	frag_color = vec4(1,1,1,1); +#if !DEPTH_CLAMP  	gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0); +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl index c1f2d90712..11411a605c 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl @@ -31,8 +31,12 @@ ATTRIBUTE vec3 position;  ATTRIBUTE vec4 diffuse_color;  ATTRIBUTE vec2 texcoord0; +#if !DEPTH_CLAMP  VARYING float pos_zd2; +#endif +  VARYING float pos_w; +  VARYING float target_pos_x;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; @@ -45,10 +49,16 @@ void main()  	vec4 pre_pos = vec4(position.xyz, 1.0);  	vec4 pos = modelview_projection_matrix * pre_pos;  	target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; +  	pos_w = pos.w; + +#if !DEPTH_CLAMP  	pos_zd2 = pos.z * 0.5;  	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif  	passTextureIndex(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl index 6195e2f1ec..ef153dfc5b 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl @@ -27,7 +27,9 @@ uniform mat4 modelview_projection_matrix;  ATTRIBUTE vec3 position; +#if !DEPTH_CLAMP  VARYING vec4 post_pos; +#endif  uniform vec3 box_center;  uniform vec3 box_size; @@ -37,8 +39,12 @@ void main()  	//transform vertex  	vec3 p = position*box_size+box_center;  	vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0); -	 + +#if !DEPTH_CLAMP  	post_pos = pos; -	 +  	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl index 7e55fdc12a..3d1b182875 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl @@ -29,11 +29,16 @@ out vec4 frag_color;  #define frag_color gl_FragColor  #endif +#if !DEPTH_CLAMP  VARYING vec4 post_pos; +#endif  void main()   {  	frag_color = vec4(1,1,1,1); +#if !DEPTH_CLAMP  	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); +#endif +  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl index 8b46e81f90..cc77a4cea0 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl @@ -27,14 +27,20 @@ uniform mat4 modelview_projection_matrix;  ATTRIBUTE vec3 position; +#if !DEPTH_CLAMP  VARYING vec4 post_pos; +#endif  void main()  {  	//transform vertex  	vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0); +#if !DEPTH_CLAMP  	post_pos = pos; -	 +  	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl index faa54a316e..22f4729e2e 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -61,6 +61,6 @@ void main()  	/// Gamma correct for WL (soft clip effect).  	frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0);  	frag_data[1] = vec4(0.0,0.0,0.0,0.0); -	frag_data[2] = vec4(0,0,1,0); +	frag_data[2] = vec4(0.5,0.5,0.0,1.0); //1.0 in norm.w masks off fog  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 89448e2167..b40850e769 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -60,6 +60,7 @@ uniform float density_multiplier;  uniform float distance_multiplier;  uniform float max_y;  uniform vec4 glow; +uniform float global_gamma;  uniform float scene_light_strength;  uniform mat3 env_mat;  uniform mat3 ssao_effect_mat; @@ -77,6 +78,34 @@ vec3 vary_AtmosAttenuation;  uniform mat4 inv_proj;  uniform vec2 screen_res; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  vec4 getPosition_d(vec2 pos_screen, float depth)  {  	vec2 sc = pos_screen.xy*2.0; @@ -116,7 +145,6 @@ vec3 getAtmosAttenuation()  	return vary_AtmosAttenuation;  } -  void setPositionEye(vec3 v)  {  	vary_PositionEye = v; @@ -220,9 +248,9 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {  		  + tmpAmbient)));  	//brightness of surface both sunlight and ambient -	setSunlitColor(vec3(sunlight * .5)); -	setAmblitColor(vec3(tmpAmbient * .25)); -	setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +	setSunlitColor(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma); +	setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma); +	setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);  }  vec3 atmosLighting(vec3 light) @@ -237,6 +265,15 @@ vec3 atmosTransport(vec3 light) {  	light += getAdditiveColor() * 2.0;  	return light;  } + +vec3 fullbrightAtmosTransport(vec3 light) { +	float brightness = dot(light.rgb, vec3(0.33333)); + +	return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); +} + + +  vec3 atmosGetDiffuseSunlightColor()  {  	return getSunlitColor(); @@ -271,59 +308,88 @@ vec3 scaleSoftClip(vec3 light)  	return light;  } + +vec3 fullbrightScaleSoftClip(vec3 light) +{ +	//soft clip effect: +	return light; +} +  void main()   {  	vec2 tc = vary_fragcoord.xy;  	float depth = texture2DRect(depthMap, tc.xy).r;  	vec3 pos = getPosition_d(tc, depth).xyz; -	vec3 norm = texture2DRect(normalMap, tc).xyz; -	norm = (norm.xyz-0.5)*2.0; // unpack norm +	vec4 norm = texture2DRect(normalMap, tc); +	float envIntensity = norm.z; +	norm.xyz = decode_normal(norm.xy); // unpack norm  	float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); -	 +  	vec4 diffuse = texture2DRect(diffuseRect, tc);  	vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); -	  	vec3 col;  	float bloom = 0.0; -	if (diffuse.a < 0.9)  	{  		calcAtmospherics(pos.xyz, 1.0);  		col = atmosAmbient(vec3(0)); -		col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a)); +		float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); +		ambient *= 0.5; +		ambient *= ambient; +		ambient = (1.0-ambient); + +		col.rgb *= ambient; + +		col += atmosAffectDirectionalLight(max(min(da, 1.0) * 2.6, 0.0));  		col *= diffuse.rgb; +		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +  		if (spec.a > 0.0) // specular reflection  		{  			// the old infinite-sky shiny reflection  			// -			vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +			  			float sa = dot(refnormpersp, sun_dir.xyz); -			vec3 dumbshiny = vary_SunlitColor*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r); +			vec3 dumbshiny = vary_SunlitColor*(texture2D(lightFunc, vec2(sa, spec.a)).r);  			// add the two types of shiny together  			vec3 spec_contrib = dumbshiny * spec.rgb; -			bloom = dot(spec_contrib, spec_contrib) / 4; +			bloom = dot(spec_contrib, spec_contrib) / 6;  			col += spec_contrib; - -			//add environmentmap +		} +		 +		 +		col = mix(col.rgb, pow(diffuse.rgb, vec3(1.0/2.2)), diffuse.a); +		 +		 +		if (envIntensity > 0.0) +		{ //add environmentmap  			vec3 env_vec = env_mat * refnormpersp; -			col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb,  -				max(spec.a-diffuse.a*2.0, 0.0));  +			 +			float exponent = mix(2.2, 1.0, diffuse.a); +			vec3 refcol = pow(textureCube(environmentMap, env_vec).rgb, vec3(exponent))*exponent; + +			col = mix(col.rgb, refcol,  +				envIntensity);   +  		} -	 -		col = atmosLighting(col); -		col = scaleSoftClip(col); -		col = mix(col.rgb, diffuse.rgb, diffuse.a); -	} -	else -	{ -		col = diffuse.rgb; -	} +		float exponent = mix(1.0, 2.2, diffuse.a); +		col = pow(col, vec3(exponent)); +				 +		if (norm.w < 0.5) +		{ +			col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); +			col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); +		} +		//col = vec3(1,0,1); +		//col.g = envIntensity; +	} +	  	frag_color.rgb = col;  	frag_color.a = bloom; diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl index c6031fc45a..b59fcbe017 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl @@ -35,6 +35,6 @@ void main()  	//transform vertex  	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);  	gl_Position = pos;  -		 +	  	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index cca63872de..3539c8d2b2 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -22,18 +22,15 @@   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ - +#extension GL_ARB_texture_rectangle : enable +  #ifdef DEFINE_GL_FRAGCOLOR  out vec4 frag_color;  #else  #define frag_color gl_FragColor  #endif -//class 1 -- no shadows - -#extension GL_ARB_texture_rectangle : enable -  uniform sampler2DRect diffuseRect;  uniform sampler2DRect specularRect;  uniform sampler2DRect depthMap; @@ -41,6 +38,7 @@ uniform sampler2DRect normalMap;  uniform samplerCube environmentMap;  uniform sampler2D noiseMap;  uniform sampler2D projectionMap; +uniform sampler2D lightFunc;  uniform mat4 proj_mat; //screen space to light space  uniform float proj_near; //near clip for projection @@ -57,20 +55,59 @@ uniform float far_clip;  uniform vec3 proj_origin; //origin of projection to be used for angular attenuation  uniform float sun_wash; +uniform float size;  uniform vec3 color;  uniform float falloff; -uniform float size; -VARYING vec4 vary_fragcoord;  VARYING vec3 trans_center; - +VARYING vec4 vary_fragcoord;  uniform vec2 screen_res;  uniform mat4 inv_proj; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif + +vec4 correctWithGamma(vec4 col) +{ +	return vec4(pow(col.rgb, vec3(2.2)), col.a); +} +  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -86,6 +123,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -103,6 +141,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -142,9 +181,11 @@ void main()  	{  		discard;  	} +	  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -	norm = vec3((norm.xy-0.5)*2.0, norm.z); +	float envIntensity = norm.z; +	norm = decode_normal(norm.xy);  	norm = normalize(norm);  	float l_dist = -dot(lv, proj_n); @@ -159,6 +200,7 @@ void main()  	float fa = falloff+1.0;  	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +	dist_atten = pow(dist_atten, 2.2) * 2.2;  	if (dist_atten <= 0.0)  	{  		discard; @@ -172,31 +214,35 @@ void main()  	vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; +	vec4 spec = texture2DRect(specularRect, frag.xy); + +	 +  	float noise = texture2D(noiseMap, frag.xy/128.0).b; +	vec3 dlit = vec3(0, 0, 0); +	  	if (proj_tc.z > 0.0 &&  		proj_tc.x < 1.0 &&  		proj_tc.y < 1.0 &&  		proj_tc.x > 0.0 &&  		proj_tc.y > 0.0)  	{ -		float lit = 0.0;  		float amb_da = proj_ambiance; +		float lit = 0.0;  		if (da > 0.0)  		{ +			lit = da * dist_atten * noise; +  			float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);  			float lod = diff * proj_lod;  			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); -		 -			vec3 lcol = color.rgb * plcol.rgb * plcol.a; -			 -			lit = da * dist_atten * noise; +			dlit = color.rgb * plcol.rgb * plcol.a; -			col = lcol*lit*diff_tex; -			amb_da += (da*0.5)*proj_ambiance; +			col = dlit*lit*diff_tex; +			//amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;  		} -		  		//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);  		vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); @@ -205,14 +251,41 @@ void main()  		amb_da *= dist_atten * noise;  		amb_da = min(amb_da, 1.0-lit); -			 -		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; +		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a*diff_tex.rgb;  	} -	 -	vec4 spec = texture2DRect(specularRect, frag.xy); +  	if (spec.a > 0.0)  	{ +		dlit *= min(da*6.0, 1.0) * dist_atten; +		vec3 npos = -normalize(pos); + +		//vec3 ref = dot(pos+lv, norm); +		vec3 h = normalize(lv+npos); +		float nh = dot(norm, h); +		float nv = dot(norm, npos); +		float vh = dot(npos, h); +		float sa = nh; +		float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; + +		float gtdenom = 2 * nh; +		float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); +								 +		if (nh > 0.0) +		{ +			 +			float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +			col += dlit*scol*spec.rgb; +			//col += spec.rgb; +		} +	}	 +	 +	 +	 +	 + +	if (envIntensity > 0.0) +	{  		vec3 ref = reflect(normalize(pos), norm);  		//project from point pos in direction ref to plane proj_p, proj_n @@ -229,8 +302,9 @@ void main()  			{  				stc.xy /= stc.w; -				float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); +				//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				if (stc.x < 1.0 && @@ -238,8 +312,7 @@ void main()  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); -					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb; +					col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb;										  				}  			}  		} diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index bac74cbbef..6653f57ee1 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -49,6 +49,40 @@ VARYING vec2 vary_fragcoord;  uniform mat4 inv_proj;  uniform vec2 screen_res; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -123,7 +157,7 @@ void main()  	vec4 pos = getPosition(pos_screen);  	vec3 norm = texture2DRect(normalMap, pos_screen).xyz; -	norm = (norm.xyz-0.5)*2.0; // unpack norm +	norm = decode_normal(norm.xy);  	frag_color[0] = 1.0;  	frag_color[1] = calcAmbientOcclusion(pos, norm); diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index daf1cc7ea2..52a429465f 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -39,6 +39,12 @@ VARYING vec3 vary_normal;  VARYING vec4 vary_texcoord0;  VARYING vec4 vary_texcoord1; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()  {  	/// Note: This should duplicate the blending functionality currently used for the terrain rendering. @@ -56,6 +62,6 @@ void main()  	frag_data[0] = vec4(outColor.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0);  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index da253846ef..808750496f 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -37,6 +37,12 @@ VARYING vec2 vary_texcoord0;  uniform float minimum_alpha; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy); @@ -48,5 +54,5 @@ void main()  	frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0);  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 1ae006bc8a..daa2fb390a 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -67,6 +67,12 @@ VARYING vec4 littleWave;  VARYING vec4 view;  VARYING vec4 vary_position; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec4 color; @@ -161,5 +167,5 @@ void main()  	frag_data[0] = vec4(color.rgb, 0.5); // diffuse  	frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec -	frag_data[2] = vec4(screenspacewavef.xyz*0.5+0.5, screenspacewavef.z*0.5); // normalxyz, displace +	frag_data[2] = vec4(encode_normal(screenspacewavef), 0.0, 0.0); // normalxyz, displace  } diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl index 5aff156eae..352cea7aaa 100755 --- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl @@ -82,7 +82,8 @@ void main()  	pos.w = 1.0;  	pos = modelview_matrix*pos; -	calcAtmospherics(view.xyz); +	calcAtmospherics(pos.xyz); +	  	//pass wave parameters to pixel shader  	vec2 bigWave =  (v.xy) * vec2(0.04,0.04)  + d1 * time * 0.055; diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl new file mode 100644 index 0000000000..947c2b0065 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl @@ -0,0 +1,42 @@ +/**  + * @file highlightV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 texture_matrix0; +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; +ATTRIBUTE vec2 texcoord1; +ATTRIBUTE vec2 texcoord2; + +VARYING vec2 vary_texcoord0; + +void main() +{ +	//transform vertex +	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl new file mode 100644 index 0000000000..c5d102b739 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl @@ -0,0 +1,42 @@ +/**  + * @file highlightV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 texture_matrix0; +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; +ATTRIBUTE vec2 texcoord1; +ATTRIBUTE vec2 texcoord2; + +VARYING vec2 vary_texcoord0; + +void main() +{ +	//transform vertex +	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord2,0,1)).xy; +} + diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl index cf29939cb2..eaaa7b208d 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl @@ -39,13 +39,15 @@ VARYING vec2 vary_texcoord0;  void default_lighting()   { -	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color; +	vec4 color = diffuseLookup(vary_texcoord0.xy);  	if (color.a < minimum_alpha)  	{  		discard;  	} +	color.rgb *= vertex_color.rgb; +  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl index 4070d41f47..b9ddbc8e1c 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl @@ -41,13 +41,15 @@ VARYING vec2 vary_texcoord0;  void default_lighting()   { -	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color; +	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);  	if (color.a < minimum_alpha)  	{  		discard;  	} +	color.rgb *= vertex_color.rgb; +	  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl index 6c34643aab..5740987ab1 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl @@ -30,6 +30,7 @@ out vec4 frag_color;  #endif  uniform float minimum_alpha; +uniform float texture_gamma;  vec3 fullbrightAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light); @@ -39,13 +40,16 @@ VARYING vec2 vary_texcoord0;  void fullbright_lighting()  { -	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color; +	vec4 color = diffuseLookup(vary_texcoord0.xy);  	if (color.a < minimum_alpha)  	{  		discard;  	} +	color.rgb *= vertex_color.rgb; + +	color.rgb = pow(color.rgb, vec3(texture_gamma));  	color.rgb = fullbrightAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl index 2ff7f795b0..c8771a3f1e 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl @@ -32,6 +32,8 @@ out vec4 frag_color;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +uniform float texture_gamma; +  vec3 fullbrightAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light); @@ -39,10 +41,14 @@ void fullbright_lighting()  {  	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color; +	color.rgb = pow(color.rgb, vec3(texture_gamma)); +  	color.rgb = fullbrightAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); +	color.rgb = pow(color.rgb, vec3(1.0/texture_gamma)); +  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl index f4477bd29a..f72f20b03d 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl @@ -30,6 +30,7 @@ out vec4 frag_color;  #endif  uniform float minimum_alpha; +uniform float texture_gamma;  vec3 fullbrightAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light); @@ -41,17 +42,22 @@ VARYING vec2 vary_texcoord0;  void fullbright_lighting()  { -	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color; +	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);  	if (color.a < minimum_alpha)  	{  		discard;  	} +	 +	color.rgb *= vertex_color.rgb; +	color.rgb = pow(color.rgb, vec3(texture_gamma));  	color.rgb = fullbrightAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); +	color.rgb = pow(color.rgb, vec3(1.0/texture_gamma)); +  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl index 777c8b45bb..c8282e9a51 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl @@ -50,7 +50,7 @@ void fullbright_shiny_lighting()  	color.rgb = fullbrightScaleSoftClip(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl index 4fa3b1d939..e7dbd4bbd2 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl @@ -51,7 +51,7 @@ void fullbright_shiny_lighting()  	color.rgb = fullbrightScaleSoftClip(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl index 58984a4263..5886fc65be 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl @@ -48,7 +48,7 @@ void fullbright_shiny_lighting_water()  	color.rgb = fullbrightShinyAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = applyWaterFog(color);  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl index a39b7205d7..cddc7d8df8 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl @@ -49,7 +49,7 @@ void fullbright_shiny_lighting_water()  	color.rgb = fullbrightShinyAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = applyWaterFog(color);  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl index 9c82056fd7..6dd3bb937f 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl @@ -41,7 +41,9 @@ VARYING vec2 vary_texcoord0;  void fullbright_lighting_water()  { -	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color; +	vec4 color = diffuseLookup(vary_texcoord0.xy); + +	color.rgb *= vertex_color.rgb;  	if (color.a < minimum_alpha)  	{ diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl index 52e3b2ad02..9208c148ef 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl @@ -50,7 +50,7 @@ void shiny_lighting()  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl index 474d5ea496..92628faa68 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl @@ -51,7 +51,7 @@ void shiny_lighting()  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl index d2a4c47aac..61841674e2 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl @@ -47,7 +47,7 @@ void shiny_lighting_water()  	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);  	color.rgb = atmosLighting(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = applyWaterFog(color);  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl index f3bd662364..0b6e835fd0 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl @@ -48,7 +48,7 @@ void shiny_lighting_water()  	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);  	color.rgb = atmosLighting(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = applyWaterFog(color);  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl index b68240ba0d..3426fea52f 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl @@ -39,7 +39,9 @@ VARYING vec2 vary_texcoord0;  void default_lighting_water()  { -	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color; +	vec4 color = diffuseLookup(vary_texcoord0.xy); + +	color.rgb *= vertex_color.rgb;  	if (color.a < minimum_alpha)  	{ diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl index da3b20012d..d9faa9b314 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl @@ -41,7 +41,9 @@ VARYING vec2 vary_texcoord0;  void default_lighting_water()  { -	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color; +	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy); + +	color.rgb *= vertex_color.rgb;  	if (color.a < minimum_alpha)  	{ diff --git a/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl index 8494ffba52..9064904191 100755 --- a/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl @@ -48,11 +48,9 @@ void main()  	mat = modelview_matrix * mat;  	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; +	vertex_color = emissive; +  	calcAtmospherics(pos.xyz); -	vertex_color = emissive; -	  	gl_Position = projection_matrix*vec4(pos, 1.0); -		 -	  } diff --git a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl index 44f1aa34a0..449d8d8b4e 100755 --- a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl +++ b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl @@ -25,12 +25,12 @@  uniform mat3 normal_matrix; -ATTRIBUTE vec3 binormal; +ATTRIBUTE vec4 tangent; -VARYING vec4 binormal_out; +VARYING vec4 tangent_out;  void main()  { -	binormal_out = vec4(normal_matrix * binormal, 0.0); +	tangent_out = vec4(normal_matrix * tangent.xyz), tangent.w);  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl deleted file mode 100755 index 12706f130b..0000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ /dev/null @@ -1,164 +0,0 @@ -/**  - * @file alphaF.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#extension GL_ARB_texture_rectangle : enable - -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_color; -#else -#define frag_color gl_FragColor -#endif - -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; - -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -uniform sampler2DShadow shadowMap2; -uniform sampler2DShadow shadowMap3; -uniform sampler2DRect depthMap; - -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; -uniform vec2 screen_res; -uniform vec2 shadow_res; - -vec3 atmosLighting(vec3 light); -vec3 scaleSoftClip(vec3 light); - -VARYING vec3 vary_ambient; -VARYING vec3 vary_directional; -VARYING vec3 vary_fragcoord; -VARYING vec3 vary_position; -VARYING vec3 vary_pointlight_col; - -uniform float shadow_bias; - -uniform mat4 inv_proj; - -float pcfShadow(sampler2DShadow shadowMap, vec4 stc) -{ -	stc.xyz /= stc.w; -	stc.z += shadow_bias; -		 -	stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here -	 -	float cs = shadow2D(shadowMap, stc.xyz).x; -	float shadow = cs; -	 -    shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; -    shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; -    shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; -    shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; -                        -    return shadow*0.2; -} - - -void main()  -{ -	vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; -	frag *= screen_res; -	 -	float shadow = 0.0; -	vec4 pos = vec4(vary_position, 1.0); -	 -	vec4 spos = pos; -		 -	if (spos.z > -shadow_clip.w) -	{	 -		vec4 lpos; -		 -		vec4 near_split = shadow_clip*-0.75; -		vec4 far_split = shadow_clip*-1.25; -		vec4 transition_domain = near_split-far_split; -		float weight = 0.0; - -		if (spos.z < near_split.z) -		{ -			lpos = shadow_matrix[3]*spos; -			 -			float w = 1.0; -			w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; -			shadow += pcfShadow(shadowMap3, lpos)*w; -			weight += w; -			shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); -		} - -		if (spos.z < near_split.y && spos.z > far_split.z) -		{ -			lpos = shadow_matrix[2]*spos; -			 -			float w = 1.0; -			w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; -			w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; -			shadow += pcfShadow(shadowMap2, lpos)*w; -			weight += w; -		} - -		if (spos.z < near_split.x && spos.z > far_split.y) -		{ -			lpos = shadow_matrix[1]*spos; -			 -			float w = 1.0; -			w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; -			w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; -			shadow += pcfShadow(shadowMap1, lpos)*w; -			weight += w; -		} - -		if (spos.z > far_split.x) -		{ -			lpos = shadow_matrix[0]*spos; -							 -			float w = 1.0; -			w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; -				 -			shadow += pcfShadow(shadowMap0, lpos)*w; -			weight += w; -		} -		 - -		shadow /= weight; -	} -	else -	{ -		shadow = 1.0; -	} -	 -	vec4 diff = diffuseLookup(vary_texcoord0.xy); - -	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a); -	vec4 color = diff * col; -	 -	color.rgb = atmosLighting(color.rgb); - -	color.rgb = scaleSoftClip(color.rgb); - -	color.rgb += diff.rgb * vary_pointlight_col.rgb; - -	frag_color = color; -} - diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl index 228dc104ac..9670d59399 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl @@ -52,12 +52,54 @@ VARYING vec3 vary_position;  VARYING vec3 vary_pointlight_col;  VARYING vec2 vary_texcoord0;  VARYING vec4 vertex_color; +VARYING vec3 vary_norm;  uniform vec2 shadow_res;  uniform float shadow_bias;  uniform mat4 inv_proj; +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec3 light_attenuation[8];  +uniform vec3 light_diffuse[8]; + +vec3 calcDirectionalLight(vec3 n, vec3 l) +{ +        float a = pow(max(dot(n,l),0.0), 0.7); +        return vec3(a,a,a); +} + +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ +	//get light vector +	vec3 lv = lp.xyz-v; +	 +	//get distance +	float d = dot(lv,lv); +	 +	float da = 0.0; + +	if (d > 0.0 && la > 0.0 && fa > 0.0) +	{ +		//normalize light vector +		lv = normalize(lv); +	 +		//distance attenuation +		float dist2 = d/la; +		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + +		// spotlight coefficient. +		float spot = max(dot(-ln, lv), is_pointlight); +		da *= spot*spot; // GL_SPOT_EXPONENT=2 + +		//angular attenuation +		da *= max(pow(dot(n, lv), 0.7), 0.0);		 +	} + +	return vec3(da,da,da);	 +} +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).a; @@ -161,17 +203,32 @@ void main()  	{  		shadow = 1.0;  	} - +	vec3 n = vary_norm; +	vec3 l = light_position[0].xyz; +	vec3 dlight = calcDirectionalLight(n, l); +	dlight = dlight * vary_directional.rgb * vary_pointlight_col;  	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); -	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a); +	vec4 col = vec4(vary_ambient + dlight*shadow, vertex_color.a);  	vec4 color = diff * col;  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); +	vec3 light_col = vec3(0,0,0); + +  #define LIGHT_LOOP(i) \ +		light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + +	LIGHT_LOOP(1) +	LIGHT_LOOP(2) +	LIGHT_LOOP(3) +	LIGHT_LOOP(4) +	LIGHT_LOOP(5) +	LIGHT_LOOP(6) +	LIGHT_LOOP(7) -	color.rgb += diff.rgb * vary_pointlight_col.rgb; +	color.rgb += diff.rgb * vary_pointlight_col * light_col;  	frag_color = color;	  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl index c3950a10e1..fae279fba0 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl @@ -53,6 +53,7 @@ VARYING vec3 vary_fragcoord;  VARYING vec3 vary_position;  VARYING vec3 vary_pointlight_col;  VARYING vec2 vary_texcoord0; +VARYING vec3 vary_norm;  uniform vec2 shadow_res; @@ -60,6 +61,47 @@ uniform float shadow_bias;  uniform mat4 inv_proj; +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec3 light_attenuation[8];  +uniform vec3 light_diffuse[8]; + +vec3 calcDirectionalLight(vec3 n, vec3 l) +{ +        float a = pow(max(dot(n,l),0.0), 0.7); +        return vec3(a, a, a); +} + +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ +	//get light vector +	vec3 lv = lp.xyz-v; +	 +	//get distance +	float d = dot(lv,lv); +	 +	float da = 0.0; + +	if (d > 0.0 && la > 0.0 && fa > 0.0) +	{ +		//normalize light vector +		lv = normalize(lv); +	 +		//distance attenuation +		float dist2 = d/la; +		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + +		// spotlight coefficient. +		float spot = max(dot(-ln, lv), is_pointlight); +		da *= spot*spot; // GL_SPOT_EXPONENT=2 + +		//angular attenuation +		da *= max(pow(dot(n, lv), 0.7), 0.0);		 +	} + +	return vec3(da,da,da);	 +} +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).a; @@ -169,15 +211,31 @@ void main()  	{  		shadow = 1.0;  	} +	vec3 n = vary_norm; +	vec3 l = light_position[0].xyz; +	vec3 dlight = calcDirectionalLight(n, l); +	dlight = dlight * vary_directional.rgb * vary_pointlight_col; -	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, 1.0); +	vec4 col = vec4(vary_ambient + dlight*shadow, 1.0);  	vec4 color = diff * col;  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); +	vec3 light_col = vec3(0,0,0); + +  #define LIGHT_LOOP(i) \ +		light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + +	LIGHT_LOOP(1) +	LIGHT_LOOP(2) +	LIGHT_LOOP(3) +	LIGHT_LOOP(4) +	LIGHT_LOOP(5) +	LIGHT_LOOP(6) +	LIGHT_LOOP(7) -	color.rgb += diff.rgb * vary_pointlight_col.rgb; +	color.rgb += diff.rgb * vary_pointlight_col * light_col;  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl index 9629cfe824..7f4d82ecc6 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl @@ -50,7 +50,7 @@ VARYING vec3 vary_pointlight_col;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; - +VARYING vec3 vary_norm;  uniform float near_clip;  uniform float shadow_offset; @@ -115,7 +115,8 @@ void main()  	n.xyz = normalize(n.xyz-pos.xyz);  	vec3 norm = n.xyz; -	 +	vary_norm = norm; +  	float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));  	vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset; diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl index 1586aab0f2..13c6ffc607 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl @@ -25,19 +25,36 @@  uniform mat3 normal_matrix;  uniform mat4 texture_matrix0; +uniform mat4 projection_matrix;  uniform mat4 modelview_matrix;  uniform mat4 modelview_projection_matrix;  ATTRIBUTE vec3 position; + +#ifdef USE_INDEXED_TEX  void passTextureIndex(); +#endif +  ATTRIBUTE vec3 normal; + +#ifdef USE_VERTEX_COLOR  ATTRIBUTE vec4 diffuse_color; +#endif +  ATTRIBUTE vec2 texcoord0; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +#else +#ifdef IS_AVATAR_SKIN +mat4 getSkinnedTransform(); +#endif +#endif +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye); -float calcDirectionalLight(vec3 n, vec3 l); +vec3 calcDirectionalLight(vec3 n, vec3 l);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -50,9 +67,12 @@ VARYING vec3 vary_fragcoord;  VARYING vec3 vary_position;  VARYING vec3 vary_pointlight_col; +#ifdef USE_VERTEX_COLOR  VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; +#endif +VARYING vec2 vary_texcoord0; +VARYING vec3 vary_norm;  uniform float near_clip;  uniform float shadow_offset; @@ -63,13 +83,15 @@ uniform vec3 light_direction[8];  uniform vec3 light_attenuation[8];   uniform vec3 light_diffuse[8]; -float calcDirectionalLight(vec3 n, vec3 l) +uniform vec3 sun_dir; + +vec3 calcDirectionalLight(vec3 n, vec3 l)  {          float a = max(dot(n,l),0.0); -        return a; +        return vec3(a,a,a);  } -float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)  {  	//get light vector  	vec3 lv = lp.xyz-v; @@ -96,55 +118,107 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  		da *= max(dot(n, lv), 0.0);		  	} -	return da;	 +	return vec3(da,da,da);	  }  void main()  { +	vec4 pos; +	vec3 norm; +	  	//transform vertex +#ifdef HAS_SKIN +	mat4 trans = getObjectSkinnedTransform(); +	trans = modelview_matrix * trans; +	 +	pos = trans * vec4(position.xyz, 1.0); +	 +	norm = position.xyz + normal.xyz; +	norm = normalize((trans * vec4(norm, 1.0)).xyz - pos.xyz); +	vec4 frag_pos = projection_matrix * pos; +	gl_Position = frag_pos; +#else + +#ifdef IS_AVATAR_SKIN +	mat4 trans = getSkinnedTransform(); +	vec4 pos_in = vec4(position.xyz, 1.0); +	pos.x = dot(trans[0], pos_in); +	pos.y = dot(trans[1], pos_in); +	pos.z = dot(trans[2], pos_in); +	pos.w = 1.0; +	 +	norm.x = dot(trans[0].xyz, normal); +	norm.y = dot(trans[1].xyz, normal); +	norm.z = dot(trans[2].xyz, normal); +	norm = normalize(norm); +	 +	vec4 frag_pos = projection_matrix * pos; +	gl_Position = frag_pos; +#else +	norm = normalize(normal_matrix * normal);  	vec4 vert = vec4(position.xyz, 1.0); -	passTextureIndex(); -	vec4 pos = (modelview_matrix * vert); +	pos = (modelview_matrix * vert);  	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +#endif +#endif + +#ifdef USE_INDEXED_TEX +	passTextureIndex();  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -		 -	vec3 norm = normalize(normal_matrix * normal); +#else +	vary_texcoord0 = texcoord0; +#endif +	vary_norm = norm;  	float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));  	vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset; -		 +	  	calcAtmospherics(pos.xyz); +#ifndef USE_VERTEX_COLOR +	vec4 diffuse_color = vec4(1,1,1,1); +#endif +  	//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));  	vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a); -	 -	// Collect normal lights -	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z); -	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z); -	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z); -	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z); -	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z); -	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z); +	vec3 dff = pow(diffuse_color.rgb, vec3(2.2f,2.2f,2.2f)); -	vary_pointlight_col = col.rgb*diffuse_color.rgb; +	vary_pointlight_col = dff;  	col.rgb = vec3(0,0,0);  	// Add windlight lights -	col.rgb = atmosAmbient(vec3(0.)); +	col.rgb = atmosAmbient(col.rgb); -	vary_ambient = col.rgb*diffuse_color.rgb; -	vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a))); +	float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); +	ambient *= 0.5; +	ambient *= ambient; +	ambient = (1.0-ambient); + +	col.rgb *= ambient; + +	vary_directional.rgb = atmosAffectDirectionalLight(1.0f); +	vary_ambient = col.rgb*dff; -	col.rgb = col.rgb*diffuse_color.rgb; +	col.rgb = col.rgb*dff; +#ifdef USE_VERTEX_COLOR  	vertex_color = col; - -	 +#endif +#ifdef HAS_SKIN +	vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip); +#else + +#ifdef IS_AVATAR_SKIN +	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); +#else  	pos = modelview_projection_matrix * vert;  	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); -	 +#endif + +#endif +  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index 5621e47ab7..eaacb93cb9 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -39,6 +39,7 @@ uniform samplerCube environmentMap;  uniform sampler2DRect lightMap;  uniform sampler2D noiseMap;  uniform sampler2D projectionMap; +uniform sampler2D lightFunc;  uniform mat4 proj_mat; //screen space to light space  uniform float proj_near; //near clip for projection @@ -67,10 +68,51 @@ uniform vec2 screen_res;  uniform mat4 inv_proj; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif + +vec4 correctWithGamma(vec4 col) +{ +	return vec4(pow(col.rgb, vec3(2.2)), col.a); +} + +  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	 +	ret = correctWithGamma(ret); +  	vec2 dist = tc-vec2(0.5);  	float det = max(1.0-lod/(proj_lod*0.5), 0.0); @@ -85,7 +127,8 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	 +	ret = correctWithGamma(ret); +  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));  	float det = min(lod/(proj_lod*0.5), 1.0); @@ -102,7 +145,8 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	 +	ret = correctWithGamma(ret); +  	vec2 dist = tc-vec2(0.5);  	float d = dot(dist,dist); @@ -154,7 +198,10 @@ void main()  	}  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -	norm = (norm.xyz-0.5)*2.0; // unpack norm +	 +	float envIntensity = norm.z; + +	norm = decode_normal(norm.xy);  	norm = normalize(norm);  	float l_dist = -dot(lv, proj_n); @@ -169,6 +216,7 @@ void main()  	float fa = falloff+1.0;  	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +	dist_atten = pow(dist_atten, 2.2) * 2.2;  	if (dist_atten <= 0.0)  	{  		discard; @@ -177,11 +225,15 @@ void main()  	lv = proj_origin-pos.xyz;  	lv = normalize(lv);  	float da = dot(norm, lv); -		 +  	vec3 col = vec3(0,0,0);  	vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; -		 +	 +	vec4 spec = texture2DRect(specularRect, frag.xy); + +	vec3 dlit = vec3(0, 0, 0); +  	float noise = texture2D(noiseMap, frag.xy/128.0).b;  	if (proj_tc.z > 0.0 &&  		proj_tc.x < 1.0 && @@ -189,21 +241,21 @@ void main()  		proj_tc.x > 0.0 &&  		proj_tc.y > 0.0)  	{ -		float lit = 0.0;  		float amb_da = proj_ambiance; -		 +		float lit = 0.0; +  		if (da > 0.0)  		{ +			lit = da * dist_atten * noise; +  			float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);  			float lod = diff * proj_lod;  			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); -			vec3 lcol = color.rgb * plcol.rgb * plcol.a; +			dlit = color.rgb * plcol.rgb * plcol.a; -			lit = da * dist_atten * noise; -			 -			col = lcol*lit*diff_tex*shadow; +			col = dlit*lit*diff_tex*shadow;  			amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;  		} @@ -219,10 +271,37 @@ void main()  		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;  	} -	 -	vec4 spec = texture2DRect(specularRect, frag.xy); +  	if (spec.a > 0.0)  	{ +		vec3 npos = -normalize(pos); +		dlit *= min(da*6.0, 1.0) * dist_atten; + +		//vec3 ref = dot(pos+lv, norm); +		vec3 h = normalize(lv+npos); +		float nh = dot(norm, h); +		float nv = dot(norm, npos); +		float vh = dot(npos, h); +		float sa = nh; +		float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; + +		float gtdenom = 2 * nh; +		float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); +								 +		if (nh > 0.0) +		{ +			float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +			col += dlit*scol*spec.rgb*shadow; +			//col += spec.rgb; +		} +	}	 +	 +	 +	 +	 + +	if (envIntensity > 0.0) +	{  		vec3 ref = reflect(normalize(pos), norm);  		//project from point pos in direction ref to plane proj_p, proj_n @@ -239,8 +318,9 @@ void main()  			{  				stc.xy /= stc.w; -				float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); +				//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				if (stc.x < 1.0 && @@ -248,8 +328,7 @@ void main()  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); -					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow; +					col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb;										  				}  			}  		} diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 9df9d75905..4fe2f1551e 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -38,7 +38,6 @@ uniform sampler2DRect lightMap;  uniform sampler2DRect depthMap;  uniform samplerCube environmentMap;  uniform sampler2D	  lightFunc; -uniform vec3 gi_quad;  uniform float blur_size;  uniform float blur_fidelity; @@ -60,16 +59,13 @@ uniform float density_multiplier;  uniform float distance_multiplier;  uniform float max_y;  uniform vec4 glow; +uniform float global_gamma;  uniform float scene_light_strength;  uniform mat3 env_mat;  uniform vec4 shadow_clip;  uniform mat3 ssao_effect_mat; -uniform mat4 inv_proj; -uniform vec2 screen_res; -  uniform vec3 sun_dir; -  VARYING vec2 vary_fragcoord;  vec3 vary_PositionEye; @@ -79,6 +75,43 @@ vec3 vary_AmblitColor;  vec3 vary_AdditiveColor;  vec3 vary_AtmosAttenuation; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  vec4 getPosition_d(vec2 pos_screen, float depth)  {  	vec2 sc = pos_screen.xy*2.0; @@ -118,7 +151,6 @@ vec3 getAtmosAttenuation()  	return vary_AtmosAttenuation;  } -  void setPositionEye(vec3 v)  {  	vary_PositionEye = v; @@ -222,9 +254,9 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {  		  + tmpAmbient)));  	//brightness of surface both sunlight and ambient -	setSunlitColor(vec3(sunlight * .5)); -	setAmblitColor(vec3(tmpAmbient * .25)); -	setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +	setSunlitColor(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma); +	setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma); +	setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);  }  vec3 atmosLighting(vec3 light) @@ -239,6 +271,15 @@ vec3 atmosTransport(vec3 light) {  	light += getAdditiveColor() * 2.0;  	return light;  } + +vec3 fullbrightAtmosTransport(vec3 light) { +	float brightness = dot(light.rgb, vec3(0.33333)); + +	return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); +} + + +  vec3 atmosGetDiffuseSunlightColor()  {  	return getSunlitColor(); @@ -273,22 +314,28 @@ vec3 scaleSoftClip(vec3 light)  	return light;  } + +vec3 fullbrightScaleSoftClip(vec3 light) +{ +	//soft clip effect: +	return light; +} +  void main()   {  	vec2 tc = vary_fragcoord.xy;  	float depth = texture2DRect(depthMap, tc.xy).r;  	vec3 pos = getPosition_d(tc, depth).xyz; -	vec3 norm = texture2DRect(normalMap, tc).xyz; -	norm = (norm.xyz-0.5)*2.0; // unpack norm +	vec4 norm = texture2DRect(normalMap, tc); +	float envIntensity = norm.z; +	norm.xyz = decode_normal(norm.xy); // unpack norm  	float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); -	 -	vec4 diffuse = texture2DRect(diffuseRect, tc); +	vec4 diffuse = texture2DRect(diffuseRect, tc); +	  	vec3 col;  	float bloom = 0.0; - -	if (diffuse.a < 0.9)  	{  		vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); @@ -299,39 +346,62 @@ void main()  		calcAtmospherics(pos.xyz, ambocc);  		col = atmosAmbient(vec3(0)); -		col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)); +		float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); +		ambient *= 0.5; +		ambient *= ambient; +		ambient = (1.0-ambient); + +		col.rgb *= ambient; + +		col += atmosAffectDirectionalLight(max(min(da, scol) * 2.6, 0.0));  		col *= diffuse.rgb; +		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +  		if (spec.a > 0.0) // specular reflection  		{  			// the old infinite-sky shiny reflection  			// -			vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +			  			float sa = dot(refnormpersp, sun_dir.xyz); -			vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r); - +			vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(texture2D(lightFunc, vec2(sa, spec.a)).r); +			  			// add the two types of shiny together  			vec3 spec_contrib = dumbshiny * spec.rgb; -			bloom = dot(spec_contrib, spec_contrib) / 4; +			bloom = dot(spec_contrib, spec_contrib) / 6;  			col += spec_contrib; - -			//add environmentmap -			vec3 env_vec = env_mat * refnormpersp; -			col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb,  -				max(spec.a-diffuse.a*2.0, 0.0));   		} +	 +		 +		col = mix(col.rgb, pow(diffuse.rgb, vec3(1.0/2.2)), diffuse.a); +		 +		 +		if (envIntensity > 0.0) +		{ //add environmentmap +			vec3 env_vec = env_mat * refnormpersp; -		col = atmosLighting(col); -		col = scaleSoftClip(col); +			float exponent = mix(2.2, 1.0, diffuse.a); +			vec3 refcol = pow(textureCube(environmentMap, env_vec).rgb, vec3(exponent))*exponent; -		col = mix(col, diffuse.rgb, diffuse.a); -	} -	else -	{ -		col = diffuse.rgb; +			col = mix(col.rgb, refcol,  +				envIntensity);   + +		} + +		float exponent = mix(1.0, 2.2, diffuse.a); +		col = pow(col, vec3(exponent)); +				 +		if (norm.w < 0.5) +		{ +			col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); +			col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); +		} + +		//col = vec3(1,0,1); +		//col.g = envIntensity;  	} -		 +	  	frag_color.rgb = col;  	frag_color.a = bloom;  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index 6d6ad6d565..bdb713d682 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -39,6 +39,7 @@ uniform samplerCube environmentMap;  uniform sampler2DRect lightMap;  uniform sampler2D noiseMap;  uniform sampler2D projectionMap; +uniform sampler2D lightFunc;  uniform mat4 proj_mat; //screen space to light space  uniform float proj_near; //near clip for projection @@ -67,9 +68,49 @@ uniform vec2 screen_res;  uniform mat4 inv_proj; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif + +vec4 correctWithGamma(vec4 col) +{ +	return vec4(pow(col.rgb, vec3(2.2)), col.a); +} +  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -85,6 +126,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -102,6 +144,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -154,7 +197,8 @@ void main()  	}  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -	norm = (norm.xyz-0.5)*2.0; // unpack norm +	float envIntensity = norm.z; +	norm = decode_normal(norm.xy);  	norm = normalize(norm);  	float l_dist = -dot(lv, proj_n); @@ -169,6 +213,7 @@ void main()  	float fa = falloff+1.0;  	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +	dist_atten = pow(dist_atten, 2.2) * 2.2;  	if (dist_atten <= 0.0)  	{  		discard; @@ -182,6 +227,10 @@ void main()  	vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; +	vec4 spec = texture2DRect(specularRect, frag.xy); + +	vec3 dlit = vec3(0, 0, 0); +  	float noise = texture2D(noiseMap, frag.xy/128.0).b;  	if (proj_tc.z > 0.0 &&  		proj_tc.x < 1.0 && @@ -189,21 +238,21 @@ void main()  		proj_tc.x > 0.0 &&  		proj_tc.y > 0.0)  	{ -		float lit = 0.0;  		float amb_da = proj_ambiance; +		float lit = 0.0;  		if (da > 0.0)  		{ +			lit = da * dist_atten * noise; +  			float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);  			float lod = diff * proj_lod;  			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); -			vec3 lcol = color.rgb * plcol.rgb * plcol.a; -			 -			lit = da * dist_atten * noise; +			dlit = color.rgb * plcol.rgb * plcol.a; -			col = lcol*lit*diff_tex*shadow; +			col = dlit*lit*diff_tex*shadow;  			amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;  		} @@ -219,10 +268,37 @@ void main()  		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;  	} -	 -	vec4 spec = texture2DRect(specularRect, frag.xy); +  	if (spec.a > 0.0)  	{ +		dlit *= min(da*6.0, 1.0) * dist_atten; +		vec3 npos = -normalize(pos); + +		//vec3 ref = dot(pos+lv, norm); +		vec3 h = normalize(lv+npos); +		float nh = dot(norm, h); +		float nv = dot(norm, npos); +		float vh = dot(npos, h); +		float sa = nh; +		float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; + +		float gtdenom = 2 * nh; +		float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); +								 +		if (nh > 0.0) +		{ +			float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +			col += dlit*scol*spec.rgb*shadow; +			//col += spec.rgb; +		} +	}	 +	 +	 +	 +	 + +	if (envIntensity > 0.0) +	{  		vec3 ref = reflect(normalize(pos), norm);  		//project from point pos in direction ref to plane proj_p, proj_n @@ -239,8 +315,9 @@ void main()  			{  				stc.xy /= stc.w; -				float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); +				//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				if (stc.x < 1.0 && @@ -248,8 +325,7 @@ void main()  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); -					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow; +					col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb;										  				}  			}  		} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index 890486c4b1..7b09dd29dd 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -65,6 +65,40 @@ uniform float shadow_offset;  uniform float spot_shadow_bias;  uniform float spot_shadow_offset; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -125,11 +159,9 @@ void main()  	vec4 pos = getPosition(pos_screen); -	vec4 nmap4 = texture2DRect(normalMap, pos_screen); -	nmap4 = vec4((nmap4.xyz-0.5)*2.0,nmap4.w); // unpack norm -	float displace = nmap4.w; -	vec3 norm = nmap4.xyz; -	 +	vec3 norm = texture2DRect(normalMap, pos_screen).xyz; +	norm = decode_normal(norm.xy); // unpack norm +		  	/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL  	{  		frag_color = vec4(0.0); // doesn't matter @@ -138,8 +170,8 @@ void main()  	float shadow = 0.0;  	float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz)); - -	vec3 shadow_pos = pos.xyz + displace*norm; +	 +	vec3 shadow_pos = pos.xyz;  	vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);  	vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 2dcd3d656f..01e34ed792 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -66,6 +66,40 @@ uniform float shadow_offset;  uniform float spot_shadow_bias;  uniform float spot_shadow_offset; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -186,11 +220,9 @@ void main()  	vec4 pos = getPosition(pos_screen); -	vec4 nmap4 = texture2DRect(normalMap, pos_screen); -	nmap4 = vec4((nmap4.xyz-0.5)*2.0,nmap4.w); // unpack norm -	float displace = nmap4.w; -	vec3 norm = nmap4.xyz; -	 +	vec3 norm = texture2DRect(normalMap, pos_screen).xyz; +	norm = decode_normal(norm.xy); // unpack norm +		  	/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL  	{  		frag_color = vec4(0.0); // doesn't matter @@ -199,8 +231,8 @@ void main()  	float shadow = 0.0;  	float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz)); - -	vec3 shadow_pos = pos.xyz + displace*norm; +	 +	vec3 shadow_pos = pos.xyz;  	vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);  	vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0); diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl index da3d922017..8fd06c7e2f 100755 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl @@ -54,6 +54,7 @@ uniform float density_multiplier;  uniform float distance_multiplier;  uniform float max_y;  uniform vec4 glow; +uniform float global_gamma;  void calcAtmospherics(vec3 inPositionEye) { @@ -129,11 +130,11 @@ void calcAtmospherics(vec3 inPositionEye) {  		vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)  	  + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x  		  + tmpAmbient))); - +	  	//brightness of surface both sunlight and ambient -	setSunlitColor(vec3(sunlight * .5)); -	setAmblitColor(vec3(tmpAmbient * .25)); -	setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +	setSunlitColor(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma); +	setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma); +	setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);  	// vary_SunlitColor = vec3(0);  	// vary_AmblitColor = vec3(0); diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 284e9c44b2..e5b385f4aa 100755 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -1084,8 +1084,7 @@           scale="0 0 .5" />        </param_skeleton>      </param> - -    <param +                          <param       id="11001"       group="0"       name="Hover" @@ -12308,7 +12307,7 @@ render_pass="bump">  	 <param_driver />      </param> -    <param +  <param       id="11000"       group="0"       name="AppearanceMessage_Version" diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt index 4c39014c8b..c64e11929d 100755 --- a/indra/newview/gpu_table.txt +++ b/indra/newview/gpu_table.txt @@ -32,20 +32,20 @@  //		1 - We claim to support this card.  // -3Dfx									.*3Dfx.*								0	0	0	0 -3Dlabs									.*3Dlabs.*								0	0	0	0 -ATI 3D-Analyze							.*ATI.*3D-Analyze.*						0	0	0	0 -ATI All-in-Wonder 7500					.*ATI.*All-in-Wonder 75.*				0	1	0	0 -ATI All-in-Wonder 8500					.*ATI.*All-in-Wonder 85.*				0	1	0	0 -ATI All-in-Wonder 9200					.*ATI.*All-in-Wonder 92.*				0	1	0	0 +3Dfx									.*3Dfx.*											0	0	0	0 +3Dlabs									.*3Dlabs.*											0	0	0	0 +ATI 3D-Analyze							.*ATI.*3D-Analyze.*									0	0	0	0 +ATI All-in-Wonder 7500					.*ATI.*All-in-Wonder 75.*							0	1	0	0 +ATI All-in-Wonder 8500					.*ATI.*All-in-Wonder 85.*							0	1	0	0 +ATI All-in-Wonder 9200					.*ATI.*All-in-Wonder 92.*							0	1	0	0  ATI All-in-Wonder 9xxx					.*ATI.*All-in-Wonder 9.*				1	1	0	0 -ATI All-in-Wonder HD					.*ATI.*All-in-Wonder HD.*				1	1	1	3.3 -ATI All-in-Wonder X600					.*ATI.*All-in-Wonder X6.*				1	1	0	0 -ATI All-in-Wonder X800					.*ATI.*All-in-Wonder X8.*				1	1	1	2.1 -ATI All-in-Wonder X1800					.*ATI.*All-in-Wonder X18.*				3	1	0	0 -ATI All-in-Wonder X1900					.*ATI.*All-in-Wonder X19.*				3	1	0	0 -ATI All-in-Wonder PCI-E					.*ATI.*All-in-Wonder.*PCI-E.*			1	1	0	0 -ATI All-in-Wonder Radeon				.*ATI.*All-in-Wonder Radeon.*			0	1	0	0 +ATI All-in-Wonder HD					.*ATI.*All-in-Wonder HD.*							1	1	1	3.3 +ATI All-in-Wonder X600					.*ATI.*All-in-Wonder X6.*							1	1	0	0 +ATI All-in-Wonder X800					.*ATI.*All-in-Wonder X8.*							1	1	1	2.1 +ATI All-in-Wonder X1800					.*ATI.*All-in-Wonder X18.*							3	1	0	0 +ATI All-in-Wonder X1900					.*ATI.*All-in-Wonder X19.*							3	1	0	0 +ATI All-in-Wonder PCI-E					.*ATI.*All-in-Wonder.*PCI-E.*						1	1	0	0 +ATI All-in-Wonder Radeon				.*ATI.*All-in-Wonder Radeon.*						0	1	0	0  ATI ASUS ARES							.*ATI.*ASUS.*ARES.*						3	1	0	0  ATI ASUS A9xxx							.*ATI.*ASUS.*A9.*						1	1	0	0  ATI ASUS AH24xx							.*ATI.*ASUS.*AH24.*						1	1	1	3.3 @@ -79,30 +79,30 @@ ATI ASUS Radeon X1xxx					.*ATI.*ASUS.*X1.*						2	1	1	2.1  ATI Radeon X7xx							.*ATI.*ASUS.*X7.*						1	1	0	0  ATI Radeon X19xx						.*ATI.*(Radeon|Diamond) X19.* ?.*		2	1	1	2.1  ATI Radeon X18xx						.*ATI.*(Radeon|Diamond) X18.* ?.*		3	1	1	2.1 -ATI Radeon X17xx						.*ATI.*(Radeon|Diamond) X17.* ?.*		1	1	1	2.1 +ATI Radeon X17xx						.*ATI.*(Radeon|Diamond) X17.* ?.*					1	1	1	2.1  ATI Radeon X16xx						.*ATI.*(Radeon|Diamond) X16.* ?.*		1	1	1	2.1  ATI Radeon X15xx						.*ATI.*(Radeon|Diamond) X15.* ?.*		1	1	1	2.1  ATI Radeon X13xx						.*ATI.*(Radeon|Diamond) X13.* ?.*		1	1	1	2.1  ATI Radeon X1xxx						.*ATI.*(Radeon|Diamond) X1.. ?.*		0	1	1	2.1  ATI Radeon X2xxx						.*ATI.*(Radeon|Diamond) X2.. ?.*		1	1	1	2.1 -ATI Display Adapter						.*ATI.*display adapter.*				1	1	1	4.1 -ATI FireGL 5200							.*ATI.*FireGL V52.*						1	1	1	2.1 -ATI FireGL 5xxx							.*ATI.*FireGL V5.*						2	1	1	3.3 -ATI FireGL								.*ATI.*Fire.*GL.*						4	1	1	4.2 +ATI Display Adapter						.*ATI.*display adapter.*							1	1	1	4.1 +ATI FireGL 5200							.*ATI.*FireGL V52.*									1	1	1	2.1 +ATI FireGL 5xxx							.*ATI.*FireGL V5.*									2	1	1	3.3 +ATI FireGL								.*ATI.*Fire.*GL.*									4	1	1	4.2  ATI FirePro M3900						.*ATI.*FirePro.*M39.*					2	1	0	0 -ATI FirePro M5800						.*ATI.*FirePro.*M58.*					3	1	0	0 -ATI FirePro M7740						.*ATI.*FirePro.*M77.*					3	1	0	0 -ATI FirePro M7820						.*ATI.*FirePro.*M78.*					5	1	1	4.2 +ATI FirePro M5800						.*ATI.*FirePro.*M58.*								3	1	0	0 +ATI FirePro M7740						.*ATI.*FirePro.*M77.*								3	1	0	0 +ATI FirePro M7820						.*ATI.*FirePro.*M78.*								5	1	1	4.2  ATI FireMV								.*ATI.*FireMV.*							0	1	1	1.3 -ATI Generic								.*ATI.*Generic.*						0	0	0	0 -ATI Hercules 9800						.*ATI.*Hercules.*9800.*					1	1	0	0 +ATI Generic								.*ATI.*Generic.*									0	0	0	0 +ATI Hercules 9800						.*ATI.*Hercules.* 9800.*							1	1	0	0  ATI IGP 340M							.*ATI.*IGP.*340M.*						0	0	0	0 -ATI M52									.*ATI.*M52.*							1	1	0	0 -ATI M54									.*ATI.*M54.*							1	1	0	0 -ATI M56									.*ATI.*M56.*							1	1	0	0 -ATI M71									.*ATI.*M71.*							1	1	0	0 -ATI M72									.*ATI.*M72.*							1	1	0	0 -ATI M76									.*ATI.*M76.*							3	1	0	0 +ATI M52									.*ATI.*M52.*										1	1	0	0 +ATI M54									.*ATI.*M54.*										1	1	0	0 +ATI M56									.*ATI.*M56.*										1	1	0	0 +ATI M71									.*ATI.*M71.*										1	1	0	0 +ATI M72									.*ATI.*M72.*										1	1	0	0 +ATI M76									.*ATI.*M76.*										3	1	0	0  ATI Radeon HD 64xx						.*ATI.*AMD Radeon.* HD [67]4..[MG]		2	1	1	4.2  ATI Radeon HD 65xx						.*ATI.*AMD Radeon.* HD [67]5..[MG]		2	1	1	4.2  ATI Radeon HD 66xx						.*ATI.*AMD Radeon.* HD [67]6..[MG]		3	1	1	4.2 @@ -124,12 +124,12 @@ ATI ASUS HD7600							.*ATI.*ASUS.* HD76.*					3	1	0	0  ATI ASUS HD7700							.*ATI.*ASUS.* HD77.*					4	1	1	4.2  ATI ASUS HD7800							.*ATI.*ASUS.* HD78.*					5	1	1	4.2  ATI ASUS HD7900							.*ATI.*ASUS.* HD79.*					5	1	1	4.2 -ATI Mobility Radeon 4100				.*ATI.*Mobility.*41..					1	1	1	3.3 -ATI Mobility Radeon 7xxx				.*ATI.*Mobility.*Radeon 7.*				0	1	1	1.3 -ATI Mobility Radeon 8xxx				.*ATI.*Mobility.*Radeon 8.*				0	1	0	0 -ATI Mobility Radeon 9800				.*ATI.*Mobility.*98.*					1	1	0	0 -ATI Mobility Radeon 9700				.*ATI.*Mobility.*97.*					0	1	1	2.1 -ATI Mobility Radeon 9600				.*ATI.*Mobility.*96.*					1	1	1	2.1 +ATI Mobility Radeon 4100				.*ATI.*Mobility.* 41..								1	1	1	3.3 +ATI Mobility Radeon 7xxx				.*ATI.*Mobility.*Radeon 7.*							0	1	1	1.3 +ATI Mobility Radeon 8xxx				.*ATI.*Mobility.*Radeon 8.*							0	1	0	0 +ATI Mobility Radeon 9800				.*ATI.*Mobility.* 98.*								1	1	0	0 +ATI Mobility Radeon 9700				.*ATI.*Mobility.* 97.*								0	1	1	2.1 +ATI Mobility Radeon 9600				.*ATI.*Mobility.* 96.*								1	1	1	2.1  ATI Mobility Radeon HD 530v				.*ATI.*Mobility.*HD *530v.*				1	1	1	3.3  ATI Mobility Radeon HD 540v				.*ATI.*Mobility.*HD *540v.*				1	1	1	3.3  ATI Mobility Radeon HD 545v				.*ATI.*Mobility.*HD *545v.*				2	1	1	4 @@ -176,7 +176,7 @@ ATI Radeon HD 3400						.*ATI.*Radeon HD *34..					1	1	1	4  ATI Radeon HD 3500						.*ATI.*Radeon HD *35..					2	1	0	0  ATI Radeon HD 3600						.*ATI.*Radeon HD *36..					3	1	1	3.3  ATI Radeon HD 3700						.*ATI.*Radeon HD *37..					3	1	0	0 -ATI HD3700								.*ATI.* HD37..							3	1	0	3.3 +ATI HD3700								.*ATI.* HD37..										3	1	0	3.3  ATI Radeon HD 3800						.*ATI.*Radeon HD *38..					3	1	1	4  ATI Radeon HD 4100						.*ATI.*Radeon HD *41..					1	1	0	0  ATI Radeon HD 4200						.*ATI.*Radeon HD *42..					1	1	1	4 @@ -202,128 +202,128 @@ ATI Radeon HD 6600						.*ATI.*Radeon HD *66..					3	1	1	4.2  ATI Radeon HD 6700						.*ATI.*Radeon HD *67..					3	1	1	4.2  ATI Radeon HD 6800						.*ATI.*Radeon HD *68..					4	1	1	4.2  ATI Radeon HD 6900						.*ATI.*Radeon HD *69..					5	1	1	4.2 -ATI Radeon OpenGL						.*ATI.*Radeon OpenGL.*					0	0	0	0 -ATI Radeon 2100							.*ATI.*Radeon 21..						0	1	1	2.1 -ATI Radeon 3000							.*ATI.*Radeon 30..						1	1	1	4 -ATI Radeon 3100							.*ATI.*Radeon 31..						0	1	1	3.3 -ATI Radeon 5xxx							.*ATI.*Radeon 5...						3	1	0	0 -ATI Radeon 7xxx							.*ATI.*Radeon 7...						0	1	1	2 -ATI Radeon 8xxx							.*ATI.*Radeon 8...						0	1	0	0 -ATI Radeon 9000							.*ATI.*Radeon 90..						0	1	1	1.3 -ATI Radeon 9100							.*ATI.*Radeon 91..						0	1	0	0 -ATI Radeon 9200							.*ATI.*Radeon 92..						0	1	1	1.3 -ATI Radeon 9500							.*ATI.*Radeon 95..						0	1	1	2.1 -ATI Radeon 9600							.*ATI.*Radeon 96..						0	1	1	2.1 -ATI Radeon 9700							.*ATI.*Radeon 97..						1	1	0	0 -ATI Radeon 9800							.*ATI.*Radeon 98..						1	1	1	2.1 -ATI Radeon RV250						.*ATI.*RV250.*							0	1	0	0 -ATI Radeon RV600						.*ATI.*RV6.*							1	1	0	0 -ATI Radeon RX700						.*ATI.*RX70.*							1	1	0	0 +ATI Radeon OpenGL						.*ATI.*Radeon OpenGL.*								0	0	0	0 +ATI Radeon 2100							.*ATI.*Radeon 21..									0	1	1	2.1 +ATI Radeon 3000							.*ATI.*Radeon 30..									1	1	1	4 +ATI Radeon 3100							.*ATI.*Radeon 31..									0	1	1	3.3 +ATI Radeon 5xxx							.*ATI.*Radeon 5...									3	1	0	0 +ATI Radeon 7xxx							.*ATI.*Radeon 7...									0	1	1	2 +ATI Radeon 8xxx							.*ATI.*Radeon 8...									0	1	0	0 +ATI Radeon 9000							.*ATI.*Radeon 90..									0	1	1	1.3 +ATI Radeon 9100							.*ATI.*Radeon 91..									0	1	0	0 +ATI Radeon 9200							.*ATI.*Radeon 92..									0	1	1	1.3 +ATI Radeon 9500							.*ATI.*Radeon 95..									0	1	1	2.1 +ATI Radeon 9600							.*ATI.*Radeon 96..									0	1	1	2.1 +ATI Radeon 9700							.*ATI.*Radeon 97..									1	1	0	0 +ATI Radeon 9800							.*ATI.*Radeon 98..									1	1	1	2.1 +ATI Radeon RV250						.*ATI.*RV250.*										0	1	0	0 +ATI Radeon RV600						.*ATI.*RV6.*										1	1	0	0 +ATI Radeon RX700						.*ATI.*RX70.*										1	1	0	0  ATI Radeon RX800						.*ATI.*Radeon *RX80.*					2	1	0	0 -ATI RS880M								.*ATI.*RS880M							1	1	0	0 -ATI Radeon RX9550						.*ATI.*RX9550.*							1	1	0	0 -ATI Radeon VE							.*ATI.*Radeon.*VE.*						0	0	0	0 +ATI RS880M								.*ATI.*RS880M										1	1	0	0 +ATI Radeon RX9550						.*ATI.*RX9550.*										1	1	0	0 +ATI Radeon VE							.*ATI.*Radeon.*VE.*									0	0	0	0  ATI Radeon X300							.*ATI.*Radeon *X3.*						1	1	1	2.1 -ATI Radeon X400							.*ATI.*Radeon ?X4.*						0	1	0	0 -ATI Radeon X500							.*ATI.*Radeon ?X5.*						1	1	1	2.1 +ATI Radeon X400							.*ATI.*Radeon ?X4.*									0	1	0	0 +ATI Radeon X500							.*ATI.*Radeon ?X5.*									1	1	1	2.1  ATI Radeon X600							.*ATI.*Radeon ?X6.*						1	1	1	2.1 -ATI Radeon X700							.*ATI.*Radeon ?X7.*						2	1	1	2.1 -ATI Radeon X800							.*ATI.*Radeon ?X8.*						1	1	1	2.1 -ATI Radeon X900							.*ATI.*Radeon ?X9.*						2	1	0	0 -ATI Radeon Xpress						.*ATI.*Radeon Xpress.*					0	1	1	2.1 -ATI Rage 128							.*ATI.*Rage 128.*						0	1	0	0 -ATI R300 (9700)							.*R300.*								0	1	1	2.1 -ATI R350 (9800)							.*R350.*								1	1	0	0 -ATI R580 (X1900)						.*R580.*								3	1	0	0 -ATI RC410 (Xpress 200)					.*RC410.*								0	0	0	0 -ATI RS48x (Xpress 200x)					.*RS48.*								0	0	0	0 -ATI RS600 (Xpress 3200)					.*RS600.*								0	0	0	0 -ATI RV350 (9600)						.*RV350.*								0	1	0	0 -ATI RV370 (X300)						.*RV370.*								0	1	0	0 -ATI RV410 (X700)						.*RV410.*								1	1	0	0 -ATI RV515								.*RV515.*								1	1	0	0 -ATI RV570 (X1900 GT/PRO)				.*RV570.*								3	1	0	0 -ATI RV380								.*RV380.*								0	1	0	0 -ATI RV530								.*RV530.*								1	1	0	0 -ATI RX480 (Xpress 200P)					.*RX480.*								0	1	0	0 -ATI RX700								.*RX700.*								1	1	0	0 -AMD ANTILLES (HD 6990)					.*(AMD|ATI).*Antilles.*					3	1	0	0 -AMD BARTS (HD 6800)						.*(AMD|ATI).*Barts.*					3	1	1	2.1 -AMD CAICOS (HD 6400)					.*(AMD|ATI).*Caicos.*					3	1	0	0 -AMD CAYMAN (HD 6900)					.*(AMD|ATI).*(Cayman|CAYMAM).*			3	1	0	0 +ATI Radeon X700							.*ATI.*Radeon ?X7.*									2	1	1	2.1 +ATI Radeon X800							.*ATI.*Radeon ?X8.*									1	1	1	2.1 +ATI Radeon X900							.*ATI.*Radeon ?X9.*									2	1	0	0 +ATI Radeon Xpress						.*ATI.*Radeon Xpress.*								0	1	1	2.1 +ATI Rage 128							.*ATI.*Rage 128.*									0	1	0	0 +ATI R300 (9700)							.*R300.*											0	1	1	2.1 +ATI R350 (9800)							.*R350.*											1	1	0	0 +ATI R580 (X1900)						.*R580.*											3	1	0	0 +ATI RC410 (Xpress 200)					.*RC410.*											0	0	0	0 +ATI RS48x (Xpress 200x)					.*RS48.*											0	0	0	0 +ATI RS600 (Xpress 3200)					.*RS600.*											0	0	0	0 +ATI RV350 (9600)						.*RV350.*											0	1	0	0 +ATI RV370 (X300)						.*RV370.*											0	1	0	0 +ATI RV410 (X700)						.*RV410.*											1	1	0	0 +ATI RV515								.*RV515.*											1	1	0	0 +ATI RV570 (X1900 GT/PRO)				.*RV570.*											3	1	0	0 +ATI RV380								.*RV380.*											0	1	0	0 +ATI RV530								.*RV530.*											1	1	0	0 +ATI RX480 (Xpress 200P)					.*RX480.*											0	1	0	0 +ATI RX700								.*RX700.*											1	1	0	0 +AMD ANTILLES (HD 6990)					.*(AMD|ATI).*Antilles.*								3	1	0	0 +AMD BARTS (HD 6800)						.*(AMD|ATI).*Barts.*								3	1	1	2.1 +AMD CAICOS (HD 6400)					.*(AMD|ATI).*Caicos.*								3	1	0	0 +AMD CAYMAN (HD 6900)					.*(AMD|ATI).*(Cayman|CAYMAM).*						3	1	0	0  AMD CEDAR (HD 5450)						.*(AMD|ATI).*Cedar.*					2	1	0	0 -AMD CYPRESS (HD 5800)					.*(AMD|ATI).*Cypress.*					3	1	0	0 -AMD HEMLOCK (HD 5970)					.*(AMD|ATI).*Hemlock.*					3	1	0	0 -AMD JUNIPER (HD 5700)					.*(AMD|ATI).*Juniper.*					3	1	0	0 -AMD PARK								.*(AMD|ATI).*Park.*						3	1	0	0 +AMD CYPRESS (HD 5800)					.*(AMD|ATI).*Cypress.*								3	1	0	0 +AMD HEMLOCK (HD 5970)					.*(AMD|ATI).*Hemlock.*								3	1	0	0 +AMD JUNIPER (HD 5700)					.*(AMD|ATI).*Juniper.*								3	1	0	0 +AMD PARK								.*(AMD|ATI).*Park.*									3	1	0	0  AMD REDWOOD (HD 5500/5600)				.*(AMD|ATI).*Redwood.*					3	1	0	0  AMD TURKS (HD 6500/6600)				.*(AMD|ATI).*Turks.*					3	1	0	0 -AMD RS780 (HD 3200)						.*RS780.*								0	1	1	2.1 -AMD RS880 (HD 4200)						.*RS880.*								0	1	1	3.2 -AMD RV610 (HD 2400)						.*RV610.*								1	1	0	0 -AMD RV620 (HD 3400)						.*RV620.*								1	1	0	0 -AMD RV630 (HD 2600)						.*RV630.*								2	1	0	0 +AMD RS780 (HD 3200)						.*RS780.*											0	1	1	2.1 +AMD RS880 (HD 4200)						.*RS880.*											0	1	1	3.2 +AMD RV610 (HD 2400)						.*RV610.*											1	1	0	0 +AMD RV620 (HD 3400)						.*RV620.*											1	1	0	0 +AMD RV630 (HD 2600)						.*RV630.*											2	1	0	0  AMD RV635 (HD 3600)						.*RV635.*								3	1	0	0 -AMD RV670 (HD 3800)						.*RV670.*								3	1	0	0 -AMD R680 (HD 3870 X2)					.*R680.*								3	1	0	0 -AMD R700 (HD 4800 X2)					.*R700.*								3	1	0	0 -AMD RV710 (HD 4300)						.*RV710.*								0	1	1	1.4 +AMD RV670 (HD 3800)						.*RV670.*											3	1	0	0 +AMD R680 (HD 3870 X2)					.*R680.*											3	1	0	0 +AMD R700 (HD 4800 X2)					.*R700.*											3	1	0	0 +AMD RV710 (HD 4300)						.*RV710.*											0	1	1	1.4  AMD RV730 (HD 4600)						.*RV730.*								3	1	0	0 -AMD RV740 (HD 4700)						.*RV740.*								3	1	0	0 -AMD RV770 (HD 4800)						.*RV770.*								3	1	0	0 -AMD RV790 (HD 4800)						.*RV790.*								3	1	0	0 -ATI 760G/Radeon 3000					.*ATI.*AMD 760G.*						1	1	1	3.3 -ATI 780L/Radeon 3000					.*ATI.*AMD 780L.*						1	1	0	0 -ATI Radeon DDR							.*ATI.*Radeon ?DDR.*					0	1	0	0 +AMD RV740 (HD 4700)						.*RV740.*											3	1	0	0 +AMD RV770 (HD 4800)						.*RV770.*											3	1	0	0 +AMD RV790 (HD 4800)						.*RV790.*											3	1	0	0 +ATI 760G/Radeon 3000					.*ATI.*AMD 760G.*									1	1	1	3.3 +ATI 780L/Radeon 3000					.*ATI.*AMD 780L.*									1	1	0	0 +ATI Radeon DDR							.*ATI.*Radeon ?DDR.*								0	1	0	0  ATI FirePro 2000						.*ATI.*FirePro 2.*						2	1	1	4.1 -ATI FirePro 3000						.*ATI.*FirePro V3.*						2	1	0	0 +ATI FirePro 3000						.*ATI.*FirePro V3.*									2	1	0	0  ATI FirePro 4000						.*ATI.*FirePro V4.*						2	1	0	0 -ATI FirePro 5000						.*ATI.*FirePro V5.*						3	1	0	0 -ATI FirePro 7000						.*ATI.*FirePro V7.*						3	1	0	0 -ATI FirePro M							.*ATI.*FirePro M.*						3	1	1	4.2 -ATI R300 (9700)							.*R300.*								0	1	1	2.1 +ATI FirePro 5000						.*ATI.*FirePro V5.*									3	1	0	0 +ATI FirePro 7000						.*ATI.*FirePro V7.*									3	1	0	0 +ATI FirePro M							.*ATI.*FirePro M.*									3	1	1	4.2 +ATI R300 (9700)							.*R300.*											0	1	1	2.1  ATI Radeon								.*ATI.*(Diamond|Radeon).*				0	1	0	4.2 -Intel X3100								.*Intel.*X3100.*						1	1	1	2.1 -Intel GMA 3600							.*Intel.* 3600.*						0	1	1	3 -Intel 830M								.*Intel.*830M							0	0	0	0 -Intel 845G								.*Intel.*845G							0	0	1	1.4 -Intel 855GM								.*Intel.*855GM							0	0	1	1.4 -Intel 865G								.*Intel.*865G							0	0	1	1.4 -Intel 900								.*Intel.*900.*900						0	0	0	0 -Intel 915GM								.*Intel.*915GM							0	0	1	1.4 -Intel 915G								.*Intel.*915G							0	0	1	1.4 -Intel 945GM								.*Intel.*945GM.*						0	1	1	1.4 -Intel 945G								.*Intel.*945G.*							0	1	1	1.4 -Intel 950								.*Intel.*950.*							0	1	1	1.4 -Intel 965								.*Intel.*965.*							0	1	1	2.1 -Intel G33								.*Intel.*G33.*							1	0	1	1.4 -Intel G41								.*Intel.*G41.*							1	1	1	2.1 -Intel G45								.*Intel.*G45.*							1	1	1	2.1 -Intel Bear Lake							.*Intel.*Bear Lake.*					1	0	1	1.4 -Intel Broadwater						.*Intel.*Broadwater.*					0	0	1	1.4 -Intel Brookdale							.*Intel.*Brookdale.*					0	0	1	1.3 -Intel Cantiga							.*Intel.*Cantiga.*						0	0	1	2 -Intel Eaglelake							.*Intel.*Eaglelake.*					1	1	1	2 -Intel Graphics Media HD					.*Intel.*Graphics Media.*HD.*			1	1	1	2.1 -Intel HD Graphics 2000					.*Intel.*HD Graphics 2.*				2	1	0	4 -Intel HD Graphics 3000					.*Intel.*HD Graphics 3.*				3	1	1	3.1 -Intel HD Graphics 4000					.*Intel.*HD Graphics 4.*				3	1	1	4 +Intel X3100								.*Intel.*X3100.*									1	1	1	2.1 +Intel GMA 3600							.*Intel.* 3600.*									0	1	1	3 +Intel 830M								.*Intel.*830M										0	0	0	0 +Intel 845G								.*Intel.*845G										0	0	1	1.4 +Intel 855GM								.*Intel.*855GM										0	0	1	1.4 +Intel 865G								.*Intel.*865G										0	0	1	1.4 +Intel 900								.*Intel.*900.*900									0	0	0	0 +Intel 915GM								.*Intel.*915GM										0	0	1	1.4 +Intel 915G								.*Intel.*915G										0	0	1	1.4 +Intel 945GM								.*Intel.*945GM.*									0	1	1	1.4 +Intel 945G								.*Intel.*945G.*										0	1	1	1.4 +Intel 950								.*Intel.*950.*										0	1	1	1.4 +Intel 965								.*Intel.*965.*										0	1	1	2.1 +Intel G33								.*Intel.*G33.*										1	0	1	1.4 +Intel G41								.*Intel.*G41.*										1	1	1	2.1 +Intel G45								.*Intel.*G45.*										1	1	1	2.1 +Intel Bear Lake							.*Intel.*Bear Lake.*								1	0	1	1.4 +Intel Broadwater						.*Intel.*Broadwater.*								0	0	1	1.4 +Intel Brookdale							.*Intel.*Brookdale.*								0	0	1	1.3 +Intel Cantiga							.*Intel.*Cantiga.*									0	0	1	2 +Intel Eaglelake							.*Intel.*Eaglelake.*								1	1	1	2 +Intel Graphics Media HD					.*Intel.*Graphics Media.*HD.*						1	1	1	2.1 +Intel HD Graphics 2000					.*Intel.*HD Graphics 2.*							2	1	0	4 +Intel HD Graphics 3000					.*Intel.*HD Graphics 3.*							3	1	1	3.1 +Intel HD Graphics 4000					.*Intel.*HD Graphics 4.*							3	1	1	4  Intel HD2000							.*Intel.*HD2000.*						2	1	0	0  Intel HD3000							.*Intel.*HD3000.*						3	1	0	0 -Intel HD Graphics						.*Intel.*HD Graphics.*					2	1	1	4 -Intel Mobile 4 Series					.*Intel.*Mobile.* 4 Series.*			0	1	1	2.1 -Intel 4 Series Internal					.*Intel.* 4 Series Internal.*			1	1	1	2.1 -Intel Media Graphics HD					.*Intel.*Media Graphics HD.*			0	1	0	0 -Intel Montara							.*Intel.*Montara.*						0	0	1	1.3 -Intel Pineview							.*Intel.*Pineview.*						0	1	1	1.4 -Intel Springdale						.*Intel.*Springdale.*					0	0	1	1.3 -Intel Grantsdale						.*Intel.*Grantsdale.*					1	1	0	0 -Intel Q45/Q43							.*Intel.*Q4.*							1	1	1	2.1 -Intel B45/B43							.*Intel.*B4.*							1	1	1	2.1 -Intel 3D-Analyze						.*Intel.*3D-Analyze.*					2	1	0	0 -Matrox									.*Matrox.*								0	0	0	0 +Intel HD Graphics						.*Intel.*HD Graphics.*								2	1	1	4 +Intel Mobile 4 Series					.*Intel.*Mobile.* 4 Series.*						0	1	1	2.1 +Intel 4 Series Internal					.*Intel.* 4 Series Internal.*						1	1	1	2.1 +Intel Media Graphics HD					.*Intel.*Media Graphics HD.*						0	1	0	0 +Intel Montara							.*Intel.*Montara.*									0	0	1	1.3 +Intel Pineview							.*Intel.*Pineview.*									0	1	1	1.4 +Intel Springdale						.*Intel.*Springdale.*								0	0	1	1.3 +Intel Grantsdale						.*Intel.*Grantsdale.*								1	1	0	0 +Intel Q45/Q43							.*Intel.*Q4.*										1	1	1	2.1 +Intel B45/B43							.*Intel.*B4.*										1	1	1	2.1 +Intel 3D-Analyze						.*Intel.*3D-Analyze.*								2	1	0	0 +Matrox									.*Matrox.*											0	0	0	0  Mesa									.*Mesa.*								1	0	1	2.1 -Gallium									.*Gallium.*								1	1	1	2.1 +Gallium									.*Gallium.*											1	1	1	2.1  NVIDIA G100M							.*NVIDIA .*100M.*						4	1	1	3.3  NVIDIA G102M							.*NVIDIA .*102M.*						1	1	1	3.3  NVIDIA G103M							.*NVIDIA .*103M.*						2	1	1	3.3 @@ -380,14 +380,14 @@ NVIDIA GTX 660M							.*NVIDIA .*GTX *66*M.*					5	1	0	0  NVIDIA GTX 670M							.*NVIDIA .*GTX *67*M.*					5	1	1	4.2  NVIDIA GTX 680M							.*NVIDIA .*GTX *68*M.*					5	1	0	0  NVIDIA GTX 690M							.*NVIDIA .*GTX *69*M.*					5	1	0	0 -NVIDIA G100								.*NVIDIA .*G10.*						3	1	1	4.2 +NVIDIA G100								.*NVIDIA .*G10.*									3	1	1	4.2  NVIDIA GT 120							.*NVIDIA .*GT *12.*						2	1	0	3  NVIDIA GT 130							.*NVIDIA .*GT *13.*						2	1	0	3.3  NVIDIA GTS 150							.*NVIDIA .*GTS *15.*					2	1	0	0 -NVIDIA 200								.*NVIDIA .*GeForce 20.*					2	1	1	3.3 -NVIDIA G200								.*NVIDIA .*GeForce G20.*				2	1	1	3.3 -NVIDIA G210								.*NVIDIA .*GeForce G210.*				3	1	1	3.3 -NVIDIA 210								.*NVIDIA .*GeForce 210.*				3	1	1	3.3 +NVIDIA 200								.*NVIDIA .*GeForce 20.*								2	1	1	3.3 +NVIDIA G200								.*NVIDIA .*GeForce G20.*							2	1	1	3.3 +NVIDIA G210								.*NVIDIA .*GeForce G210.*							3	1	1	3.3 +NVIDIA 210								.*NVIDIA .*GeForce 210.*							3	1	1	3.3  NVIDIA GT 220							.*NVIDIA .*GT *22.*						2	1	1	3.3  NVIDIA GT 230							.*NVIDIA .*GT *23.*						2	1	1	3.3  NVIDIA GT 240							.*NVIDIA .*GT *24.*						4	1	1	3.3 @@ -397,12 +397,12 @@ NVIDIA GTX 260							.*NVIDIA .*GTX *26.*					4	1	1	3.3  NVIDIA GTX 270							.*NVIDIA .*GTX *27.*					4	1	0	3.3  NVIDIA GTX 280							.*NVIDIA .*GTX *28.*					4	1	1	3.3  NVIDIA GTX 290							.*NVIDIA .*GTX *29.*					5	1	0	3.3 -NVIDIA 310								.*NVIDIA .*GeForce 310.*				3	1	1	3.3 -NVIDIA 315								.*NVIDIA .*GeForce 315.*				3	1	1	3.3 +NVIDIA 310								.*NVIDIA .*GeForce 310.*							3	1	1	3.3 +NVIDIA 315								.*NVIDIA .*GeForce 315.*							3	1	1	3.3  NVIDIA GT 320							.*NVIDIA .*GT *32.*						3	1	0	3.3  NVIDIA GT 330							.*NVIDIA .*GT *33.*						3	1	0	3.3  NVIDIA GT 340							.*NVIDIA .*GT *34.*						3	1	0	0 -NVIDIA 405								.*NVIDIA .* 405.*						3	1	0	3.3 +NVIDIA 405								.*NVIDIA .* 405.*									3	1	0	3.3  NVIDIA GT 420							.*NVIDIA .*GT *42.*						3	1	1	4.2  NVIDIA GT 430							.*NVIDIA .*GT *43.*						3	1	1	4.2  NVIDIA GT 440							.*NVIDIA .*GT *44.*						4	1	0	4.2 @@ -429,125 +429,125 @@ NVIDIA GTX 660							.*NVIDIA .*GTX *66.*					5	1	0	4.3  NVIDIA GTX 670							.*NVIDIA .*GTX *67.*					5	1	1	4.2  NVIDIA GTX 680							.*NVIDIA .*GTX *68.*					5	1	1	4.2  NVIDIA GTX 690							.*NVIDIA .*GTX *69.*					5	1	1	4.2 -NVIDIA C51								.*NVIDIA .*C51.*						0	1	1	2 -NVIDIA G72								.*NVIDIA .*G72.*						1	1	0	0 -NVIDIA G73								.*NVIDIA .*G73.*						1	1	0	0 -NVIDIA G84								.*NVIDIA .*G84.*						2	1	0	0 -NVIDIA G86								.*NVIDIA .*G86.*						3	1	0	0 -NVIDIA G92								.*NVIDIA .*G92.*						3	1	0	0 -NVIDIA GeForce							.*GeForce 256.*							0	0	0	0 -NVIDIA GeForce 2						.*GeForce ?2 ?.*						0	1	1	1.5 +NVIDIA C51								.*NVIDIA .*C51.*									0	1	1	2 +NVIDIA G72								.*NVIDIA .*G72.*									1	1	0	0 +NVIDIA G73								.*NVIDIA .*G73.*									1	1	0	0 +NVIDIA G84								.*NVIDIA .*G84.*									2	1	0	0 +NVIDIA G86								.*NVIDIA .*G86.*									3	1	0	0 +NVIDIA G92								.*NVIDIA .*G92.*									3	1	0	0 +NVIDIA GeForce							.*GeForce 256.*										0	0	0	0 +NVIDIA GeForce 2						.*GeForce ?2 ?.*									0	1	1	1.5  NVIDIA GeForce 3						.*GeForce ?3 ?.*						2	1	1	2.1  NVIDIA GeForce 3 Ti						.*GeForce ?3 Ti.*						0	1	0	0 -NVIDIA GeForce 4						.*NVIDIA .*GeForce ?4.*					0	1	1	1.5 +NVIDIA GeForce 4						.*NVIDIA .*GeForce ?4.*								0	1	1	1.5  NVIDIA GeForce 4 Go						.*NVIDIA .*GeForce ?4.*Go.*				0	1	0	0  NVIDIA GeForce 4 MX						.*NVIDIA .*GeForce ?4 MX.*				0	1	0	0  NVIDIA GeForce 4 PCX					.*NVIDIA .*GeForce ?4 PCX.*				0	1	0	0  NVIDIA GeForce 4 Ti						.*NVIDIA .*GeForce ?4 Ti.*				0	1	0	0 -NVIDIA GeForce 6100						.*NVIDIA .*GeForce 61.*					3	1	1	4.2 -NVIDIA GeForce 6200						.*NVIDIA .*GeForce 62.*					0	1	1	2.1 -NVIDIA GeForce 6500						.*NVIDIA .*GeForce 65.*					1	1	1	2.1 -NVIDIA GeForce 6600						.*NVIDIA .*GeForce 66.*					2	1	1	2.1 -NVIDIA GeForce 6700						.*NVIDIA .*GeForce 67.*					2	1	1	2.1 -NVIDIA GeForce 6800						.*NVIDIA .*GeForce 68.*					1	1	1	2.1 -NVIDIA GeForce 7000						.*NVIDIA .*GeForce 70.*					1	1	1	2.1 -NVIDIA GeForce 7100						.*NVIDIA .*GeForce 71.*					1	1	1	2.1 -NVIDIA GeForce 7200						.*NVIDIA .*GeForce 72.*					1	1	0	0 -NVIDIA GeForce 7300						.*NVIDIA .*GeForce 73.*					1	1	1	2.1 -NVIDIA GeForce 7500						.*NVIDIA .*GeForce 75.*					2	1	1	2.1 -NVIDIA GeForce 7600						.*NVIDIA .*GeForce 76.*					2	1	1	2.1 -NVIDIA GeForce 7800						.*NVIDIA .*GeForce 78.*					2	1	1	2.1 -NVIDIA GeForce 7900						.*NVIDIA .*GeForce 79.*					3	1	1	2.1 +NVIDIA GeForce 6100						.*NVIDIA .*GeForce 61.*								3	1	1	4.2 +NVIDIA GeForce 6200						.*NVIDIA .*GeForce 62.*								0	1	1	2.1 +NVIDIA GeForce 6500						.*NVIDIA .*GeForce 65.*								1	1	1	2.1 +NVIDIA GeForce 6600						.*NVIDIA .*GeForce 66.*								2	1	1	2.1 +NVIDIA GeForce 6700						.*NVIDIA .*GeForce 67.*								2	1	1	2.1 +NVIDIA GeForce 6800						.*NVIDIA .*GeForce 68.*								1	1	1	2.1 +NVIDIA GeForce 7000						.*NVIDIA .*GeForce 70.*								1	1	1	2.1 +NVIDIA GeForce 7100						.*NVIDIA .*GeForce 71.*								1	1	1	2.1 +NVIDIA GeForce 7200						.*NVIDIA .*GeForce 72.*								1	1	0	0 +NVIDIA GeForce 7300						.*NVIDIA .*GeForce 73.*								1	1	1	2.1 +NVIDIA GeForce 7500						.*NVIDIA .*GeForce 75.*								2	1	1	2.1 +NVIDIA GeForce 7600						.*NVIDIA .*GeForce 76.*								2	1	1	2.1 +NVIDIA GeForce 7800						.*NVIDIA .*GeForce 78.*								2	1	1	2.1 +NVIDIA GeForce 7900						.*NVIDIA .*GeForce 79.*								3	1	1	2.1  NVIDIA GeForce 8100						.*NVIDIA .*GeForce 81.*					1	1	0	0  NVIDIA GeForce 8200M					.*NVIDIA .*GeForce 8200M.*				1	1	0	3.3  NVIDIA GeForce 8200						.*NVIDIA .*GeForce 82.*					1	1	0	2.1 -NVIDIA GeForce 8300						.*NVIDIA .*GeForce 83.*					3	1	1	3.3 +NVIDIA GeForce 8300						.*NVIDIA .*GeForce 83.*								3	1	1	3.3  NVIDIA GeForce 8400M					.*NVIDIA .*GeForce 8400M.*				1	1	1	3.3 -NVIDIA GeForce 8400						.*NVIDIA .*GeForce 84.*					2	1	1	3.3 -NVIDIA GeForce 8500						.*NVIDIA .*GeForce 85.*					2	1	1	3.3 +NVIDIA GeForce 8400						.*NVIDIA .*GeForce 84.*								2	1	1	3.3 +NVIDIA GeForce 8500						.*NVIDIA .*GeForce 85.*								2	1	1	3.3  NVIDIA GeForce 8600M					.*NVIDIA .*GeForce 8600M.*				2	1	1	3.3 -NVIDIA GeForce 8600						.*NVIDIA .*GeForce 86.*					3	1	1	3.3 +NVIDIA GeForce 8600						.*NVIDIA .*GeForce 86.*								3	1	1	3.3  NVIDIA GeForce 8700M					.*NVIDIA .*GeForce 8700M.*				2	1	1	3.3 -NVIDIA GeForce 8700						.*NVIDIA .*GeForce 87.*					3	1	0	0 +NVIDIA GeForce 8700						.*NVIDIA .*GeForce 87.*								3	1	0	0  NVIDIA GeForce 8800M					.*NVIDIA .*GeForce 8800M.*				2	1	1	3.3 -NVIDIA GeForce 8800						.*NVIDIA .*GeForce 88.*					3	1	1	3.3 +NVIDIA GeForce 8800						.*NVIDIA .*GeForce 88.*								3	1	1	3.3  NVIDIA GeForce 9100M					.*NVIDIA .*GeForce 9100M.*				0	1	0	0 -NVIDIA GeForce 9100						.*NVIDIA .*GeForce 91.*					0	1	0	3.3 +NVIDIA GeForce 9100						.*NVIDIA .*GeForce 91.*								0	1	0	3.3  NVIDIA GeForce 9200M					.*NVIDIA .*GeForce 9200M.*				1	1	0	3.1 -NVIDIA GeForce 9200						.*NVIDIA .*GeForce 92.*					1	1	0	3.3 +NVIDIA GeForce 9200						.*NVIDIA .*GeForce 92.*								1	1	0	3.3  NVIDIA GeForce 9300M					.*NVIDIA .*GeForce 9300M.*				1	1	1	3.3 -NVIDIA GeForce 9300						.*NVIDIA .*GeForce 93.*					1	1	1	3.3 +NVIDIA GeForce 9300						.*NVIDIA .*GeForce 93.*								1	1	1	3.3  NVIDIA GeForce 9400M					.*NVIDIA .*GeForce 9400M.*				2	1	1	3.3 -NVIDIA GeForce 9400						.*NVIDIA .*GeForce 94.*					3	1	1	3.3 +NVIDIA GeForce 9400						.*NVIDIA .*GeForce 94.*								3	1	1	3.3  NVIDIA GeForce 9500M					.*NVIDIA .*GeForce 9500M.*				1	1	1	3.3 -NVIDIA GeForce 9500						.*NVIDIA .*GeForce 95.*					3	1	1	3.3 +NVIDIA GeForce 9500						.*NVIDIA .*GeForce 95.*								3	1	1	3.3  NVIDIA GeForce 9600M					.*NVIDIA .*GeForce 9600M.*				2	1	1	3.3 -NVIDIA GeForce 9600						.*NVIDIA .*GeForce 96.*					3	1	1	3.3 +NVIDIA GeForce 9600						.*NVIDIA .*GeForce 96.*								3	1	1	3.3  NVIDIA GeForce 9700M					.*NVIDIA .*GeForce 9700M.*				0	1	1	3.3  NVIDIA GeForce 9800M					.*NVIDIA .*GeForce 9800M.*				2	1	1	3.3 -NVIDIA GeForce 9800						.*NVIDIA .*GeForce 98.*					3	1	1	3.3 -NVIDIA GeForce FX 5100					.*NVIDIA .*GeForce FX 51.*				0	1	0	0 -NVIDIA GeForce FX 5200					.*NVIDIA .*GeForce FX 52.*				0	1	0	2.1 -NVIDIA GeForce FX 5300					.*NVIDIA .*GeForce FX 53.*				0	1	0	0 -NVIDIA GeForce FX 5500					.*NVIDIA .*GeForce FX 55.*				0	1	1	2.1 -NVIDIA GeForce FX 5600					.*NVIDIA .*GeForce FX 56.*				1	1	1	2.1 -NVIDIA GeForce FX 5700					.*NVIDIA .*GeForce FX 57.*				0	1	1	2.1 -NVIDIA GeForce FX 5800					.*NVIDIA .*GeForce FX 58.*				1	1	0	0 -NVIDIA GeForce FX 5900					.*NVIDIA .*GeForce FX 59.*				1	1	1	2.1 -NVIDIA GeForce FX Go5100				.*NVIDIA .*GeForce FX Go51.*			0	1	0	0 +NVIDIA GeForce 9800						.*NVIDIA .*GeForce 98.*								3	1	1	3.3 +NVIDIA GeForce FX 5100					.*NVIDIA .*GeForce FX 51.*							0	1	0	0 +NVIDIA GeForce FX 5200					.*NVIDIA .*GeForce FX 52.*							0	1	0	2.1 +NVIDIA GeForce FX 5300					.*NVIDIA .*GeForce FX 53.*							0	1	0	0 +NVIDIA GeForce FX 5500					.*NVIDIA .*GeForce FX 55.*							0	1	1	2.1 +NVIDIA GeForce FX 5600					.*NVIDIA .*GeForce FX 56.*							1	1	1	2.1 +NVIDIA GeForce FX 5700					.*NVIDIA .*GeForce FX 57.*							0	1	1	2.1 +NVIDIA GeForce FX 5800					.*NVIDIA .*GeForce FX 58.*							1	1	0	0 +NVIDIA GeForce FX 5900					.*NVIDIA .*GeForce FX 59.*							1	1	1	2.1 +NVIDIA GeForce FX Go5100				.*NVIDIA .*GeForce FX Go51.*						0	1	0	0  NVIDIA GeForce FX Go5200				.*NVIDIA .*GeForce FX Go52.*			0	1	0	0 -NVIDIA GeForce FX Go5300				.*NVIDIA .*GeForce FX Go53.*			0	1	0	0 -NVIDIA GeForce FX Go5500				.*NVIDIA .*GeForce FX Go55.*			0	1	0	0 -NVIDIA GeForce FX Go5600				.*NVIDIA .*GeForce FX Go56.*			0	1	1	2.1 -NVIDIA GeForce FX Go5700				.*NVIDIA .*GeForce FX Go57.*			1	1	1	1.5 -NVIDIA GeForce FX Go5800				.*NVIDIA .*GeForce FX Go58.*			1	1	0	0 -NVIDIA GeForce FX Go5900				.*NVIDIA .*GeForce FX Go59.*			1	1	0	0 -NVIDIA GeForce FX Go5xxx				.*NVIDIA .*GeForce FX Go.*				0	1	0	0 -NVIDIA GeForce Go 6100					.*NVIDIA .*GeForce Go 61.*				0	1	1	2.1 +NVIDIA GeForce FX Go5300				.*NVIDIA .*GeForce FX Go53.*						0	1	0	0 +NVIDIA GeForce FX Go5500				.*NVIDIA .*GeForce FX Go55.*						0	1	0	0 +NVIDIA GeForce FX Go5600				.*NVIDIA .*GeForce FX Go56.*						0	1	1	2.1 +NVIDIA GeForce FX Go5700				.*NVIDIA .*GeForce FX Go57.*						1	1	1	1.5 +NVIDIA GeForce FX Go5800				.*NVIDIA .*GeForce FX Go58.*						1	1	0	0 +NVIDIA GeForce FX Go5900				.*NVIDIA .*GeForce FX Go59.*						1	1	0	0 +NVIDIA GeForce FX Go5xxx				.*NVIDIA .*GeForce FX Go.*							0	1	0	0 +NVIDIA GeForce Go 6100					.*NVIDIA .*GeForce Go 61.*							0	1	1	2.1  NVIDIA GeForce Go 6200					.*NVIDIA .*GeForce Go 62.*				0	1	0	0  NVIDIA GeForce Go 6400					.*NVIDIA .*GeForce Go 64.*				1	1	1	2 -NVIDIA GeForce Go 6500					.*NVIDIA .*GeForce Go 65.*				1	1	0	0 -NVIDIA GeForce Go 6600					.*NVIDIA .*GeForce Go 66.*				0	1	1	2.1 -NVIDIA GeForce Go 6700					.*NVIDIA .*GeForce Go 67.*				1	1	0	0 -NVIDIA GeForce Go 6800					.*NVIDIA .*GeForce Go 68.*				0	1	1	2.1 +NVIDIA GeForce Go 6500					.*NVIDIA .*GeForce Go 65.*							1	1	0	0 +NVIDIA GeForce Go 6600					.*NVIDIA .*GeForce Go 66.*							0	1	1	2.1 +NVIDIA GeForce Go 6700					.*NVIDIA .*GeForce Go 67.*							1	1	0	0 +NVIDIA GeForce Go 6800					.*NVIDIA .*GeForce Go 68.*							0	1	1	2.1  NVIDIA GeForce Go 7200					.*NVIDIA .*GeForce Go 72.*				1	1	0	0 -NVIDIA GeForce Go 7300 LE				.*NVIDIA .*GeForce Go 73.*LE.*			1	1	0	0 -NVIDIA GeForce Go 7300					.*NVIDIA .*GeForce Go 73.*				1	1	1	2.1 -NVIDIA GeForce Go 7400					.*NVIDIA .*GeForce Go 74.*				1	1	1	2.1 -NVIDIA GeForce Go 7600					.*NVIDIA .*GeForce Go 76.*				1	1	1	2.1 -NVIDIA GeForce Go 7700					.*NVIDIA .*GeForce Go 77.*				0	1	1	2.1 -NVIDIA GeForce Go 7800					.*NVIDIA .*GeForce Go 78.*				2	1	0	0 -NVIDIA GeForce Go 7900					.*NVIDIA .*GeForce Go 79.*				1	1	1	2.1 -NVIDIA D9M								.*NVIDIA .*D9M.*						1	1	0	0 -NVIDIA G94								.*NVIDIA .*G94.*						3	1	0	0 -NVIDIA GeForce Go 6						.*GeForce Go 6.*						1	1	0	0 -NVIDIA ION 2							.*NVIDIA .*ION 2.*						2	1	0	0 -NVIDIA ION 								.*NVIDIA Corporation.*ION.*				2	1	1	3.3 -NVIDIA NB8M								.*NVIDIA .*NB8M.*						1	1	0	0 -NVIDIA NB8P								.*NVIDIA .*NB8P.*						2	1	0	0 -NVIDIA NB9E								.*NVIDIA .*NB9E.*						3	1	0	0 -NVIDIA NB9M								.*NVIDIA .*NB9M.*						1	1	0	0 -NVIDIA NB9P								.*NVIDIA .*NB9P.*						2	1	0	0 +NVIDIA GeForce Go 7300 LE				.*NVIDIA .*GeForce Go 73.*LE.*						1	1	0	0 +NVIDIA GeForce Go 7300					.*NVIDIA .*GeForce Go 73.*							1	1	1	2.1 +NVIDIA GeForce Go 7400					.*NVIDIA .*GeForce Go 74.*							1	1	1	2.1 +NVIDIA GeForce Go 7600					.*NVIDIA .*GeForce Go 76.*							1	1	1	2.1 +NVIDIA GeForce Go 7700					.*NVIDIA .*GeForce Go 77.*							0	1	1	2.1 +NVIDIA GeForce Go 7800					.*NVIDIA .*GeForce Go 78.*							2	1	0	0 +NVIDIA GeForce Go 7900					.*NVIDIA .*GeForce Go 79.*							1	1	1	2.1 +NVIDIA D9M								.*NVIDIA .*D9M.*									1	1	0	0 +NVIDIA G94								.*NVIDIA .*G94.*									3	1	0	0 +NVIDIA GeForce Go 6						.*GeForce Go 6.*									1	1	0	0 +NVIDIA ION 2							.*NVIDIA .*ION 2.*									2	1	0	0 +NVIDIA ION 								.*NVIDIA Corporation.*ION.*							2	1	1	3.3 +NVIDIA NB8M								.*NVIDIA .*NB8M.*									1	1	0	0 +NVIDIA NB8P								.*NVIDIA .*NB8P.*									2	1	0	0 +NVIDIA NB9E								.*NVIDIA .*NB9E.*									3	1	0	0 +NVIDIA NB9M								.*NVIDIA .*NB9M.*									1	1	0	0 +NVIDIA NB9P								.*NVIDIA .*NB9P.*									2	1	0	0  NVIDIA N10								.*NVIDIA .*N10.*						1	1	0	0  NVIDIA GeForce PCX						.*GeForce PCX.*							0	1	0	0  NVIDIA Generic							.*NVIDIA .*Unknown.*					0	0	0	3 -NVIDIA NV17								.*NVIDIA .*NV17.*						0	1	0	0 -NVIDIA NV34								.*NVIDIA .*NV34.*						0	1	0	0 -NVIDIA NV35								.*NVIDIA .*NV35.*						0	1	0	0 -NVIDIA NV36								.*NVIDIA .*NV36.*						1	1	0	0 -NVIDIA NV41								.*NVIDIA .*NV41.*						1	1	0	0 -NVIDIA NV43								.*NVIDIA .*NV43.*						1	1	0	0 -NVIDIA NV44								.*NVIDIA .*NV44.*						1	1	0	0 -NVIDIA nForce							.*NVIDIA .*nForce.*						0	0	0	3.3 -NVIDIA MCP51							.*NVIDIA .*MCP51.*						1	1	0	0 +NVIDIA NV17								.*NVIDIA .*NV17.*									0	1	0	0 +NVIDIA NV34								.*NVIDIA .*NV34.*									0	1	0	0 +NVIDIA NV35								.*NVIDIA .*NV35.*									0	1	0	0 +NVIDIA NV36								.*NVIDIA .*NV36.*									1	1	0	0 +NVIDIA NV41								.*NVIDIA .*NV41.*									1	1	0	0 +NVIDIA NV43								.*NVIDIA .*NV43.*									1	1	0	0 +NVIDIA NV44								.*NVIDIA .*NV44.*									1	1	0	0 +NVIDIA nForce							.*NVIDIA .*nForce.*									0	0	0	3.3 +NVIDIA MCP51							.*NVIDIA .*MCP51.*									1	1	0	0  NVIDIA MCP61							.*NVIDIA .*MCP61.*						1	1	0	0 -NVIDIA MCP67							.*NVIDIA .*MCP67.*						1	1	0	0 -NVIDIA MCP68							.*NVIDIA .*MCP68.*						1	1	0	0 -NVIDIA MCP73							.*NVIDIA .*MCP73.*						1	1	0	0 -NVIDIA MCP77							.*NVIDIA .*MCP77.*						1	1	0	0 -NVIDIA MCP78							.*NVIDIA .*MCP78.*						1	1	0	0 -NVIDIA MCP79							.*NVIDIA .*MCP79.*						1	1	0	0 -NVIDIA MCP7A							.*NVIDIA .*MCP7A.*						1	1	0	0 +NVIDIA MCP67							.*NVIDIA .*MCP67.*									1	1	0	0 +NVIDIA MCP68							.*NVIDIA .*MCP68.*									1	1	0	0 +NVIDIA MCP73							.*NVIDIA .*MCP73.*									1	1	0	0 +NVIDIA MCP77							.*NVIDIA .*MCP77.*									1	1	0	0 +NVIDIA MCP78							.*NVIDIA .*MCP78.*									1	1	0	0 +NVIDIA MCP79							.*NVIDIA .*MCP79.*									1	1	0	0 +NVIDIA MCP7A							.*NVIDIA .*MCP7A.*									1	1	0	0  NVIDIA Quadro2							.*Quadro2.*								0	1	0	0  NVIDIA Quadro 1000M						.*Quadro.*1000M.*						2	1	0	4.2  NVIDIA Quadro 2000 M/D					.*Quadro.*2000.*						3	1	0	4.2 @@ -555,12 +555,12 @@ NVIDIA Quadro 3000M						.*Quadro.*3000M.*						3	1	0	0  NVIDIA Quadro 4000M						.*Quadro.*4000M.*						3	1	0	0  NVIDIA Quadro 4000						.*Quadro *4000.*						3	1	0	4.2  NVIDIA Quadro 50x0 M					.*Quadro.*50.0.*						3	1	0	0 -NVIDIA Quadro 6000						.*Quadro.*6000.*						3	1	0	0 -NVIDIA Quadro 400						.*Quadro.*400.*							2	1	0	3.3 +NVIDIA Quadro 6000						.*Quadro.* 6000.*									3	1	0	0 +NVIDIA Quadro 400						.*Quadro.* 400.*									2	1	0	3.3  NVIDIA Quadro 600						.*Quadro.*600.*							2	1	0	3.3  NVIDIA Quadro4							.*Quadro4.*								0	1	0	0 -NVIDIA Quadro DCC						.*Quadro DCC.*							0	1	0	0 -NVIDIA Quadro CX						.*Quadro.*CX.*							3	1	0	0 +NVIDIA Quadro DCC						.*Quadro DCC.*										0	1	0	0 +NVIDIA Quadro CX						.*Quadro.*CX.*										3	1	0	0  NVIDIA Quadro FX 770M					.*Quadro.*FX *770M.*					2	1	0	0  NVIDIA Quadro FX 1500M					.*Quadro.*FX *1500M.*					1	1	0	2.1  NVIDIA Quadro FX 1600M					.*Quadro.*FX *1600M.*					2	1	0	0 @@ -574,7 +574,7 @@ NVIDIA Quadro FX 3800					.*Quadro.*FX *3800.*					3	1	0	3.2  NVIDIA Quadro FX 4500					.*Quadro.*FX *45.*						3	1	0	0  NVIDIA Quadro FX 880M					.*Quadro.*FX *880M.*					3	1	0	3.3  NVIDIA Quadro FX 4800					.*NVIDIA .*Quadro *FX *4800.*			3	1	0	0 -NVIDIA Quadro FX						.*Quadro FX.*							1	1	0	3.3 +NVIDIA Quadro FX						.*Quadro FX.*										1	1	0	3.3  NVIDIA Quadro NVS 1xxM					.*Quadro NVS *1.[05]M.*					0	1	1	3.3  NVIDIA Quadro NVS 300M					.*NVIDIA .*NVS *300M.*					2	1	0	0  NVIDIA Quadro NVS 320M					.*NVIDIA .*NVS *320M.*					2	1	0	0 @@ -583,16 +583,16 @@ NVIDIA Quadro NVS 3100M					.*NVIDIA .*NVS *3100M.*					2	1	0	0  NVIDIA Quadro NVS 4200M					.*NVIDIA .*NVS *4200M.*					2	1	0	4.1  NVIDIA Quadro NVS 5100M					.*NVIDIA .*NVS *5100M.*					2	1	0	0  NVIDIA Quadro NVS						.*NVIDIA .*NVS							0	1	0	3.2 -NVIDIA Corporation N12P					.*NVIDIA .*N12P.*						1	1	1	4.1 +NVIDIA Corporation N12P					.*NVIDIA .*N12P.*									1	1	1	4.1  NVIDIA Corporation N11M					.*NVIDIA .*N11M.*						2	1	0	0  NVIDIA RIVA TNT							.*RIVA TNT.*							0	0	0	0 -S3										.*S3 Graphics.*							0	0	1	1.4 -SiS										SiS.*									0	0	1	1.5 -Trident									Trident.*								0	0	0	0 -Tungsten Graphics						Tungsten.*								0	0	0	0 -XGI										XGI.*									0	0	0	0 -VIA										VIA.*									0	0	0	0 -Apple Generic							Apple.*Generic.*						0	0	0	0 -Apple Software Renderer					Apple.*Software Renderer.*				0	0	0	0 -Humper									Humper.*								0	1	1	2.1 -PowerVR SGX545							.*PowerVR SGX.*							1	1	1	3 +S3										.*S3 Graphics.*										0	0	1	1.4 +SiS										SiS.*												0	0	1	1.5 +Trident									Trident.*											0	0	0	0 +Tungsten Graphics						Tungsten.*											0	0	0	0 +XGI										XGI.*												0	0	0	0 +VIA										VIA.*												0	0	0	0 +Apple Generic							Apple.*Generic.*									0	0	0	0 +Apple Software Renderer					Apple.*Software Renderer.*							0	0	0	0 +Humper									Humper.*											0	1	1	2.1 +PowerVR SGX545							.*PowerVR SGX.*										1	1	1	3 diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 8c42defa73..3e94c5edf7 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4317,7 +4317,7 @@ void LLAgent::sendAgentSetAppearance()  		return;  	} - +	  	LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL;  	//dumpAvatarTEs( "sendAgentSetAppearance()" ); @@ -4425,7 +4425,7 @@ void LLAgent::sendAgentSetAppearance()  		}  	} -	//llinfos << "Avatar XML num VisualParams transmitted = " << transmitted_params << llendl; +//	llinfos << "Avatar XML num VisualParams transmitted = " << transmitted_params << llendl;  	sendReliableMessage();  } diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 0896aa5972..488a134aa2 100755 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -2267,22 +2267,22 @@ void LLAgentCamera::changeCameraToCustomizeAvatar()  		gFocusMgr.setKeyboardFocus( NULL );  		gFocusMgr.setMouseCapture( NULL ); -		// Remove any pitch or rotation from the avatar -		LLVector3 at = gAgent.getAtAxis(); -		at.mV[VZ] = 0.f; -		at.normalize(); -		gAgent.resetAxes(at); - -		gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START); -		gAgent.setCustomAnim(TRUE); -		gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE); -		LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE); - -		if (turn_motion) -		{ -			// delay camera animation long enough to play through turn animation -			setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP); -		} +			// Remove any pitch or rotation from the avatar +			LLVector3 at = gAgent.getAtAxis(); +			at.mV[VZ] = 0.f; +			at.normalize(); +			gAgent.resetAxes(at); + +			gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START); +			gAgent.setCustomAnim(TRUE); +			gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE); +			LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE); + +			if (turn_motion) +			{ +				// delay camera animation long enough to play through turn animation +				setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP); +			}  	}  	LLVector3 agent_at = gAgent.getAtAxis(); diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index c88694ef76..1edbbe2a2e 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -62,15 +62,15 @@ using namespace LLAvatarAppearanceDefines;  // Callback to wear and start editing an item that has just been created.  void wear_and_edit_cb(const LLUUID& inv_item) -{ -	if (inv_item.isNull()) return; -	 -	// Request editing the item after it gets worn. -	gAgentWearables.requestEditingWearable(inv_item); -	 -	// Wear it. -	LLAppearanceMgr::instance().wearItemOnAvatar(inv_item); -} +	{ +		if (inv_item.isNull()) return; + +		// Request editing the item after it gets worn. +		gAgentWearables.requestEditingWearable(inv_item); + +		// Wear it. +		LLAppearanceMgr::instance().wearItemOnAvatar(inv_item); +	}  /////////////////////////////////////////////////////////////////////////////// @@ -180,10 +180,10 @@ void LLAgentWearables::initClass()  }  void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar) -{ +{   	llassert(avatar); -	avatar->outputRezTiming("Sending wearables request"); -	sendAgentWearablesRequest(); +		avatar->outputRezTiming("Sending wearables request"); +		sendAgentWearablesRequest();  	setAvatarAppearance(avatar);  } @@ -706,7 +706,7 @@ LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::ETyp  }  const LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const -{ +	{  	return dynamic_cast<const LLViewerWearable*> (getWearable(type, index));  } @@ -714,39 +714,39 @@ const LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType  BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type)  {  	return (gAgentWearables.getWearableCount(type) > 0); -} - +	} +	  // virtual  void LLAgentWearables::wearableUpdated(LLWearable *wearable, BOOL removed) -{ +	{  	if (isAgentAvatarValid())  	{  		const BOOL upload_result = removed;  		gAgentAvatarp->wearableUpdated(wearable->getType(), upload_result); -	} +}  	LLWearableData::wearableUpdated(wearable, removed);  	if (!removed) -	{ +{  		LLViewerWearable* viewer_wearable = dynamic_cast<LLViewerWearable*>(wearable);  		viewer_wearable->refreshName(); -		// Hack pt 2. If the wearable we just loaded has definition version 24, -		// then force a re-save of this wearable after slamming the version number to 22. -		// This number was incorrectly incremented for internal builds before release, and -		// this fix will ensure that the affected wearables are re-saved with the right version number. -		// the versions themselves are compatible. This code can be removed before release. -		if( wearable->getDefinitionVersion() == 24 ) -		{ -			wearable->setDefinitionVersion(22); -			U32 index = getWearableIndex(wearable); +	// Hack pt 2. If the wearable we just loaded has definition version 24, +	// then force a re-save of this wearable after slamming the version number to 22. +	// This number was incorrectly incremented for internal builds before release, and +	// this fix will ensure that the affected wearables are re-saved with the right version number. +	// the versions themselves are compatible. This code can be removed before release. +	if( wearable->getDefinitionVersion() == 24 ) +	{ +		wearable->setDefinitionVersion(22); +		U32 index = getWearableIndex(wearable);  			llinfos << "forcing wearable type " << wearable->getType() << " to version 22 from 24" << llendl; -			saveWearable(wearable->getType(),index,TRUE); -		} +		saveWearable(wearable->getType(),index,TRUE); +	}  		checkWearableAgainstInventory(viewer_wearable); -	} +}  }  BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const @@ -965,8 +965,8 @@ public:  		llinfos << "All items created" << llendl;  		LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;  		LLAppearanceMgr::instance().linkAll(LLAppearanceMgr::instance().getCOF(), -											mItemsToLink, -											link_waiter); +												mItemsToLink, +												link_waiter);  	}  	void addPendingWearable(LLViewerWearable *wearable)  	{ @@ -1496,12 +1496,12 @@ void LLAgentWearables::queryWearableCache()  // virtual  void LLAgentWearables::invalidateBakedTextureHash(LLMD5& hash) const  { -	// Add some garbage into the hash so that it becomes invalid. -	if (isAgentAvatarValid()) -	{ -		hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES); -	} -} +		// Add some garbage into the hash so that it becomes invalid. +			if (isAgentAvatarValid()) +			{ +				hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES); +			} +		}  // User has picked "remove from avatar" from a menu.  // static diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp index 2d2d730396..8b6b6db525 100755 --- a/indra/newview/llagentwearablesfetch.cpp +++ b/indra/newview/llagentwearablesfetch.cpp @@ -36,44 +36,44 @@  void order_my_outfits_cb() -{ -	if (!LLApp::isRunning())  	{ -		llwarns << "called during shutdown, skipping" << llendl; -		return; -	} +		if (!LLApp::isRunning()) +		{ +			llwarns << "called during shutdown, skipping" << llendl; +			return; +		} -	const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); -	if (my_outfits_id.isNull()) return; +		const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); +		if (my_outfits_id.isNull()) return; -	LLInventoryModel::cat_array_t* cats; -	LLInventoryModel::item_array_t* items; -	gInventory.getDirectDescendentsOf(my_outfits_id, cats, items); -	if (!cats) return; +		LLInventoryModel::cat_array_t* cats; +		LLInventoryModel::item_array_t* items; +		gInventory.getDirectDescendentsOf(my_outfits_id, cats, items); +		if (!cats) return; -	//My Outfits should at least contain saved initial outfit and one another outfit -	if (cats->size() < 2) -	{ -		llwarning("My Outfits category was not populated properly", 0); -		return; -	} +		//My Outfits should at least contain saved initial outfit and one another outfit +		if (cats->size() < 2) +		{ +			llwarning("My Outfits category was not populated properly", 0); +			return; +		} -	llinfos << "Starting updating My Outfits with wearables ordering information" << llendl; +		llinfos << "Starting updating My Outfits with wearables ordering information" << llendl; -	for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin(); -		 outfit_iter != cats->end(); ++outfit_iter) -	{ -		const LLUUID& cat_id = (*outfit_iter)->getUUID(); -		if (cat_id.isNull()) continue; +		for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin(); +			outfit_iter != cats->end(); ++outfit_iter) +		{ +			const LLUUID& cat_id = (*outfit_iter)->getUUID(); +			if (cat_id.isNull()) continue; -		// saved initial outfit already contains wearables ordering information -		if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue; +			// saved initial outfit already contains wearables ordering information +			if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue; -		LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id); -	} +			LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id); +		} -	llinfos << "Finished updating My Outfits with wearables ordering information" << llendl; -} +		llinfos << "Finished updating My Outfits with wearables ordering information" << llendl; +	}  LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) :  	LLInventoryFetchDescendentsObserver(cof_id) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 652f199e28..fd9236c8b3 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -196,7 +196,7 @@ public:  		LLEventTimer(5.0)  	{  		if (!mTrackingPhase.empty()) -		{ +	{  			selfStartPhase(mTrackingPhase);  		}  	} @@ -212,23 +212,23 @@ public:  			addItem(item->getUUID());  		}  	} - +		  	// Request or re-request operation for specified item.  	void addItem(const LLUUID& item_id)  	{  		LL_DEBUGS("Avatar") << "item_id " << item_id << llendl; -		 +  		if (!requestOperation(item_id))  		{  			LL_DEBUGS("Avatar") << "item_id " << item_id << " requestOperation false, skipping" << llendl;  			return; -		} +	}  		mPendingRequests++;  		// On a re-request, this will reset the timer.  		mWaitTimes[item_id] = LLTimer();  		if (mRetryCounts.find(item_id) == mRetryCounts.end()) -		{ +	{  			mRetryCounts[item_id] = 0;  		}  		else @@ -242,7 +242,7 @@ public:  	void onOp(const LLUUID& src_id, const LLUUID& dst_id, LLTimer timestamp)  	{  		if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateLateOpRate")) -		{ +	{  			llwarns << "Simulating late operation by punting handling to later" << llendl;  			doAfterInterval(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,src_id,dst_id,timestamp),  							mRetryAfter); @@ -265,12 +265,12 @@ public:  			onCompletionOrFailure();  		}  	} - +		  	void onCompletionOrFailure()  	{  		assert (!mCompletionOrFailureCalled);  		mCompletionOrFailureCalled = true; -		 +  		// Will never call onCompletion() if any item has been flagged as  		// a failure - otherwise could wind up with corrupted  		// outfit, involuntary nudity, etc. @@ -288,7 +288,7 @@ public:  			onFailure();  		}  	} - +		  	void onFailure()  	{  		llinfos << "failed" << llendl; @@ -300,7 +300,7 @@ public:  		llinfos << "done" << llendl;  		mOnCompletionFunc();  	} -	 +  	// virtual  	// Will be deleted after returning true - only safe to do this if all callbacks have fired.  	BOOL tick() @@ -313,7 +313,7 @@ public:  		// been serviced, since it will result in this object being  		// deleted.  		bool all_done = (mPendingRequests==0); - +		  		if (!mWaitTimes.empty())  		{  			llwarns << "still waiting on " << mWaitTimes.size() << " items" << llendl; @@ -323,20 +323,20 @@ public:  				// Use a copy of iterator because it may be erased/invalidated.  				std::map<LLUUID,LLTimer>::iterator curr_it = it;  				++it; -				 +  				F32 time_waited = curr_it->second.getElapsedTimeF32();  				S32 retries = mRetryCounts[curr_it->first];  				if (time_waited > mRetryAfter)  				{  					if (retries < mMaxRetries) -					{ +		{  						LL_DEBUGS("Avatar") << "Waited " << time_waited <<  							" for " << curr_it->first << ", retrying" << llendl;  						mRetryCount++;  						addItem(curr_it->first); -					} -					else -					{ +		} +		else +		{  						llwarns << "Giving up on " << curr_it->first << " after too many retries" << llendl;  						mWaitTimes.erase(curr_it);  						mFailCount++; @@ -347,8 +347,8 @@ public:  					onCompletionOrFailure();  				} -			}  		} +	}  		return all_done;  	} @@ -360,7 +360,7 @@ public:  		LL_DEBUGS("Avatar") << "Times: n " << mTimeStats.getCount() << " min " << mTimeStats.getMinValue() << " max " << mTimeStats.getMaxValue() << llendl;  		LL_DEBUGS("Avatar") << "Mean " << mTimeStats.getMean() << " stddev " << mTimeStats.getStdDev() << llendl;  	} -	 +  	virtual ~LLCallAfterInventoryBatchMgr()  	{  		LL_DEBUGS("Avatar") << "deleting" << llendl; @@ -397,9 +397,9 @@ public:  	{  		addItems(src_items);  	} -	 +  	virtual bool requestOperation(const LLUUID& item_id) -	{ +		{  		LLViewerInventoryItem *item = gInventory.getItem(item_id);  		llassert(item);  		LL_DEBUGS("Avatar") << "copying item " << item_id << llendl; @@ -479,9 +479,9 @@ public:  			LLAppearanceMgr::instance().purgeBaseOutfitLink(cof);  			if (catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT) -			{ +	{  				if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate")) -				{ +		{  					LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;  					return true;  				} @@ -841,69 +841,69 @@ bool LLWearableHoldingPattern::pollFetchCompletion()  void recovered_item_link_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)  {  	if (!holder->isMostRecent()) -	{ -		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; -		// runway skip here? -	} +		{ +			llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +			// runway skip here? +		}  	llinfos << "Recovered item link for type " << type << llendl;  	holder->eraseTypeToLink(type); -	// Add wearable to FoundData for actual wearing -	LLViewerInventoryItem *item = gInventory.getItem(item_id); -	LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL; +		// Add wearable to FoundData for actual wearing +		LLViewerInventoryItem *item = gInventory.getItem(item_id); +		LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL; -	if (linked_item) -	{ -		gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID()); -			 -		if (item) +		if (linked_item)  		{ -			LLFoundData found(linked_item->getUUID(), -							  linked_item->getAssetUUID(), -							  linked_item->getName(), -							  linked_item->getType(), -							  linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID, -							  true // is replacement -				); +			gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID()); +			 +			if (item) +			{ +				LLFoundData found(linked_item->getUUID(), +								  linked_item->getAssetUUID(), +								  linked_item->getName(), +								  linked_item->getType(), +								  linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID, +								  true // is replacement +					);  			found.mWearable = wearable;  			holder->getFoundList().push_front(found); +			} +			else +			{ +				llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl; +			}  		}  		else  		{ -			llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl; +			llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl;  		}  	} -	else -	{ -		llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl; -	} -}  void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)  {  	if (!holder->isMostRecent()) -	{ -		// runway skip here? -		llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; -	} +		{ +			// runway skip here? +			llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +		}  	LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << type << LL_ENDL; -	LLViewerInventoryItem *itemp = gInventory.getItem(item_id); +		LLViewerInventoryItem *itemp = gInventory.getItem(item_id);  	wearable->setItemID(item_id);  	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_link_cb,_1,type,wearable,holder));  	holder->eraseTypeToRecover(type); -	llassert(itemp); -	if (itemp) -	{ -		link_inventory_item( gAgent.getID(), -							 item_id, -							 LLAppearanceMgr::instance().getCOF(), -							 itemp->getName(), -							 itemp->getDescription(), -							 LLAssetType::AT_LINK, -							 cb); +		llassert(itemp); +		if (itemp) +		{ +			link_inventory_item( gAgent.getID(), +					     item_id, +					     LLAppearanceMgr::instance().getCOF(), +					     itemp->getName(), +						 itemp->getDescription(), +					     LLAssetType::AT_LINK, +					     cb); +		}  	} -}  void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type)  { @@ -1290,7 +1290,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up  	if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID()))  	{  		LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(wear_on_avatar_cb,_1,replace)); -		copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(), cb); +		copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(),cb);  		return false;  	}   	else if (!gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getRootFolderID())) @@ -1680,8 +1680,8 @@ void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_lin  			}  			else  			{ -				gInventory.purgeObject(item->getUUID()); -			} +			gInventory.purgeObject(item->getUUID()); +		}  #else  			gInventory.purgeObject(item->getUUID());  		} @@ -2267,7 +2267,7 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego  	// Avoid unintentionally overwriting old wearables.  We have to do  	// this up front to avoid having to deal with the case of multiple  	// wearables being dirty. -	if (!category) return; +	if(!category) return;  	if ( !LLInventoryCallbackManager::is_instantiated() )  	{ @@ -2388,7 +2388,7 @@ void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id, bool do_update, LLPo  }  void modified_cof_cb(const LLUUID& inv_item) -{ +{		  	LLAppearanceMgr::instance().updateAppearanceFromCOF();  	// Start editing the item if previously requested. @@ -3237,7 +3237,7 @@ void LLAppearanceMgr::requestServerAppearanceUpdate(LLCurl::ResponderPtr respond  		llwarns << "No cap for UpdateAvatarAppearance." << llendl;  		return;  	} -	 +  	LLSD body;  	S32 cof_version = getCOFVersion();  	if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate")) @@ -3253,7 +3253,7 @@ void LLAppearanceMgr::requestServerAppearanceUpdate(LLCurl::ResponderPtr respond  		}  	}  	LL_DEBUGS("Avatar") << "request url " << url << " my_cof_version " << cof_version << llendl; -	 +  	//LLCurl::ResponderPtr responder_ptr;  	if (!responder_ptr.get())  	{ @@ -3347,33 +3347,33 @@ std::string LLAppearanceMgr::getAppearanceServiceURL() const  }  void show_created_outfit(LLUUID& folder_id, bool show_panel = true) -{ -	if (!LLApp::isRunning())  	{ -		llwarns << "called during shutdown, skipping" << llendl; -		return; -	} -	 -	LLSD key; -	 +		if (!LLApp::isRunning()) +		{ +			llwarns << "called during shutdown, skipping" << llendl; +			return; +		} + +		LLSD key; +		  	//EXT-7727. For new accounts inventory callback is created during login process  	// and may be processed after login process is finished  	if (show_panel) -	{ -		LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key); -		 -	} -	LLOutfitsList *outfits_list = -		dynamic_cast<LLOutfitsList*>(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab")); -	if (outfits_list) -	{ +		{ +			LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key); + +		} +		LLOutfitsList *outfits_list = +			dynamic_cast<LLOutfitsList*>(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab")); +		if (outfits_list) +		{  		outfits_list->setSelectedOutfitByUUID(folder_id); +		} + +		LLAppearanceMgr::getInstance()->updateIsDirty(); +		gAgentWearables.notifyLoadingFinished(); // New outfit is saved. +		LLAppearanceMgr::getInstance()->updatePanelOutfitName("");  	} -	 -	LLAppearanceMgr::getInstance()->updateIsDirty(); -	gAgentWearables.notifyLoadingFinished(); // New outfit is saved. -	LLAppearanceMgr::getInstance()->updatePanelOutfitName(""); -}  LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel)  { @@ -3415,13 +3415,13 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)  		llwarns << "called with empty list, nothing to do" << llendl;  	}  	for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it) -	{ +			{  		const LLUUID& id_to_remove = *it;  		const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove);  		removeCOFItemLinks(linked_item_id); -	} +			}  	updateAppearanceFromCOF(); -} +	}  void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)  { diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ed93ca849d..912a5e9b7f 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -128,9 +128,9 @@  #if LL_WINDOWS -#	include <share.h> // For _SH_DENYWR in initMarkerFile +#	include <share.h> // For _SH_DENYWR in processMarkerFiles  #else -#   include <sys/file.h> // For initMarkerFile support +#   include <sys/file.h> // For processMarkerFiles  #endif  #include "llapr.h" @@ -600,7 +600,8 @@ static void settings_to_globals()  static void settings_modify()  {  	LLRenderTarget::sUseFBO				= gSavedSettings.getBOOL("RenderDeferred"); -	LLPipeline::sRenderDeferred			= gSavedSettings.getBOOL("RenderDeferred"); +	LLPipeline::sRenderBump				= gSavedSettings.getBOOL("RenderObjectBump"); +	LLPipeline::sRenderDeferred		= LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");  	LLVOAvatar::sUseImpostors			= gSavedSettings.getBOOL("RenderUseImpostors");  	LLVOSurfacePatch::sLODFactor		= gSavedSettings.getF32("RenderTerrainLODFactor");  	LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4] @@ -742,8 +743,10 @@ bool LLAppViewer::init()  	// this allows simple skinned file lookups to work  	gDirUtilp->setSkinFolder("default", "en"); -	initLogging(); +	initLoggingAndGetLastDuration(); +	processMarkerFiles(); +  	//  	// OK to write stuff to logs now, we've now crash reported if necessary  	// @@ -766,7 +769,7 @@ bool LLAppViewer::init()  	logdir += gDirUtilp->getDirDelimiter();  	setMiniDumpDir(logdir); -	// Although initLogging() is the right place to mess with +	// Although initLoggingAndGetLastDuration() is the right place to mess with  	// setFatalFunction(), we can't query gSavedSettings until after  	// initConfiguration().  	S32 rc(gSavedSettings.getS32("QAModeTermCode")); @@ -1727,7 +1730,7 @@ bool LLAppViewer::cleanup()  		gAudiop->setStreamingAudioImpl(NULL);  		// shut down the audio subsystem -        gAudiop->shutdown(); +			gAudiop->shutdown();  		delete gAudiop;  		gAudiop = NULL; @@ -1803,6 +1806,8 @@ bool LLAppViewer::cleanup()  	LLAvatarAppearance::cleanupClass(); +	LLAvatarAppearance::cleanupClass(); +	  	LLPostProcess::cleanupClass();  	LLTracker::cleanupInstance(); @@ -2126,7 +2131,7 @@ void errorCallback(const std::string &error_string)  	LLError::crashAndLoop(error_string);  } -void LLAppViewer::initLogging() +void LLAppViewer::initLoggingAndGetLastDuration()  {  	//  	// Set up logging defaults for the viewer @@ -2151,24 +2156,35 @@ void LLAppViewer::initLogging()  	std::string start_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, START_MARKER_FILE_NAME);  	llstat start_marker_stat;  	llstat log_file_stat; -	if (   0 == LLFile::stat(start_marker_file_name, &start_marker_stat) -		&& 0 == LLFile::stat(log_file, &log_file_stat) -		) +	std::ostringstream duration_log_stream; // can't log yet, so save any message for when we can below +	int start_stat_result = LLFile::stat(start_marker_file_name, &start_marker_stat); +	int log_stat_result = LLFile::stat(log_file, &log_file_stat); +	if ( 0 == start_stat_result && 0 == log_stat_result )  	{  		int elapsed_seconds = log_file_stat.st_ctime - start_marker_stat.st_ctime;  		// only report a last run time if the last viewer was the same version  		// because this stat will be counted against this version -		gLastExecDuration = markerIsSameVersion(start_marker_file_name) ? elapsed_seconds : -1; +		if ( markerIsSameVersion(start_marker_file_name) ) +		{ +			gLastExecDuration = elapsed_seconds; +		} +		else +		{ +			duration_log_stream << "start marker from some other version; duration is not reported"; +			gLastExecDuration = -1; +		}  	}  	else  	{  		// at least one of the LLFile::stat calls failed, so we can't compute the run time +		duration_log_stream << "duration stat failure; start: "<< start_stat_result << " log: " << log_stat_result;  		gLastExecDuration = -1; // unknown  	} +	std::string duration_log_msg(duration_log_stream.str());  	// Create a new start marker file for comparison with log file time for the next run  	LLAPRFile start_marker_file ; -	start_marker_file.open(start_marker_file_name, LL_APR_W); +	start_marker_file.open(start_marker_file_name, LL_APR_WB);  	if (start_marker_file.getFileHandle())  	{  		recordMarkerVersion(start_marker_file); @@ -2180,6 +2196,10 @@ void LLAppViewer::initLogging()  	// Set the log file to SecondLife.log  	LLError::logToFile(log_file); +	if (!duration_log_msg.empty()) +	{ +		LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL; +	}  }  bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, @@ -2757,7 +2777,6 @@ bool LLAppViewer::initConfiguration()  	//  	// Check for another instance of the app running  	// -	mSecondInstance = anotherInstanceRunning();  	if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers"))  	{  		std::ostringstream msg; @@ -2769,8 +2788,6 @@ bool LLAppViewer::initConfiguration()  		return false;  	} -	initMarkerFile(); -          	if (mSecondInstance)  	{  		// This is the second instance of SL. Turn off voice support, @@ -2971,26 +2988,26 @@ namespace {  		{  			LL_WARNS("UpdaterService") << "no info url supplied - defaulting to hard coded release notes pattern" << LL_ENDL; -			// truncate version at the rightmost '.'  -			std::string version_short(data["version"]); -			size_t short_length = version_short.rfind('.'); -			if (short_length != std::string::npos) -			{ -				version_short.resize(short_length); -			} +		// truncate version at the rightmost '.'  +		std::string version_short(data["version"]); +		size_t short_length = version_short.rfind('.'); +		if (short_length != std::string::npos) +		{ +			version_short.resize(short_length); +		} -			LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]"); -			relnotes_url.setArg("[VERSION_SHORT]", version_short); +		LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]"); +		relnotes_url.setArg("[VERSION_SHORT]", version_short); -			// *TODO thread the update service's response through to this point -			std::string const & channel = LLVersionInfo::getChannel(); -			boost::shared_ptr<char> channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free); +		// *TODO thread the update service's response through to this point +		std::string const & channel = LLVersionInfo::getChannel(); +		boost::shared_ptr<char> channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free); -			relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get()); -			relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL")); +		relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get()); +		relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL"));  			substitutions["INFO_URL"] = relnotes_url.getString();  		} -		 +  		LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_callback);  	} @@ -3456,21 +3473,21 @@ void LLAppViewer::handleViewerCrash()  	//we're already in a crash situation	  	if (gDirUtilp)  	{ -		std::string crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, -																	 gLLErrorActivated -																	 ? LLERROR_MARKER_FILE_NAME -																	 : ERROR_MARKER_FILE_NAME); -		LLAPRFile crash_file ; -		crash_file.open(crash_file_name, LL_APR_W); -		if (crash_file.getFileHandle()) +		std::string crash_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, +																			gLLErrorActivated +																			? LLERROR_MARKER_FILE_NAME +																			: ERROR_MARKER_FILE_NAME); +		LLAPRFile crash_marker_file ; +		crash_marker_file.open(crash_marker_file_name, LL_APR_WB); +		if (crash_marker_file.getFileHandle())  		{ -			LL_INFOS("MarkerFile") << "Created crash marker file " << crash_file_name << LL_ENDL; -			recordMarkerVersion(crash_file); +			LL_INFOS("MarkerFile") << "Created crash marker file " << crash_marker_file_name << LL_ENDL; +			recordMarkerVersion(crash_marker_file);  		}  		else  		{ -			LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_file_name << LL_ENDL; -		}		 +			LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_marker_file_name << LL_ENDL; +		}  	}  	else  	{ @@ -3521,38 +3538,6 @@ void LLAppViewer::handleViewerCrash()  	return;  } -bool LLAppViewer::anotherInstanceRunning() -{ -	// We create a marker file when the program starts and remove the file when it finishes. -	// If the file is currently locked, that means another process is already running. - -	std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, MARKER_FILE_NAME); -	LL_DEBUGS("MarkerFile") << "Checking marker file '"<< marker_file << "' for lock..." << LL_ENDL; - -	//Freeze case checks -	if (LLAPRFile::isExist(marker_file, NULL, LL_APR_RB)) -	{ -		// File exists, try opening with write permissions -		LLAPRFile outfile ; -		outfile.open(marker_file, LL_APR_AB); -		apr_file_t* fMarker = outfile.getFileHandle() ;  -		if (!fMarker) -		{ -			// Another instance is running. Skip the rest of these operations. -			LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL; -			return true; -		} -		if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) //flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1) -		{ -			LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL; -			return true; -		} -		// No other instances; we'll lock this file now & delete on quit.		 -	} -	LL_DEBUGS("MarkerFile") << "Marker file isn't locked." << LL_ENDL; -	return false; -} -  // static  void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file)   {		 @@ -3597,14 +3582,8 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const  	return sameVersion;  } -void LLAppViewer::initMarkerFile() +void LLAppViewer::processMarkerFiles()  { -	//First, check for the existence of other files. -	//There are marker files for two different types of crashes -	 -	mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME); -	LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL; -  	//We've got 4 things to test for here  	// - Other Process Running (SecondLife.exec_marker present, locked)  	// - Freeze (SecondLife.exec_marker present, not locked) @@ -3612,29 +3591,92 @@ void LLAppViewer::initMarkerFile()  	// - Other Crash (SecondLife.error_marker present)  	// These checks should also remove these files for the last 2 cases if they currently exist -	//LLError/Error checks. Only one of these should ever happen at a time. -	std::string logout_marker_file =  gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME); -	std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME); -	std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); - -	if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning()) +	bool marker_is_same_version = true; +	// first, look for the marker created at startup and deleted on a clean exit +	mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME); +	if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB))  	{ -		if ( markerIsSameVersion(mMarkerFileName) ) +		// File exists... +		// first, read it to see if it was created by the same version (we need this later) +		marker_is_same_version = markerIsSameVersion(mMarkerFileName); + +		// now test to see if this file is locked by a running process (try to open for write) +		LL_DEBUGS("MarkerFile") << "Checking exec marker file for lock..." << LL_ENDL; +		mMarkerFile.open(mMarkerFileName, LL_APR_WB); +		apr_file_t* fMarker = mMarkerFile.getFileHandle() ;  +		if (!fMarker) +		{ +			LL_INFOS("MarkerFile") << "Exec marker file open failed - assume it is locked." << LL_ENDL; +			mSecondInstance = true; // lock means that instance is running. +		} +		else  		{ -			LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found" << LL_ENDL; +			// We were able to open it, now try to lock it ourselves... +			if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) +			{ +				LL_WARNS_ONCE("MarkerFile") << "Locking exec marker failed." << LL_ENDL; +				mSecondInstance = true; // lost a race? be conservative +			} +			else +			{ +				// No other instances; we've locked this file now, so record our version; delete on quit.		 +				recordMarkerVersion(mMarkerFile); +				LL_DEBUGS("MarkerFile") << "Exec marker file existed but was not locked; rewritten." << LL_ENDL; +			} +		} + +		if (mSecondInstance) +		{ +			LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' owned by another instance" << LL_ENDL; +		} +		else if (marker_is_same_version) +		{ +			// the file existed, is ours, and matched our version, so we can report on what it says +			LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec FROZE" << LL_ENDL;  			gLastExecEvent = LAST_EXEC_FROZE; +				  		}  		else  		{  			LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL;  		} -	}     +	} +	else // marker did not exist... last exec (if any) did not freeze +	{ +		// Create the marker file for this execution & lock it; it will be deleted on a clean exit +		apr_status_t s; +		s = mMarkerFile.open(mMarkerFileName, LL_APR_WB, TRUE);	 + +		if (s == APR_SUCCESS && mMarkerFile.getFileHandle()) +		{ +			LL_DEBUGS("MarkerFile") << "Exec marker file '"<< mMarkerFileName << "' created." << LL_ENDL; +			if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE))  +			{ +				recordMarkerVersion(mMarkerFile); +				LL_DEBUGS("MarkerFile") << "Exec marker file locked." << LL_ENDL; +			} +			else +			{ +				LL_WARNS("MarkerFile") << "Exec marker file cannot be locked." << LL_ENDL; +			} +		} +		else +		{ +			LL_WARNS("MarkerFile") << "Failed to create exec marker file '"<< mMarkerFileName << "'." << LL_ENDL; +		} +	} + +	// now check for cases in which the exec marker may have been cleaned up by crash handlers + +	// check for any last exec event report based on whether or not it happened during logout +	// (the logout marker is created when logout begins) +	std::string logout_marker_file =  gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME);  	if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))  	{  		if (markerIsSameVersion(logout_marker_file))  		{  			gLastExecEvent = LAST_EXEC_LOGOUT_FROZE; -			LL_INFOS("MarkerFile") << "Logout crashed '"<< logout_marker_file << "', setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +			LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "', changing LastExecEvent to LOGOUT_FROZE" << LL_ENDL;  		}  		else  		{ @@ -3642,89 +3684,86 @@ void LLAppViewer::initMarkerFile()  		}  		LLAPRFile::remove(logout_marker_file);  	} +	// further refine based on whether or not a marker created during an llerr crash is found +	std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);  	if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))  	{  		if (markerIsSameVersion(llerror_marker_file))  		{ -			gLastExecEvent = ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE ) -				? LAST_EXEC_LOGOUT_CRASH : LAST_EXEC_LLERROR_CRASH; -			LL_INFOS("MarkerFile") << "Last exec LLError '"<< llerror_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +			if ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE ) +			{ +				gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; +				LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL; +			} +			else +			{ +				gLastExecEvent = LAST_EXEC_LLERROR_CRASH; +				LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL; +			}  		}  		else  		{ -			LL_INFOS("MarkerFile") << "Last exec LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL; +			LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL;  		}  		LLAPRFile::remove(llerror_marker_file);  	} +	// and last refine based on whether or not a marker created during a non-llerr crash is found +	std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);  	if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))  	{  		if (markerIsSameVersion(error_marker_file))  		{ -			gLastExecEvent = (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) -				? LAST_EXEC_LOGOUT_CRASH : LAST_EXEC_OTHER_CRASH; -			LL_INFOS("MarkerFile") << "Last exec '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +			if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) +			{ +				gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; +				LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL; +			} +			else +			{ +				gLastExecEvent = LAST_EXEC_OTHER_CRASH; +				LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +			}  		}  		else  		{ -			LL_INFOS("MarkerFile") << "Last exec '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL; +			LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL;  		}  		LLAPRFile::remove(error_marker_file);  	} - -	// No new markers if another instance is running. -	if(anotherInstanceRunning())  -	{ -		return; -	} -	 -	// Create the marker file for this execution & lock it -	apr_status_t s; -	s = mMarkerFile.open(mMarkerFileName, LL_APR_W, TRUE);	 - -	if (s == APR_SUCCESS && mMarkerFile.getFileHandle()) -	{ -		LL_DEBUGS("MarkerFile") << "Marker file '"<< mMarkerFileName << "' created." << LL_ENDL; -		if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE))  -		{ -			recordMarkerVersion(mMarkerFile); -			LL_DEBUGS("MarkerFile") << "Marker file locked." << LL_ENDL; -		} -		else -		{ -			LL_INFOS("MarkerFile") << "Marker file cannot be locked." << LL_ENDL; -		} -	} -	else -	{ -		LL_INFOS("MarkerFile") << "Failed to create marker file '"<< mMarkerFileName << "'." << LL_ENDL; -	}  }  void LLAppViewer::removeMarkerFile(bool leave_logout_marker)  { -	LL_DEBUGS("MarkerFile") << "removeMarkerFile("<<(leave_logout_marker?"leave":"remove") <<" logout)" << LL_ENDL; -	if (mMarkerFile.getFileHandle()) -	{ -		LL_DEBUGS("MarkerFile") << "removeMarkerFile marker '"<<mMarkerFileName<<"'"<< LL_ENDL; -		mMarkerFile.close(); -		LLAPRFile::remove( mMarkerFileName ); -	} -	else -	{ -		LL_WARNS("MarkerFile") << "removeMarkerFile marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL; -	} -	if (!leave_logout_marker) -	{ -		if (mLogoutMarkerFile.getFileHandle()) +	if (!mSecondInstance) +	{		 +		LL_DEBUGS("MarkerFile") << (leave_logout_marker?"leave":"remove") <<" logout" << LL_ENDL; +		if (mMarkerFile.getFileHandle())  		{ -			LL_DEBUGS("MarkerFile") << "removeMarkerFile logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL; -			mLogoutMarkerFile.close(); +			LL_DEBUGS("MarkerFile") << "removing exec marker '"<<mMarkerFileName<<"'"<< LL_ENDL; +			mMarkerFile.close() ; +			LLAPRFile::remove( mMarkerFileName );  		}  		else  		{ -			LL_WARNS("MarkerFile") << "removeMarkerFile logout marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL; +			LL_WARNS("MarkerFile") << "marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL;  		} -		LLAPRFile::remove( mLogoutMarkerFileName ); +		if (!leave_logout_marker) +		{ +			if (mLogoutMarkerFile.getFileHandle()) +			{ +				LL_DEBUGS("MarkerFile") << "removing logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL; +				mLogoutMarkerFile.close(); +			} +			else +			{ +				LL_WARNS("MarkerFile") << "logout marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL; +			} +			LLAPRFile::remove( mLogoutMarkerFileName ); +		} +	} +	else +	{ +		LL_WARNS("MarkerFile") << "leaving markers because this is a second instance" << LL_ENDL;  	}  } @@ -3779,6 +3818,12 @@ void LLAppViewer::requestQuit()  		gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.  	} +	// Try to send last batch of avatar rez metrics. +	if (!gDisconnected && isAgentAvatarValid()) +	{ +		gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent. +	} +	  	LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);  	effectp->setPositionGlobal(gAgent.getPositionGlobal());  	effectp->setColor(LLColor4U(gAgent.getEffectColor())); @@ -4943,6 +4988,22 @@ void LLAppViewer::sendLogoutRequest()  {  	if(!mLogoutRequestSent && gMessageSystem)  	{ +		//Set internal status variables and marker files before actually starting the logout process +		gLogoutInProgress = TRUE; +		mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME); +		 +		LLAPRFile outfile ; +		mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB); +		if (mLogoutMarkerFile.getFileHandle()) +		{ +			LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL; +			recordMarkerVersion(outfile); +		} +		else +		{ +			LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL; +		}		 +  		LLMessageSystem* msg = gMessageSystem;  		msg->newMessageFast(_PREHASH_LogoutRequest);  		msg->nextBlockFast(_PREHASH_AgentData); @@ -4958,22 +5019,6 @@ void LLAppViewer::sendLogoutRequest()  		{  			LLVoiceClient::getInstance()->leaveChannel();  		} - -		//Set internal status variables and marker files -		gLogoutInProgress = TRUE; -		mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME); -		 -		LLAPRFile outfile ; -		mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_W); -		if (mLogoutMarkerFile.getFileHandle()) -		{ -			LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << mLogoutMarkerFileName << LL_ENDL; -			recordMarkerVersion(outfile); -		} -		else -		{ -			LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL; -		}		  	}  } @@ -5239,11 +5284,12 @@ void LLAppViewer::disconnectViewer()  void LLAppViewer::forceErrorLLError()  { -   	llerrs << "This is an llerror" << llendl; +   	llerrs << "This is a deliberate llerror" << llendl;  }  void LLAppViewer::forceErrorBreakpoint()  { +   	llwarns << "Forcing a deliberate breakpoint" << llendl;  #ifdef LL_WINDOWS      DebugBreak();  #endif @@ -5252,6 +5298,7 @@ void LLAppViewer::forceErrorBreakpoint()  void LLAppViewer::forceErrorBadMemoryAccess()  { +   	llwarns << "Forcing a deliberate bad memory access" << llendl;      S32* crash = NULL;      *crash = 0xDEADBEEF;        return; @@ -5259,6 +5306,7 @@ void LLAppViewer::forceErrorBadMemoryAccess()  void LLAppViewer::forceErrorInfiniteLoop()  { +   	llwarns << "Forcing a deliberate infinite loop" << llendl;      while(true)      {          ; @@ -5268,12 +5316,14 @@ void LLAppViewer::forceErrorInfiniteLoop()  void LLAppViewer::forceErrorSoftwareException()  { +   	llwarns << "Forcing a deliberate exception" << llendl;      // *FIX: Any way to insure it won't be handled?      throw;   }  void LLAppViewer::forceErrorDriverCrash()  { +   	llwarns << "Forcing a deliberate driver crash" << llendl;  	glDeleteTextures(1, NULL);  } @@ -5386,7 +5436,7 @@ void LLAppViewer::handleLoginComplete()  void LLAppViewer::launchUpdater()  { -	LLSD query_map = LLSD::emptyMap(); +		LLSD query_map = LLSD::emptyMap();  	query_map["os"] = gPlatform;  	// *TODO change userserver to be grid on both viewer and sim, since diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index bcee7be02d..260eb7352e 100755 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -187,7 +187,7 @@ public:  protected:  	virtual bool initWindow(); // Initialize the viewer's window. -	virtual void initLogging(); // Initialize log files, logging system +	virtual void initLoggingAndGetLastDuration(); // Initialize log files, logging system  	virtual void initConsole() {}; // Initialize OS level debugging console.  	virtual bool initHardwareTest() { return true; } // A false result indicates the app should quit.  	virtual bool initSLURLHandler(); @@ -219,8 +219,7 @@ private:  	void writeSystemInfo(); // Write system info to "debug_info.log" -	bool anotherInstanceRunning();  -	void initMarkerFile();  +	void processMarkerFiles();   	static void recordMarkerVersion(LLAPRFile& marker_file);  	bool markerIsSameVersion(const std::string& marker_name) const; diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 5f98fd0a34..b16bb573e1 100755 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -440,7 +440,7 @@ bool LLAppViewerLinux::beingDebugged()  #endif  } -void LLAppViewerLinux::initLogging() +void LLAppViewerLinux::initLoggingAndGetLastDuration()  {  	// Remove the last stack trace, if any  	// This file is no longer created, since the move to Google Breakpad @@ -449,7 +449,7 @@ void LLAppViewerLinux::initLogging()  		gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");  	LLFile::remove(old_stack_file); -	LLAppViewer::initLogging(); +	LLAppViewer::initLoggingAndGetLastDuration();  }  bool LLAppViewerLinux::initParseCommandLine(LLCommandLineParser& clp) diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h index b30977acb3..fb77600c10 100755 --- a/indra/newview/llappviewerlinux.h +++ b/indra/newview/llappviewerlinux.h @@ -63,7 +63,7 @@ protected:  	virtual bool restoreErrorTrap();  	virtual void handleCrashReporting(bool reportFreeze); -	virtual void initLogging(); +	virtual void initLoggingAndGetLastDuration();  	virtual bool initParseCommandLine(LLCommandLineParser& clp);  	virtual bool initSLURLHandler(); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 0ba3669487..3cf3c739d9 100755 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -490,7 +490,7 @@ bool LLAppViewerWin32::init()  	// (Don't send our data to Microsoft--at least until we are Logo approved and have a way  	// of getting the data back from them.)  	// -	llinfos << "Turning off Windows error reporting." << llendl; +	// llinfos << "Turning off Windows error reporting." << llendl;  	disableWinErrorReporting();  #ifndef LL_RELEASE_FOR_DOWNLOAD @@ -509,9 +509,9 @@ bool LLAppViewerWin32::cleanup()  	return result;  } -void LLAppViewerWin32::initLogging() +void LLAppViewerWin32::initLoggingAndGetLastDuration()  { -	LLAppViewer::initLogging(); +	LLAppViewer::initLoggingAndGetLastDuration();  }  void LLAppViewerWin32::initConsole() diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h index d95174dd1d..386bddd495 100755 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -44,7 +44,7 @@ public:  	virtual bool cleanup();  protected: -	virtual void initLogging(); // Override to clean stack_trace info. +	virtual void initLoggingAndGetLastDuration(); // Override to clean stack_trace info.  	virtual void initConsole(); // Initialize OS level debugging console.  	virtual bool initHardwareTest(); // Win32 uses DX9 to test hardware.  	virtual bool initParseCommandLine(LLCommandLineParser& clp); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 47306d3a6a..8c9fd4152a 100755 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -308,6 +308,49 @@ LLFace*	LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)  } +LLFace*	LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp) +{ +	LLFace *face; +	face = new LLFace(this, mVObjp); +	 +	face->setTEOffset(mFaces.size()); +	face->setTexture(texturep); +	face->setNormalMap(normalp); +	face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep)); +	 +	mFaces.push_back(face); +	 +	if (isState(UNLIT)) +	{ +		face->setState(LLFace::FULLBRIGHT); +	} +	 +	return face; +	 +} + +LLFace*	LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp) +{ +	LLFace *face; +	face = new LLFace(this, mVObjp); +	 +	face->setTEOffset(mFaces.size()); +	face->setTexture(texturep); +	face->setNormalMap(normalp); +	face->setSpecularMap(specularp); +	face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep)); +	 +	mFaces.push_back(face); +	 +	if (isState(UNLIT)) +	{ +		face->setState(LLFace::FULLBRIGHT); +	} +	 +	return face; +	 +} +  void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep)  {  	if (newFaces == (S32)mFaces.size()) diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 4420a34fae..c3f6d77edc 100755 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -145,6 +145,8 @@ public:  	//void                removeFace(const S32 i); // SJB: Avoid using this, it's slow  	LLFace*				addFace(LLFacePool *poolp, LLViewerTexture *texturep);  	LLFace*				addFace(const LLTextureEntry *te, LLViewerTexture *texturep); +	LLFace*				addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp); +	LLFace*				addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp);  	void				deleteFaces(S32 offset, S32 count);  	void                setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);  	void                setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep); diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 94dd927d26..04e31e6486 100755 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -35,6 +35,7 @@  #include "lldrawpoolalpha.h"  #include "lldrawpoolavatar.h"  #include "lldrawpoolbump.h" +#include "lldrawpoolmaterials.h"  #include "lldrawpoolground.h"  #include "lldrawpoolsimple.h"  #include "lldrawpoolsky.h" @@ -47,6 +48,7 @@  #include "llspatialpartition.h"  #include "llviewercamera.h"  #include "lldrawpoolwlsky.h" +#include "llglslshader.h"  S32 LLDrawPool::sNumDrawPools = 0; @@ -64,6 +66,12 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)  	case POOL_GRASS:  		poolp = new LLDrawPoolGrass();  		break; +	case POOL_ALPHA_MASK: +		poolp = new LLDrawPoolAlphaMask(); +		break; +	case POOL_FULLBRIGHT_ALPHA_MASK: +		poolp = new LLDrawPoolFullbrightAlphaMask(); +		break;  	case POOL_FULLBRIGHT:  		poolp = new LLDrawPoolFullbright();  		break; @@ -98,6 +106,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)  	case POOL_BUMP:  		poolp = new LLDrawPoolBump();  		break; +	case POOL_MATERIALS: +		poolp = new LLDrawPoolMaterials(); +		break;  	case POOL_WL_SKY:  		poolp = new LLDrawPoolWLSky();  		break; @@ -411,6 +422,27 @@ void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_text  	}  } +void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) +{ +	for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	 +	{ +		LLDrawInfo* pparams = *i; +		if (pparams)  +		{ +			if (LLGLSLShader::sCurBoundShaderPtr) +			{ +				LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); +			} +			else +			{ +				gGL.setAlphaRejectSettings(LLRender::CF_GREATER, pparams->mAlphaMaskCutoff); +			} +			 +			pushBatch(*pparams, mask, texture, batch_textures); +		} +	} +} +  void LLRenderPass::applyModelMatrix(LLDrawInfo& params)  {  	if (params.mModelMatrix != gGLLastMatrix) diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index ab9bb9e611..3bde0d29be 100755 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -50,10 +50,13 @@ public:  		POOL_GROUND,  		POOL_FULLBRIGHT,  		POOL_BUMP, +		POOL_MATERIALS,  		POOL_TERRAIN,	  		POOL_SKY,  		POOL_WL_SKY,  		POOL_TREE, +		POOL_ALPHA_MASK, +		POOL_FULLBRIGHT_ALPHA_MASK,  		POOL_GRASS,  		POOL_INVISIBLE, // see below *  		POOL_AVATAR, @@ -133,6 +136,22 @@ public:  		PASS_SHINY,  		PASS_BUMP,  		PASS_POST_BUMP, +		PASS_MATERIAL, +		PASS_MATERIAL_ALPHA, +		PASS_MATERIAL_ALPHA_MASK, +		PASS_MATERIAL_ALPHA_EMISSIVE, +		PASS_SPECMAP, +		PASS_SPECMAP_BLEND, +		PASS_SPECMAP_MASK, +		PASS_SPECMAP_EMISSIVE, +		PASS_NORMMAP, +		PASS_NORMMAP_BLEND, +		PASS_NORMMAP_MASK, +		PASS_NORMMAP_EMISSIVE, +		PASS_NORMSPEC, +		PASS_NORMSPEC_BLEND, +		PASS_NORMSPEC_MASK, +		PASS_NORMSPEC_EMISSIVE,  		PASS_GLOW,  		PASS_ALPHA,  		PASS_ALPHA_MASK, @@ -151,6 +170,7 @@ public:  	static void applyModelMatrix(LLDrawInfo& params);  	virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); +	virtual void pushMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);  	virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);  	virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);  	virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 313b310e1e..c832e1401d 100755 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -71,33 +71,6 @@ void LLDrawPoolAlpha::prerender()  	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  } -S32 LLDrawPoolAlpha::getNumDeferredPasses() -{ -	return 1; -} - -void LLDrawPoolAlpha::beginDeferredPass(S32 pass) -{ -	 -} - -void LLDrawPoolAlpha::endDeferredPass(S32 pass) -{ -	 -} - -void LLDrawPoolAlpha::renderDeferred(S32 pass) -{ -	LLFastTimer t(FTM_RENDER_GRASS); -	gDeferredDiffuseAlphaMaskProgram.bind(); -	gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f); - -	//render alpha masked objects -	LLRenderPass::pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); -	gDeferredDiffuseAlphaMaskProgram.unbind();			 -} - -  S32 LLDrawPoolAlpha::getNumPostDeferredPasses()   {   	if (LLPipeline::sImpostorRender) @@ -121,8 +94,10 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)  	if (pass == 0)  	{  		simple_shader = &gDeferredAlphaProgram; -		fullbright_shader = &gObjectFullbrightAlphaMaskProgram; - +		fullbright_shader = &gObjectFullbrightProgram; +		fullbright_shader->bind(); +		fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);  +		fullbright_shader->unbind();  		//prime simple shader (loads shadow relevant uniforms)  		gPipeline.bindDeferredShader(*simple_shader);  	} @@ -133,8 +108,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)  		gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),  							0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);	  		gPipeline.mDeferredDepth.bindTarget(); -		simple_shader = NULL; -		fullbright_shader = NULL; +		simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;  		gObjectFullbrightAlphaMaskProgram.bind();  		gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f);  	} @@ -150,7 +124,6 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)  void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)   {  -  	if (pass == 1)  	{  		gPipeline.mDeferredDepth.flush(); @@ -173,14 +146,14 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)  	if (LLPipeline::sUnderWaterRender)  	{ -		simple_shader = &gObjectSimpleWaterAlphaMaskProgram; -		fullbright_shader = &gObjectFullbrightWaterAlphaMaskProgram; +		simple_shader = &gObjectSimpleWaterProgram; +		fullbright_shader = &gObjectFullbrightWaterProgram;  		emissive_shader = &gObjectEmissiveWaterProgram;  	}  	else  	{ -		simple_shader = &gObjectSimpleAlphaMaskProgram; -		fullbright_shader = &gObjectFullbrightAlphaMaskProgram; +		simple_shader = &gObjectSimpleProgram; +		fullbright_shader = &gObjectFullbrightProgram;  		emissive_shader = &gObjectEmissiveProgram;  	} @@ -218,43 +191,7 @@ void LLDrawPoolAlpha::render(S32 pass)  	{  		gGL.setColorMask(true, true);  	} - -	if (LLPipeline::sAutoMaskAlphaNonDeferred) -	{ -		mColorSFactor = LLRender::BF_ONE;  // } -		mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow -		mAlphaSFactor = LLRender::BF_ZERO; -		mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds -		gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); - -		if (mVertexShaderLevel > 0) -		{ -			if (!LLPipeline::sRenderDeferred || !deferred_render) -			{ -				simple_shader->bind(); -				simple_shader->setMinimumAlpha(0.33f); - -				pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); -			} -			if (fullbright_shader) -			{ -				fullbright_shader->bind(); -				fullbright_shader->setMinimumAlpha(0.33f); -			} -			pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); -			//LLGLSLShader::bindNoShader(); -		} -		else -		{ -			gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f); //OK -			gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); -			pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask()); -			gPipeline.enableLightsDynamic(); -			pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask()); -			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK -		} -	} - +	  	LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ||   				(deferred_render && pass == 1) ? GL_TRUE : GL_FALSE); @@ -302,7 +239,7 @@ void LLDrawPoolAlpha::render(S32 pass)  	if (mVertexShaderLevel > 0)  	{ -		renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX); +		renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2);  	}  	else  	{ @@ -412,8 +349,14 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  				}  				LLRenderPass::applyModelMatrix(params); - +				LLMaterial* mat = NULL; + +				if (deferred_render && !LLPipeline::sUnderWaterRender) +				{ +					mat = params.mMaterial; +				} +  				if (params.mFullbright)  				{  					// Turn off lighting if it hasn't already been so. @@ -446,11 +389,30 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  					light_enabled = TRUE;  				} -				// If we need shaders, and we're not ALREADY using the proper shader, then bind it -				// (this way we won't rebind shaders unnecessarily). -				if(use_shaders && (current_shader != target_shader)) +				if (deferred_render && mat)  				{ -					llassert(target_shader != NULL); +					U32 mask = params.mShaderMask; + +					llassert(mask < LLMaterial::SHADER_COUNT); +					target_shader = &(gDeferredMaterialProgram[mask]); + +					if (current_shader != target_shader) +					{ +						gPipeline.bindDeferredShader(*target_shader); +					} +				} +				else if (!params.mFullbright) +				{ +					target_shader = simple_shader; +				} +				else +				{ +					target_shader = fullbright_shader; +				} +				 +				if(use_shaders && (current_shader != target_shader)) +				{// If we need shaders, and we're not ALREADY using the proper shader, then bind it +				// (this way we won't rebind shaders unnecessarily).  					current_shader = target_shader;  					current_shader->bind();  				} @@ -459,6 +421,38 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  					LLGLSLShader::bindNoShader();  					current_shader = NULL;  				} +				 +				if (use_shaders && mat) +				{ +					// We have a material.  Supply the appropriate data here. +					if (LLPipeline::sRenderDeferred) +					{ +						current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);						 +						current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity); +						current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f); + +						if (params.mNormalMap) +						{ +							params.mNormalMap->addTextureStats(params.mVSize); +							current_shader->bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap); +						}  +						 +						if (params.mSpecularMap) +						{ +							params.mSpecularMap->addTextureStats(params.mVSize); +							current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap); +						}  +					} + +				} else if (LLPipeline::sRenderDeferred && current_shader && (current_shader == simple_shader)) +				{ +					current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);						 +					current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);			 +					LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(params.mVSize); +					current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);						 +					LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize); +					current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); +				}  				if (params.mGroup)  				{ @@ -477,12 +471,20 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  						}  					}  				} -				else +				else    				{ //not batching textures or batch has only 1 texture -- might need a texture matrix  					if (params.mTexture.notNull())  					{  						params.mTexture->addTextureStats(params.mVSize); -						gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; +						if (use_shaders && mat) +						{ +							current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, params.mTexture); +						} +						else +						{ +							gGL.getTexUnit(0)->bind(params.mTexture, TRUE); +						} +						  						if (params.mTextureMatrix)  						{  							tex_setup = true; diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h index a4245e561d..43122218ed 100755 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -50,11 +50,6 @@ public:  	LLDrawPoolAlpha(U32 type = LLDrawPool::POOL_ALPHA);  	/*virtual*/ ~LLDrawPoolAlpha(); -	/*virtual*/ S32 getNumDeferredPasses(); -	/*virtual*/ void beginDeferredPass(S32 pass); -	/*virtual*/ void endDeferredPass(S32 pass); -	/*virtual*/ void renderDeferred(S32 pass); -  	/*virtual*/ S32 getNumPostDeferredPasses();  	/*virtual*/ void beginPostDeferredPass(S32 pass);  	/*virtual*/ void endPostDeferredPass(S32 pass); @@ -70,7 +65,7 @@ public:  	void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);  	void renderAlpha(U32 mask);  	void renderAlphaHighlight(U32 mask); -	 +		  	static BOOL sShowDebugAlpha;  private: diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 294cecc703..075299386e 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -62,6 +62,7 @@ S32 LLDrawPoolAvatar::sDiffuseChannel = 0;  static bool is_deferred_render = false; +static bool is_post_deferred_render = false;  extern BOOL gUseGLPick; @@ -183,6 +184,9 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)  	case 4:  		beginDeferredRiggedBump();  		break; +	default: +		beginDeferredRiggedMaterial(pass-5); +		break;  	}  } @@ -215,6 +219,9 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass)  	case 4:  		endDeferredRiggedBump();  		break; +	default: +		endDeferredRiggedMaterial(pass-5); +		break;  	}  } @@ -225,7 +232,7 @@ void LLDrawPoolAvatar::renderDeferred(S32 pass)  S32 LLDrawPoolAvatar::getNumPostDeferredPasses()  { -	return 6; +	return 10;  }  void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) @@ -247,9 +254,12 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)  	case 4:  		beginRiggedFullbrightAlpha();  		break; -	case 5: +	case 9:  		beginRiggedGlow();  		break; +	default: +		beginDeferredRiggedMaterialAlpha(pass-5); +		break;  	}  } @@ -275,11 +285,34 @@ void LLDrawPoolAvatar::beginDeferredRiggedAlpha()  	gPipeline.enableLightsDynamic();  } +void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass) +{ +	switch (pass) +	{ +	case 0: pass = 1; break; +	case 1: pass = 5; break; +	case 2: pass = 9; break; +	default: pass = 13; break; +	} + +	pass += LLMaterial::SHADER_COUNT; + +	sVertexProgram = &gDeferredMaterialProgram[pass]; + +	gPipeline.bindDeferredShader(*sVertexProgram); +	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +	normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); +	specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); +	gPipeline.enableLightsDynamic(); +} +  void LLDrawPoolAvatar::endDeferredRiggedAlpha()  {  	LLVertexBuffer::unbind();  	gPipeline.unbindDeferredShader(*sVertexProgram);  	sDiffuseChannel = 0; +	normal_channel = -1; +	specular_channel = -1;  	sVertexProgram = NULL;  } @@ -305,6 +338,9 @@ void LLDrawPoolAvatar::endPostDeferredPass(S32 pass)  	case 5:  		endRiggedGlow();  		break; +	default: +		endDeferredRiggedAlpha(); +		break;  	}  } @@ -328,17 +364,23 @@ void LLDrawPoolAvatar::renderPostDeferred(S32 pass)  		6, //rigged fullbright shiny  		7, //rigged alpha  		8, //rigged fullbright alpha -		9, //rigged glow +		9, //rigged material alpha 1 +		10,//rigged material alpha 2 +		11,//rigged material alpha 3 +		12,//rigged material alpha 4 +		13, //rigged glow  	}; -	pass = actual_pass[pass]; +	S32 p = actual_pass[pass];  	if (LLPipeline::sImpostorRender)  	{ //HACK for impostors so actual pass ends up being proper pass -		pass -= 2; +		p -= 2;  	} -	render(pass); +	is_post_deferred_render = true; +	render(p); +	is_post_deferred_render = false;  } @@ -425,12 +467,10 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)  	}  	else  	{ -		renderRigged(avatarp, RIGGED_SIMPLE); -		renderRigged(avatarp, RIGGED_ALPHA); -		renderRigged(avatarp, RIGGED_FULLBRIGHT); -		renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY); -		renderRigged(avatarp, RIGGED_SHINY); -		renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA); +		for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i) +		{ +			renderRigged(avatarp, i); +		}  	}  } @@ -455,7 +495,7 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses()  	}  	else  	{ -		return 5; +		return 21;  	}  } @@ -839,6 +879,8 @@ void LLDrawPoolAvatar::beginRiggedGlow()  	{  		sDiffuseChannel = 0;  		sVertexProgram->bind(); + +		sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f);  	}  } @@ -857,7 +899,14 @@ void LLDrawPoolAvatar::beginRiggedFullbright()  		}  		else  		{ -			sVertexProgram = &gSkinnedObjectFullbrightProgram; +			if (LLPipeline::sRenderDeferred) +			{ +				sVertexProgram = &gDeferredSkinnedFullbrightProgram; +			} +			else +			{ +				sVertexProgram = &gSkinnedObjectFullbrightProgram; +			}  		}  	}  	else @@ -876,6 +925,15 @@ void LLDrawPoolAvatar::beginRiggedFullbright()  	{  		sDiffuseChannel = 0;  		sVertexProgram->bind(); + +		if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred) +		{ +			sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); +		}  +		else  +		{ +			sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +		}  	}  } @@ -942,7 +1000,14 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()  		}  		else  		{ -			sVertexProgram = &gSkinnedObjectFullbrightShinyProgram; +			if (LLPipeline::sRenderDeferred) +			{ +				sVertexProgram = &gDeferredSkinnedFullbrightShinyProgram; +			} +			else +			{ +				sVertexProgram = &gSkinnedObjectFullbrightShinyProgram; +			}  		}  	}  	else @@ -957,11 +1022,19 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()  		}  	} -  	if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())  	{  		sVertexProgram->bind();  		LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false); + +		if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred) +		{ +			sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); +		}  +		else  +		{ +			sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +		}  	}  } @@ -1010,6 +1083,42 @@ void LLDrawPoolAvatar::endDeferredRiggedBump()  	sVertexProgram = NULL;  } +void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass) +{ +	if (pass == 1 || +		pass == 5 || +		pass == 9 || +		pass == 13) +	{ //skip alpha passes +		return; +	} +	sVertexProgram = &gDeferredMaterialProgram[pass+LLMaterial::SHADER_COUNT]; +	sVertexProgram->bind(); +	normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); +	specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); +	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +} + +void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass) +{ +	if (pass == 1 || +		pass == 5 || +		pass == 9 || +		pass == 13) +	{ +		return; +	} + +	LLVertexBuffer::unbind(); +	sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP); +	sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP); +	sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +	sVertexProgram->unbind(); +	normal_channel = -1; +	sDiffuseChannel = 0; +	sVertexProgram = NULL; +} +  void LLDrawPoolAvatar::beginDeferredSkinned()  {  	sShaderLevel = mVertexShaderLevel; @@ -1167,6 +1276,22 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  		else  		{  			renderRiggedSimple(avatarp); + +			if (LLPipeline::sRenderDeferred) +			{ //render "simple" materials +				renderRigged(avatarp, RIGGED_MATERIAL); +				renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK); +				renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE); +				renderRigged(avatarp, RIGGED_NORMMAP); +				renderRigged(avatarp, RIGGED_NORMMAP_MASK); +				renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);	 +				renderRigged(avatarp, RIGGED_SPECMAP); +				renderRigged(avatarp, RIGGED_SPECMAP_MASK); +				renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE); +				renderRigged(avatarp, RIGGED_NORMSPEC); +				renderRigged(avatarp, RIGGED_NORMSPEC_MASK); +				renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE); +			}  		}  		return;  	} @@ -1185,9 +1310,27 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  		return;  	} +	if (is_deferred_render && pass >= 5 && pass <= 21) +	{ +		S32 p = pass-5; + +		if (p != 1 && +			p != 5 && +			p != 9 && +			p != 13) +		{ +			renderDeferredRiggedMaterial(avatarp, p); +		} +		return; +	} + + + +  	if (pass == 5)  	{  		renderRiggedShinySimple(avatarp); +				  		return;  	} @@ -1197,11 +1340,29 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  		return;  	} -	if (pass >= 7 && pass < 9) +	if (pass >= 7 && pass < 13)  	{  		if (pass == 7)  		{  			renderRiggedAlpha(avatarp); + +			if (LLPipeline::sRenderDeferred && !is_post_deferred_render) +			{ //render transparent materials under water +				LLGLEnable blend(GL_BLEND); + +				gGL.setColorMask(true, true); +				gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, +								LLRender::BF_ONE_MINUS_SOURCE_ALPHA, +								LLRender::BF_ZERO, +								LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + +				renderRigged(avatarp, RIGGED_MATERIAL_ALPHA); +				renderRigged(avatarp, RIGGED_SPECMAP_BLEND); +				renderRigged(avatarp, RIGGED_NORMMAP_BLEND); +				renderRigged(avatarp, RIGGED_NORMSPEC_BLEND); + +				gGL.setColorMask(true, false); +			}  			return;  		} @@ -1210,9 +1371,32 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  			renderRiggedFullbrightAlpha(avatarp);  			return;  		} + +		if (LLPipeline::sRenderDeferred && is_post_deferred_render) +		{ +			S32 p = 0; +			switch (pass) +			{ +			case 9: p = 1; break; +			case 10: p = 5; break; +			case 11: p = 9; break; +			case 12: p = 13; break; +			} + +			{ +				LLGLEnable blend(GL_BLEND); +				renderDeferredRiggedMaterial(avatarp, p); +			} +			return; +		} +		else if (pass == 9) +		{ +			renderRiggedGlow(avatarp); +			return; +		}  	} -	if (pass == 9) +	if (pass == 13)  	{  		renderRiggedGlow(avatarp); @@ -1474,9 +1658,11 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  		{  			if (sShaderLevel > 0)  			{ //upload matrix palette to shader -				LLMatrix4 mat[64]; +				LLMatrix4 mat[32]; + +				U32 count = llmin((U32) skin->mJointNames.size(), (U32) 32); -				for (U32 i = 0; i < skin->mJointNames.size(); ++i) +				for (U32 i = 0; i < count; ++i)  				{  					LLJoint* joint = avatar->getJoint(skin->mJointNames[i]);  					if (joint) @@ -1489,7 +1675,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  				stop_glerror();  				LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette",  -					skin->mJointNames.size(), +					count,  					FALSE,  					(GLfloat*) mat[0].mMatrix); @@ -1510,10 +1696,59 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  				gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow());  			}*/ -			gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture()); -			if (normal_channel > -1) +			const LLTextureEntry* te = face->getTextureEntry(); +			LLMaterial* mat = te->getMaterialParams().get(); + +			if (mat)  			{ -				LLDrawPoolBump::bindBumpMap(face, normal_channel); +				gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP)); +				gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP)); +				gGL.getTexUnit(specular_channel)->bind(face->getTexture(LLRender::SPECULAR_MAP)); + +				LLColor4 col = mat->getSpecularLightColor(); +				F32 spec = mat->getSpecularLightExponent()/255.f; + +				F32 env = mat->getEnvironmentIntensity()/255.f; + +				if (mat->getSpecularID().isNull()) +				{ +					env = te->getShiny()*0.25f; +					col.set(env,env,env,0); +					spec = env; +				} +		 +				BOOL fullbright = te->getFullbright(); + +				sVertexProgram->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, fullbright ? 1.f : 0.f); +				sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec); +				sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env); + +				if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +				{ +					sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f); +				} +				else +				{ +					sVertexProgram->setMinimumAlpha(0.f); +				} + +				for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) +				{ +					LLViewerTexture* tex = face->getTexture(i); +					if (tex) +					{ +						tex->addTextureStats(avatar->getPixelArea()); +					} +				} +			} +			else +			{ +				gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture()); +				sVertexProgram->setMinimumAlpha(0.f); +				if (normal_channel > -1) +				{ +					LLDrawPoolBump::bindBumpMap(face, normal_channel); +				}  			}  			if (face->mTextureMatrix) @@ -1545,6 +1780,11 @@ void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar)  	renderRigged(avatar, RIGGED_DEFERRED_BUMP);  } +void LLDrawPoolAvatar::renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass) +{ +	renderRigged(avatar, pass); +} +  static LLFastTimer::DeclareTimer FTM_RIGGED_VBO("Rigged VBO");  void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 69e3068858..7d0368a945 100755 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -75,7 +75,7 @@ public:  	/*virtual*/ void beginDeferredPass(S32 pass);  	/*virtual*/ void endDeferredPass(S32 pass);  	/*virtual*/ void renderDeferred(S32 pass); - +	  	/*virtual*/ S32 getNumPostDeferredPasses();  	/*virtual*/ void beginPostDeferredPass(S32 pass);  	/*virtual*/ void endPostDeferredPass(S32 pass); @@ -113,6 +113,8 @@ public:  	void beginRiggedFullbrightAlpha();  	void beginRiggedGlow();  	void beginDeferredRiggedAlpha(); +	void beginDeferredRiggedMaterial(S32 pass); +	void beginDeferredRiggedMaterialAlpha(S32 pass);  	void endRiggedSimple();  	void endRiggedFullbright(); @@ -122,6 +124,8 @@ public:  	void endRiggedFullbrightAlpha();  	void endRiggedGlow();  	void endDeferredRiggedAlpha(); +	void endDeferredRiggedMaterial(S32 pass); +	void endDeferredRiggedMaterialAlpha(S32 pass);  	void beginDeferredRiggedSimple();  	void beginDeferredRiggedBump(); @@ -146,10 +150,27 @@ public:  	void renderRiggedGlow(LLVOAvatar* avatar);  	void renderDeferredRiggedSimple(LLVOAvatar* avatar);  	void renderDeferredRiggedBump(LLVOAvatar* avatar); - +	void renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass); +	  	typedef enum  	{ -		RIGGED_SIMPLE = 0, +		RIGGED_MATERIAL=0, +		RIGGED_MATERIAL_ALPHA, +		RIGGED_MATERIAL_ALPHA_MASK, +		RIGGED_MATERIAL_ALPHA_EMISSIVE, +		RIGGED_SPECMAP, +		RIGGED_SPECMAP_BLEND, +		RIGGED_SPECMAP_MASK, +		RIGGED_SPECMAP_EMISSIVE, +		RIGGED_NORMMAP, +		RIGGED_NORMMAP_BLEND, +		RIGGED_NORMMAP_MASK, +		RIGGED_NORMMAP_EMISSIVE, +		RIGGED_NORMSPEC, +		RIGGED_NORMSPEC_BLEND, +		RIGGED_NORMSPEC_MASK, +		RIGGED_NORMSPEC_EMISSIVE, +		RIGGED_SIMPLE,  		RIGGED_FULLBRIGHT,  		RIGGED_SHINY,  		RIGGED_FULLBRIGHT_SHINY, @@ -164,6 +185,48 @@ public:  	typedef enum  	{ +		RIGGED_MATERIAL_MASK = +						LLVertexBuffer::MAP_VERTEX |  +						LLVertexBuffer::MAP_NORMAL |  +						LLVertexBuffer::MAP_TEXCOORD0 | +						LLVertexBuffer::MAP_COLOR | +						LLVertexBuffer::MAP_WEIGHT4, +		RIGGED_MATERIAL_ALPHA_VMASK = RIGGED_MATERIAL_MASK, +		RIGGED_MATERIAL_ALPHA_MASK_MASK = RIGGED_MATERIAL_MASK, +		RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK = RIGGED_MATERIAL_MASK, +		RIGGED_SPECMAP_VMASK = +						LLVertexBuffer::MAP_VERTEX |  +						LLVertexBuffer::MAP_NORMAL |  +						LLVertexBuffer::MAP_TEXCOORD0 | +						LLVertexBuffer::MAP_TEXCOORD2 | +						LLVertexBuffer::MAP_COLOR | +						LLVertexBuffer::MAP_WEIGHT4, +		RIGGED_SPECMAP_BLEND_MASK = RIGGED_SPECMAP_VMASK, +		RIGGED_SPECMAP_MASK_MASK = RIGGED_SPECMAP_VMASK, +		RIGGED_SPECMAP_EMISSIVE_MASK = RIGGED_SPECMAP_VMASK, +		RIGGED_NORMMAP_VMASK = +						LLVertexBuffer::MAP_VERTEX |  +						LLVertexBuffer::MAP_NORMAL |  +						LLVertexBuffer::MAP_TANGENT |  +						LLVertexBuffer::MAP_TEXCOORD0 | +						LLVertexBuffer::MAP_TEXCOORD1 | +						LLVertexBuffer::MAP_COLOR | +						LLVertexBuffer::MAP_WEIGHT4, +		RIGGED_NORMMAP_BLEND_MASK = RIGGED_NORMMAP_VMASK, +		RIGGED_NORMMAP_MASK_MASK = RIGGED_NORMMAP_VMASK, +		RIGGED_NORMMAP_EMISSIVE_MASK = RIGGED_NORMMAP_VMASK, +		RIGGED_NORMSPEC_VMASK = +						LLVertexBuffer::MAP_VERTEX |  +						LLVertexBuffer::MAP_NORMAL |  +						LLVertexBuffer::MAP_TANGENT |  +						LLVertexBuffer::MAP_TEXCOORD0 | +						LLVertexBuffer::MAP_TEXCOORD1 | +						LLVertexBuffer::MAP_TEXCOORD2 | +						LLVertexBuffer::MAP_COLOR | +						LLVertexBuffer::MAP_WEIGHT4, +		RIGGED_NORMSPEC_BLEND_MASK = RIGGED_NORMSPEC_VMASK, +		RIGGED_NORMSPEC_MASK_MASK = RIGGED_NORMSPEC_VMASK, +		RIGGED_NORMSPEC_EMISSIVE_MASK = RIGGED_NORMSPEC_VMASK,  		RIGGED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |   							 LLVertexBuffer::MAP_NORMAL |   							 LLVertexBuffer::MAP_TEXCOORD0 | @@ -184,7 +247,7 @@ public:  		RIGGED_DEFERRED_BUMP_MASK = LLVertexBuffer::MAP_VERTEX |   							 LLVertexBuffer::MAP_NORMAL |   							 LLVertexBuffer::MAP_TEXCOORD0 | -							 LLVertexBuffer::MAP_BINORMAL | +							 LLVertexBuffer::MAP_TANGENT |  							 LLVertexBuffer::MAP_COLOR |  							 LLVertexBuffer::MAP_WEIGHT4,  		RIGGED_DEFERRED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |  diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index e8d43c8631..155e289c9d 100755 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -153,7 +153,7 @@ void LLStandardBumpmap::addstandard()  		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label;  		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage =   			LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id));	 -		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::BOOST_BUMP) ; +		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::LOCAL) ;  		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL );  		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0) ;  		LLStandardBumpmap::sStandardBumpmapCount++; @@ -449,9 +449,6 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&  	LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;  	if( cube_map )  	{ -		cube_map->disable(); -		cube_map->restoreMatrix(); -  		if (!invisible && shader_level > 1)  		{  			shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); @@ -464,6 +461,8 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&  				}  			}  		} +		cube_map->disable(); +		cube_map->restoreMatrix();  	}  	if (!LLGLSLShader::sNoFixedFunction) @@ -514,7 +513,14 @@ void LLDrawPoolBump::beginFullbrightShiny()  	}  	else  	{ -		shader = &gObjectFullbrightShinyProgram; +		if (LLPipeline::sRenderDeferred) +		{ +			shader = &gDeferredFullbrightShinyProgram; +		} +		else +		{ +			shader = &gObjectFullbrightShinyProgram; +		}  	}  	LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; @@ -850,7 +856,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)  	LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);  	LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); -	U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; +	U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;  	for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)	  	{ @@ -915,6 +921,8 @@ void LLBumpImageList::init()  	llassert( mDarknessEntries.size() == 0 );  	LLStandardBumpmap::init(); + +	LLStandardBumpmap::restoreGL();  }  void LLBumpImageList::clear() diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp new file mode 100644 index 0000000000..08a36bddf1 --- /dev/null +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -0,0 +1,217 @@ +/**  + * @file lldrawpool.cpp + * @brief LLDrawPoolMaterials class implementation + * @author Jonathan "Geenz" Goodman + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "lldrawpoolmaterials.h" +#include "llviewershadermgr.h" +#include "pipeline.h" + +S32 diffuse_channel = -1; + +LLDrawPoolMaterials::LLDrawPoolMaterials() +:  LLRenderPass(LLDrawPool::POOL_MATERIALS) +{ +	 +} + +void LLDrawPoolMaterials::prerender() +{ +	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  +} + +S32 LLDrawPoolMaterials::getNumDeferredPasses() +{ +	return 12; +} + +void LLDrawPoolMaterials::beginDeferredPass(S32 pass) +{ +	U32 shader_idx[] =  +	{ +		0, //LLRenderPass::PASS_MATERIAL, +		//1, //LLRenderPass::PASS_MATERIAL_ALPHA, +		2, //LLRenderPass::PASS_MATERIAL_ALPHA_MASK, +		3, //LLRenderPass::PASS_MATERIAL_ALPHA_GLOW, +		4, //LLRenderPass::PASS_SPECMAP, +		//5, //LLRenderPass::PASS_SPECMAP_BLEND, +		6, //LLRenderPass::PASS_SPECMAP_MASK, +		7, //LLRenderPass::PASS_SPECMAP_GLOW, +		8, //LLRenderPass::PASS_NORMMAP, +		//9, //LLRenderPass::PASS_NORMMAP_BLEND, +		10, //LLRenderPass::PASS_NORMMAP_MASK, +		11, //LLRenderPass::PASS_NORMMAP_GLOW, +		12, //LLRenderPass::PASS_NORMSPEC, +		//13, //LLRenderPass::PASS_NORMSPEC_BLEND, +		14, //LLRenderPass::PASS_NORMSPEC_MASK, +		15, //LLRenderPass::PASS_NORMSPEC_GLOW, +	}; +	 +	mShader = &(gDeferredMaterialProgram[shader_idx[pass]]); +	mShader->bind(); + +	diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP); +		 +	LLFastTimer t(FTM_RENDER_MATERIALS); +} + +void LLDrawPoolMaterials::endDeferredPass(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_MATERIALS); + +	mShader->unbind(); + +	LLRenderPass::endRenderPass(pass); +} + +void LLDrawPoolMaterials::renderDeferred(S32 pass) +{ +	U32 type_list[] =  +	{ +		LLRenderPass::PASS_MATERIAL, +		//LLRenderPass::PASS_MATERIAL_ALPHA, +		LLRenderPass::PASS_MATERIAL_ALPHA_MASK, +		LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, +		LLRenderPass::PASS_SPECMAP, +		//LLRenderPass::PASS_SPECMAP_BLEND, +		LLRenderPass::PASS_SPECMAP_MASK, +		LLRenderPass::PASS_SPECMAP_EMISSIVE, +		LLRenderPass::PASS_NORMMAP, +		//LLRenderPass::PASS_NORMMAP_BLEND, +		LLRenderPass::PASS_NORMMAP_MASK, +		LLRenderPass::PASS_NORMMAP_EMISSIVE, +		LLRenderPass::PASS_NORMSPEC, +		//LLRenderPass::PASS_NORMSPEC_BLEND, +		LLRenderPass::PASS_NORMSPEC_MASK, +		LLRenderPass::PASS_NORMSPEC_EMISSIVE, +	}; + +	llassert(pass < sizeof(type_list)/sizeof(U32)); + +	U32 type = type_list[pass]; + +	U32 mask = mShader->mAttributeMask; + +	LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); +	LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); +	 +	for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) +	{ +		LLDrawInfo& params = **i; +		 +		mShader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]); +		mShader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity); +		 +		if (params.mNormalMap) +		{ +			params.mNormalMap->addTextureStats(params.mVSize); +			bindNormalMap(params.mNormalMap); +		} +		 +		if (params.mSpecularMap) +		{ +			params.mSpecularMap->addTextureStats(params.mVSize); +			bindSpecularMap(params.mSpecularMap); +		} +		 +		mShader->setMinimumAlpha(params.mAlphaMaskCutoff); +		mShader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f); + +		pushBatch(params, mask, TRUE); +	} +} + +void LLDrawPoolMaterials::bindSpecularMap(LLViewerTexture* tex) +{ +	mShader->bindTexture(LLShaderMgr::SPECULAR_MAP, tex); +} + +void LLDrawPoolMaterials::bindNormalMap(LLViewerTexture* tex) +{ +	mShader->bindTexture(LLShaderMgr::BUMP_MAP, tex); +} + +void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) +{ +	applyModelMatrix(params); +	 +	bool tex_setup = false; +	 +	if (batch_textures && params.mTextureList.size() > 1) +	{ +		for (U32 i = 0; i < params.mTextureList.size(); ++i) +		{ +			if (params.mTextureList[i].notNull()) +			{ +				gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); +			} +		} +	} +	else +	{ //not batching textures or batch has only 1 texture -- might need a texture matrix +		if (params.mTextureMatrix) +		{ +			//if (mShiny) +			{ +				gGL.getTexUnit(0)->activate(); +				gGL.matrixMode(LLRender::MM_TEXTURE); +			} +			 +			gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); +			gPipeline.mTextureMatrixOps++; +			 +			tex_setup = true; +		} +		 +		if (mVertexShaderLevel > 1 && texture) +		{ +			if (params.mTexture.notNull()) +			{ +				gGL.getTexUnit(diffuse_channel)->bind(params.mTexture); +				params.mTexture->addTextureStats(params.mVSize); +			} +			else +			{ +				gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); +			} +		} +	} +	 +	if (params.mGroup) +	{ +		params.mGroup->rebuildMesh(); +	} +	params.mVertexBuffer->setBuffer(mask); +	params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); +	gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); +	if (tex_setup) +	{ +		gGL.getTexUnit(0)->activate(); +		gGL.loadIdentity(); +		gGL.matrixMode(LLRender::MM_MODELVIEW); +	} +} diff --git a/indra/newview/lldrawpoolmaterials.h b/indra/newview/lldrawpoolmaterials.h new file mode 100644 index 0000000000..eae1aba87c --- /dev/null +++ b/indra/newview/lldrawpoolmaterials.h @@ -0,0 +1,75 @@ +/**  + * @file lldrawpoolmaterials.h + * @brief LLDrawPoolMaterials class definition + * @author Jonathan "Geenz" Goodman + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLDRAWPOOLMATERIALS_H +#define LL_LLDRAWPOOLMATERIALS_H + +#include "v4coloru.h" +#include "v2math.h" +#include "v3math.h" +#include "llvertexbuffer.h" +#include "lldrawpool.h" + +class LLViewerTexture; +class LLDrawInfo; +class LLGLSLShader; + +class LLDrawPoolMaterials : public LLRenderPass +{ +	LLGLSLShader *mShader; +public: +	LLDrawPoolMaterials(); +	 +	enum +	{ +		VERTEX_DATA_MASK =	LLVertexBuffer::MAP_VERTEX | +		LLVertexBuffer::MAP_NORMAL | +		LLVertexBuffer::MAP_TEXCOORD0 | +		LLVertexBuffer::MAP_TEXCOORD1 | +		LLVertexBuffer::MAP_TEXCOORD2 | +		LLVertexBuffer::MAP_COLOR | +		LLVertexBuffer::MAP_TANGENT +	}; +	 +	/*virtual*/ U32 getVertexDataMask() { return VERTEX_DATA_MASK; } +	 +	/*virtual*/ void render(S32 pass = 0) { } +	/*virtual*/ S32	 getNumPasses() {return 0;} +	/*virtual*/ void prerender(); +	 +	/*virtual*/ S32 getNumDeferredPasses(); +	/*virtual*/ void beginDeferredPass(S32 pass); +	/*virtual*/ void endDeferredPass(S32 pass); +	/*virtual*/ void renderDeferred(S32 pass); +	 +	void bindSpecularMap(LLViewerTexture* tex); +	void bindNormalMap(LLViewerTexture* tex); +	 +	/*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE); +}; + +#endif //LL_LLDRAWPOOLMATERIALS_H diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 6e0ea78af2..2cf9d833c6 100755 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -47,6 +47,7 @@ static LLFastTimer::DeclareTimer FTM_RENDER_GRASS_DEFERRED("Deferred Grass");  void LLDrawPoolGlow::beginPostDeferredPass(S32 pass)  {  	gDeferredEmissiveProgram.bind(); +	gDeferredEmissiveProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);  }  static LLFastTimer::DeclareTimer FTM_RENDER_GLOW_PUSH("Glow Push"); @@ -110,6 +111,7 @@ void LLDrawPoolGlow::render(S32 pass)  	LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;  	shader->bind(); +	shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);  	LLGLDepthTest depth(GL_TRUE, GL_FALSE);  	gGL.setColorMask(false, true); @@ -198,7 +200,11 @@ void LLDrawPoolSimple::render(S32 pass)  			if (LLPipeline::sRenderDeferred)  			{ //if deferred rendering is enabled, bump faces aren't registered as simple  				//render bump faces here as simple so bump faces will appear under water -				pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE); +				pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE);			 +				pushBatches(LLRenderPass::PASS_MATERIAL, mask, TRUE, TRUE); +				pushBatches(LLRenderPass::PASS_SPECMAP, mask, TRUE, TRUE); +				pushBatches(LLRenderPass::PASS_NORMMAP, mask, TRUE, TRUE); +				pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE);		  			}  		}  		else @@ -210,6 +216,169 @@ void LLDrawPoolSimple::render(S32 pass)  	}  } + + + + + + + + + +static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK("Alpha Mask"); + +LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() : +	LLRenderPass(POOL_ALPHA_MASK) +{ +} + +void LLDrawPoolAlphaMask::prerender() +{ +	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); +} + +void LLDrawPoolAlphaMask::beginRenderPass(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_ALPHA_MASK); + +	if (LLPipeline::sUnderWaterRender) +	{ +		simple_shader = &gObjectSimpleWaterAlphaMaskProgram; +	} +	else +	{ +		simple_shader = &gObjectSimpleAlphaMaskProgram; +	} + +	if (mVertexShaderLevel > 0) +	{ +		simple_shader->bind(); +	} +	else  +	{ +		// don't use shaders! +		if (gGLManager.mHasShaderObjects) +		{ +			LLGLSLShader::bindNoShader(); +		}		 +	} +} + +void LLDrawPoolAlphaMask::endRenderPass(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_ALPHA_MASK); +	stop_glerror(); +	LLRenderPass::endRenderPass(pass); +	stop_glerror(); +	if (mVertexShaderLevel > 0) +	{ +		simple_shader->unbind(); +	} +} + +void LLDrawPoolAlphaMask::render(S32 pass) +{ +	LLGLDisable blend(GL_BLEND); +	LLFastTimer t(FTM_RENDER_ALPHA_MASK); +	 +	if (mVertexShaderLevel > 0) +	{ +		simple_shader->bind(); +		simple_shader->setMinimumAlpha(0.33f); + +		pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +		pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +		pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +		pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +		pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +	} +	else +	{ +		LLGLEnable test(GL_ALPHA_TEST); +		pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE); +		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK +	} +} + +LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() : +	LLRenderPass(POOL_FULLBRIGHT_ALPHA_MASK) +{ +} + +void LLDrawPoolFullbrightAlphaMask::prerender() +{ +	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); +} + +void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_ALPHA_MASK); + +	if (LLPipeline::sUnderWaterRender) +	{ +		simple_shader = &gObjectFullbrightWaterAlphaMaskProgram; +	} +	else +	{ +		simple_shader = &gObjectFullbrightAlphaMaskProgram; +	} + +	if (mVertexShaderLevel > 0) +	{ +		simple_shader->bind(); +	} +	else  +	{ +		// don't use shaders! +		if (gGLManager.mHasShaderObjects) +		{ +			LLGLSLShader::bindNoShader(); +		}		 +	} +} + +void LLDrawPoolFullbrightAlphaMask::endRenderPass(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_ALPHA_MASK); +	stop_glerror(); +	LLRenderPass::endRenderPass(pass); +	stop_glerror(); +	if (mVertexShaderLevel > 0) +	{ +		simple_shader->unbind(); +	} +} + +void LLDrawPoolFullbrightAlphaMask::render(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_ALPHA_MASK); + +	if (mVertexShaderLevel > 0) +	{ +		if (simple_shader) +		{ +			simple_shader->bind(); +			simple_shader->setMinimumAlpha(0.33f); +			if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred) +			{ +				simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); +			} else { +				simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +			} +		} +		pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +		//LLGLSLShader::bindNoShader(); +	} +	else +	{ +		LLGLEnable test(GL_ALPHA_TEST); +		gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); +		pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE); +		gPipeline.enableLightsDynamic(); +		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK +	} +} +  //===============================  //DEFERRED IMPLEMENTATION  //=============================== @@ -239,6 +408,28 @@ void LLDrawPoolSimple::renderDeferred(S32 pass)  	}  } +static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK_DEFERRED("Deferred Alpha Mask"); + +void LLDrawPoolAlphaMask::beginDeferredPass(S32 pass) +{ +	 +} + +void LLDrawPoolAlphaMask::endDeferredPass(S32 pass) +{ +	 +} + +void LLDrawPoolAlphaMask::renderDeferred(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_ALPHA_MASK_DEFERRED); +	gDeferredDiffuseAlphaMaskProgram.bind(); +	gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f); +	pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +	gDeferredDiffuseAlphaMaskProgram.unbind();			 +} + +  // grass drawpool  LLDrawPoolGrass::LLDrawPoolGrass() :   LLRenderPass(POOL_GRASS) @@ -403,14 +594,24 @@ void LLDrawPoolFullbright::render(S32 pass)  	{  		fullbright_shader->bind();  		fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f); +		fullbright_shader->uniform1f(LLViewerShaderMgr::TEXTURE_GAMMA, 1.f); +  		U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;  		pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); +		pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask, TRUE, TRUE); +		pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask, TRUE, TRUE); +		pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask, TRUE, TRUE); +		pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask, TRUE, TRUE);  	}  	else  	{  		gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));  		U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR;  		renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask); +		pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask); +		pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask); +		pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask); +		pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask);  	}  	stop_glerror(); @@ -421,3 +622,32 @@ S32 LLDrawPoolFullbright::getNumPasses()  	return 1;  } + +void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass) +{ +	gObjectFullbrightAlphaMaskProgram.bind(); +	if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred) +	{ +		gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); +	}  +	else  +	{ +		gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +	} +} + +void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_FULLBRIGHT); +	LLGLDisable blend(GL_BLEND); +	U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; +	pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE); +} + +void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass) +{ +	gObjectFullbrightAlphaMaskProgram.unbind(); +	LLRenderPass::endRenderPass(pass); +} + + diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h index bd62bc7502..608ad9e1eb 100755 --- a/indra/newview/lldrawpoolsimple.h +++ b/indra/newview/lldrawpoolsimple.h @@ -84,6 +84,59 @@ public:  	/*virtual*/ void prerender();  }; +class LLDrawPoolAlphaMask : public LLRenderPass +{ +public: +	enum +	{ +		VERTEX_DATA_MASK =	LLVertexBuffer::MAP_VERTEX | +							LLVertexBuffer::MAP_NORMAL | +							LLVertexBuffer::MAP_TEXCOORD0 | +							LLVertexBuffer::MAP_COLOR +	}; +	virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + +	LLDrawPoolAlphaMask(); + +	/*virtual*/ S32 getNumDeferredPasses() { return 1; } +	/*virtual*/ void beginDeferredPass(S32 pass); +	/*virtual*/ void endDeferredPass(S32 pass); +	/*virtual*/ void renderDeferred(S32 pass); + +	/*virtual*/ S32	 getNumPasses() { return 1; } +	/*virtual*/ void beginRenderPass(S32 pass); +	/*virtual*/ void endRenderPass(S32 pass); +	/*virtual*/ void render(S32 pass = 0); +	/*virtual*/ void prerender(); + +}; + +class LLDrawPoolFullbrightAlphaMask : public LLRenderPass +{ +public: +	enum +	{ +		VERTEX_DATA_MASK =	LLVertexBuffer::MAP_VERTEX | +							LLVertexBuffer::MAP_TEXCOORD0 | +							LLVertexBuffer::MAP_COLOR +	}; +	virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + +	LLDrawPoolFullbrightAlphaMask(); +	 +	/*virtual*/ S32 getNumPostDeferredPasses() { return 1; } +	/*virtual*/ void beginPostDeferredPass(S32 pass); +	/*virtual*/ void endPostDeferredPass(S32 pass); +	/*virtual*/ void renderPostDeferred(S32 pass); + +	/*virtual*/ S32	 getNumPasses() { return 1; } +	/*virtual*/ void beginRenderPass(S32 pass); +	/*virtual*/ void endRenderPass(S32 pass); +	/*virtual*/ void render(S32 pass = 0); +	/*virtual*/ void prerender(); +}; + +  class LLDrawPoolFullbright : public LLRenderPass  {  public: diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index e0f7223a8c..c1630318e8 100755 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -213,7 +213,7 @@ namespace  		{  			llwarns << "LLEventPollResponder error <" << mCount   					<< "> [status:" << status << "]: " << content -					<< (mDone ? " -- done" : "") << llendl; +					<<	(mDone ? " -- done"	: "") << llendl;  			stop();  			// At this point we have given up and the viewer will not receive HTTP messages from the simulator. diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 281f852b0a..f021f4ed0f 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -51,7 +51,7 @@  #include "llviewerregion.h"  #include "llviewerwindow.h"  #include "llviewershadermgr.h" - +#include "llviewertexture.h"  #define LL_MAX_INDICES_COUNT 1000000 @@ -106,41 +106,6 @@ void planarProjection(LLVector2 &tc, const LLVector4a& normal,  	tc.mV[0] = 1.0f+((binormal.dot3(vec).getF32())*2 - 0.5f);  } -void sphericalProjection(LLVector2 &tc, const LLVector4a& normal, -						 const LLVector4a &mCenter, const LLVector4a& vec) -{	//BROKEN -	/*tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/3.14159f; -	 -	tc.mV[1] = acosf(vd.mNormal * LLVector3(0,0,1))/6.284f; -	if (vd.mNormal.mV[1] > 0) -	{ -		tc.mV[1] = 1.0f-tc.mV[1]; -	}*/ -} - -void cylindricalProjection(LLVector2 &tc, const LLVector4a& normal, const LLVector4a &mCenter, const LLVector4a& vec) -{	//BROKEN -	/*LLVector3 binormal; -	float d = vd.mNormal * LLVector3(1,0,0); -	if (d >= 0.5f || d <= -0.5f) -	{ -		binormal = LLVector3(0,1,0); -	} -	else{ -		binormal = LLVector3(1,0,0); -	} -	LLVector3 tangent = binormal % vd.mNormal; - -	tc.mV[1] = -((tangent*vec)*2 - 0.5f); - -	tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/6.284f; - -	if (vd.mNormal.mV[1] < 0) -	{ -		tc.mV[0] = 1.0f-tc.mV[0]; -	}*/ -} -  ////////////////////  //  // LLFace implementation @@ -167,8 +132,12 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)  	//special value to indicate uninitialized position  	mIndicesIndex	= 0xFFFFFFFF; -	mIndexInTex = 0; -	mTexture		= NULL; +	for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) +	{ +		mIndexInTex[i] = 0; +		mTexture[i] = NULL; +	} +  	mTEOffset		= -1;  	mTextureIndex = 255; @@ -185,8 +154,6 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)  	mImportanceToCamera = 0.f ;  	mBoundingSphereRadius = 0.0f ; -	mAtlasInfop = NULL ; -	mUsingAtlas  = FALSE ;  	mHasMedia = FALSE ;  } @@ -197,9 +164,12 @@ void LLFace::destroy()  		gPipeline.checkReferences(this);  	} -	if(mTexture.notNull()) +	for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)  	{ -		mTexture->removeFace(this) ; +		if(mTexture[i].notNull()) +		{ +			mTexture[i]->removeFace(i, this) ; +		}  	}  	if (isState(LLFace::PARTICLE)) @@ -239,8 +209,7 @@ void LLFace::destroy()  	}  	setDrawInfo(NULL); -	removeAtlas(); -		 +			  	mDrawablep = NULL;  	mVObjp = NULL;  } @@ -293,48 +262,76 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)  	setTexture(texturep) ;  } -void LLFace::setTexture(LLViewerTexture* tex)  +void LLFace::setTexture(U32 ch, LLViewerTexture* tex)   { -	if(mTexture == tex) +	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + +	if(mTexture[ch] == tex)  	{  		return ;  	} -	if(mTexture.notNull()) +	if(mTexture[ch].notNull())  	{ -		mTexture->removeFace(this) ; -		removeAtlas() ; +		mTexture[ch]->removeFace(ch, this) ;  	}	  	if(tex)  	{ -		tex->addFace(this) ; +		tex->addFace(ch, this) ;  	} -	mTexture = tex ; +	mTexture[ch] = tex ; +} + +void LLFace::setTexture(LLViewerTexture* tex)  +{ +	setDiffuseMap(tex); +} + +void LLFace::setDiffuseMap(LLViewerTexture* tex) +{ +	setTexture(LLRender::DIFFUSE_MAP, tex); +} + +void LLFace::setNormalMap(LLViewerTexture* tex) +{ +	setTexture(LLRender::NORMAL_MAP, tex); +} + +void LLFace::setSpecularMap(LLViewerTexture* tex) +{ +	setTexture(LLRender::SPECULAR_MAP, tex);  }  void LLFace::dirtyTexture()  {  	LLDrawable* drawablep = getDrawable(); -	if (mVObjp.notNull() && mVObjp->getVolume() &&  -		mTexture.notNull() && mTexture->getComponents() == 4) -	{ //dirty texture on an alpha object should be treated as an LoD update -		LLVOVolume* vobj = drawablep->getVOVolume(); -		if (vobj) +	if (mVObjp.notNull() && mVObjp->getVolume()) +	{ +		for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)  		{ -			vobj->mLODChanged = TRUE; +			if (mTexture[ch].notNull() && mTexture[ch]->getComponents() == 4) +			{ //dirty texture on an alpha object should be treated as an LoD update +				LLVOVolume* vobj = drawablep->getVOVolume(); +				if (vobj) +				{ +					vobj->mLODChanged = TRUE; +				} +				gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE); +			}  		} -		gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE); -	}		 +	}  	gPipeline.markTextured(drawablep);  } -void LLFace::switchTexture(LLViewerTexture* new_texture) +void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)  { -	if(mTexture == new_texture) +	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); +	 +	if(mTexture[ch] == new_texture)  	{  		return ;  	} @@ -344,10 +341,17 @@ void LLFace::switchTexture(LLViewerTexture* new_texture)  		llerrs << "Can not switch to a null texture." << llendl;  		return;  	} -	new_texture->addTextureStats(mTexture->getMaxVirtualSize()) ; -	getViewerObject()->changeTEImage(mTEOffset, new_texture) ; -	setTexture(new_texture) ;	 +	llassert(mTexture[ch].notNull()); + +	new_texture->addTextureStats(mTexture[ch]->getMaxVirtualSize()) ; + +	if (ch == LLRender::DIFFUSE_MAP) +	{ +		getViewerObject()->changeTEImage(mTEOffset, new_texture) ; +	} + +	setTexture(ch, new_texture) ;	  	dirtyTexture();  } @@ -543,7 +547,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);  		} @@ -811,6 +817,12 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  			size.mul(scale);  		} +		// Catch potential badness from normalization before it happens +		// +		llassert(mat_normal.mMatrix[0].isFinite3() && (mat_normal.mMatrix[0].dot3(mat_normal.mMatrix[0]).getF32() > F_APPROXIMATELY_ZERO)); +		llassert(mat_normal.mMatrix[1].isFinite3() && (mat_normal.mMatrix[1].dot3(mat_normal.mMatrix[1]).getF32() > F_APPROXIMATELY_ZERO)); +		llassert(mat_normal.mMatrix[2].isFinite3() && (mat_normal.mMatrix[2].dot3(mat_normal.mMatrix[2]).getF32() > F_APPROXIMATELY_ZERO)); +  		mat_normal.mMatrix[0].normalize3fast();  		mat_normal.mMatrix[1].normalize3fast();  		mat_normal.mMatrix[2].normalize3fast(); @@ -896,7 +908,7 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  // integrated with getGeometryVolume() for its texture coordinate  // generation - but i'll leave that to someone more familiar  // with the implications. -LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal) +LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal)  {  	LLVector2 tc = surface_coord; @@ -916,7 +928,9 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,  		LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter);  		LLVector4a volume_position; -		volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(position).mV); +		LLVector3 v_position(position.getF32ptr()); + +		volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(v_position).mV);  		if (!mDrawablep->getVOVolume()->isVolumeGlobal())  		{ @@ -926,23 +940,14 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,  		}  		LLVector4a volume_normal; -		volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(normal).mV); +		LLVector3 v_normal(normal.getF32ptr()); +		volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(v_normal).mV);  		volume_normal.normalize3fast(); -		switch (texgen) +		if (texgen == LLTextureEntry::TEX_GEN_PLANAR)  		{ -		case LLTextureEntry::TEX_GEN_PLANAR:  			planarProjection(tc, volume_normal, center, volume_position); -			break; -		case LLTextureEntry::TEX_GEN_SPHERICAL: -			sphericalProjection(tc, volume_normal, center, volume_position); -			break; -		case LLTextureEntry::TEX_GEN_CYLINDRICAL: -			cylindricalProjection(tc, volume_normal, center, volume_position); -			break; -		default: -			break; -		}		 +		}  	}  	if (mTextureMatrix)	// if we have a texture matrix, use it @@ -969,7 +974,12 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po  	const LLMatrix4& vol_mat = getWorldMatrix();  	const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset);  	const LLVector4a& normal4a = vf.mNormals[0]; -	const LLVector4a& binormal4a = vf.mBinormals[0]; +	const LLVector4a& tangent = vf.mTangents[0]; + +	LLVector4a binormal4a; +	binormal4a.setCross3(normal4a, tangent); +	binormal4a.mul(tangent.getF32ptr()[3]); +  	LLVector2 projected_binormal;  	planarProjection(projected_binormal, normal4a, *vf.mCenter, binormal4a);  	projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform() @@ -1059,6 +1069,12 @@ bool LLFace::canRenderAsMask()  		return false;  	} +	LLMaterial* mat = te->getMaterialParams(); +	if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) +	{ +		return false; +	} +	  	if ((te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha  		(te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask  		getTexture()->getIsAlphaMask()) // texture actually qualifies for masking (lazily recalculated but expensive) @@ -1091,7 +1107,7 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)  {  	LLFastTimer t(FTM_FACE_GEOM_VOLUME);  	U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | -				LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL; +				LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL;  	if (vf.mWeights)  	{ @@ -1104,11 +1120,11 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)  	buff->allocateBuffer(vf.mNumVertices, 0, true);  	LLStrider<LLVector4a> f_vert; -	LLStrider<LLVector3> f_binorm; +	LLStrider<LLVector4a> f_tangent;  	LLStrider<LLVector3> f_norm;  	LLStrider<LLVector2> f_tc; -	buff->getBinormalStrider(f_binorm); +	buff->getTangentStrider(f_tangent);  	buff->getVertexStrider(f_vert);  	buff->getNormalStrider(f_norm);  	buff->getTexCoord0Strider(f_tc); @@ -1116,7 +1132,7 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)  	for (U32 i = 0; i < vf.mNumVertices; ++i)  	{  		*f_vert++ = vf.mPositions[i]; -		(*f_binorm++).set(vf.mBinormals[i].getF32ptr()); +		*f_tangent++ = vf.mTangents[i];  		*f_tc++ = vf.mTexCoords[i];  		(*f_norm++).set(vf.mNormals[i].getF32ptr());  	} @@ -1158,7 +1174,7 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TEXTURE("Texture");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_COLOR("Color");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_EMISSIVE("Emissive");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights"); -static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TANGENT("Binormal");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX("Index");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX_TAIL("Tail");  static LLFastTimer::DeclareTimer FTM_FACE_POSITION_STORE("Pos"); @@ -1219,11 +1235,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	}  	LLStrider<LLVector3> vert; -	LLStrider<LLVector2> tex_coords; +	LLStrider<LLVector2> tex_coords0; +	LLStrider<LLVector2> tex_coords1;  	LLStrider<LLVector2> tex_coords2;  	LLStrider<LLVector3> norm;  	LLStrider<LLColor4U> colors; -	LLStrider<LLVector3> binorm; +	LLStrider<LLVector3> tangent;  	LLStrider<U16> indicesp;  	LLStrider<LLVector4> wght; @@ -1245,33 +1262,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	bool rebuild_emissive = rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE);  	bool rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD);  	bool rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); -	bool rebuild_binormal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_BINORMAL); +	bool rebuild_tangent = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TANGENT);  	bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4);  	const LLTextureEntry *tep = mVObjp->getTE(f);  	const U8 bump_code = tep ? tep->getBumpmap() : 0; -	F32 tcoord_xoffset = 0.f ; -	F32 tcoord_yoffset = 0.f ; -	F32 tcoord_xscale = 1.f ; -	F32 tcoord_yscale = 1.f ; -	BOOL in_atlas = FALSE ; - -	if (rebuild_tcoord) -	{ -		in_atlas = isAtlasInUse() ; -		if(in_atlas) -		{ -			const LLVector2* tmp = getTexCoordOffset() ; -			tcoord_xoffset = tmp->mV[0] ;  -			tcoord_yoffset = tmp->mV[1] ; - -			tmp = getTexCoordScale() ; -			tcoord_xscale = tmp->mV[0] ;  -			tcoord_yscale = tmp->mV[1] ;	 -		} -	} -	  	BOOL is_static = mDrawablep->isStatic();  	BOOL is_global = is_static; @@ -1289,19 +1285,41 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	LLColor4U color = tep->getColor();  	if (rebuild_color) -	{ -		if (tep) +	{ //decide if shiny goes in alpha channel of color +		if (tep &&  +			getPoolType() != LLDrawPool::POOL_ALPHA)  // <--- alpha channel MUST contain transparency, not shiny  		{ -			GLfloat alpha[4] = -			{ -				0.00f, -				0.25f, -				0.5f, -				0.75f -			}; +			LLMaterial* mat = tep->getMaterialParams().get(); +						 +			bool shiny_in_alpha = false; -			if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || (LLPipeline::sRenderBump && tep->getShiny()))) +			if (LLPipeline::sRenderDeferred) +			{ //store shiny in alpha if we don't have a specular map +				if  (!mat || mat->getSpecularID().isNull()) +				{ +					shiny_in_alpha = true; +				} +			} +			else  			{ +				if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +				{ +					shiny_in_alpha = true; +				} +			} + +			if (shiny_in_alpha) +			{ + +				GLfloat alpha[4] = +				{ +					0.00f, +					0.25f, +					0.5f, +					0.75f +				}; +			 +				llassert(tep->getShiny() <= 3);  				color.mV[3] = U8 (alpha[tep->getShiny()] * 255);  			}  		} @@ -1392,7 +1410,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)  		{ -			mVObjp->getVolume()->genBinormals(f); +			mVObjp->getVolume()->genTangents(f);  			LLFace::cacheFaceInVRAM(vf);  			buff = (LLVertexBuffer*) vf.mVertexBuffer.get();  		}		 @@ -1477,15 +1495,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			glEndTransformFeedback();  		} -		if (rebuild_binormal) +		if (rebuild_tangent)  		{ -			LLFastTimer t(FTM_FACE_GEOM_BINORMAL); -			gTransformBinormalProgram.bind(); +			LLFastTimer t(FTM_FACE_GEOM_TANGENT); +			gTransformTangentProgram.bind(); -			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount); +			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount);  			glBeginTransformFeedback(GL_POINTS); -			buff->setBuffer(LLVertexBuffer::MAP_BINORMAL); +			buff->setBuffer(LLVertexBuffer::MAP_TANGENT);  			push_for_transform(buff, vf.mNumVertices, mGeomCount);  			glEndTransformFeedback();  		} @@ -1547,7 +1565,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			if (bump_code)  			{ -				mVObjp->getVolume()->genBinormals(f); +				mVObjp->getVolume()->genTangents(f);  				F32 offset_multiple;   				switch( bump_code )  				{ @@ -1556,11 +1574,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  					break;  					case BE_BRIGHTNESS:  					case BE_DARKNESS: -					if( mTexture.notNull() && mTexture->hasGLTexture()) +					if( mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->hasGLTexture())  					{  						// Offset by approximately one texel -						S32 cur_discard = mTexture->getDiscardLevel(); -						S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() ); +						S32 cur_discard = mTexture[LLRender::DIFFUSE_MAP]->getDiscardLevel(); +						S32 max_size = llmax( mTexture[LLRender::DIFFUSE_MAP]->getWidth(), mTexture[LLRender::DIFFUSE_MAP]->getHeight() );  						max_size <<= cur_discard;  						const F32 ARTIFICIAL_OFFSET = 2.f;  						offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size; @@ -1596,16 +1614,23 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			U8 texgen = getTextureEntry()->getTexGen();  			if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)  			{ //planar texgen needs binormals -				mVObjp->getVolume()->genBinormals(f); +				mVObjp->getVolume()->genTangents(f);  			}  			U8 tex_mode = 0; +			bool tex_anim = false; + +			LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;	 +			tex_mode = vobj->mTexAnimMode; + +			if (vobj->mTextureAnimp) +			{ //texture animation is in play, override specular and normal map tex coords with diffuse texcoords +				tex_anim = true; +			} +  			if (isState(TEXTURE_ANIM))  			{ -				LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;	 -				tex_mode = vobj->mTexAnimMode; -  				if (!tex_mode)  				{  					clearState(TEXTURE_ANIM); @@ -1620,7 +1645,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  					do_xform = false;  				} - +				  				if (getVirtualSize() >= MIN_TEX_ANIM_SIZE)  				{ //don't override texture transform during tc bake  					tex_mode = 0; @@ -1630,12 +1655,21 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			LLVector4a scalea;  			scalea.load3(scale.mV); +			LLMaterial* mat = tep->getMaterialParams().get(); +  			bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); -			bool do_tex_mat = tex_mode && mTextureMatrix; -			if (!in_atlas && !do_bump) -			{ //not in atlas or not bump mapped, might be able to do a cheap update -				mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount); +			if (mat && !do_bump) +			{ +				do_bump  = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1) +					     || mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2); +			} +			 +			bool do_tex_mat = tex_mode && mTextureMatrix; +						 +			if (!do_bump) +			{ //not bump mapped, might be able to do a cheap update +				mVertexBuffer->getTexCoord0Strider(tex_coords0, mGeomIndex, mGeomCount);  				if (texgen != LLTextureEntry::TEX_GEN_PLANAR)  				{ @@ -1646,12 +1680,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  						{  							LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM);  							S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; -							LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, tc_size); +							LLVector4a::memcpyNonAliased16((F32*) tex_coords0.get(), (F32*) vf.mTexCoords, tc_size);  						}  						else  						{  							LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM); -							F32* dst = (F32*) tex_coords.get(); +							F32* dst = (F32*) tex_coords0.get();  							LLVector4a* src = (LLVector4a*) vf.mTexCoords;  							LLVector4a trans; @@ -1686,7 +1720,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  						}  					}  					else -					{ //do tex mat, no texgen, no atlas, no bump +					{ //do tex mat, no texgen, no bump  						for (S32 i = 0; i < num_vertices; i++)  						{	  							LLVector2 tc(vf.mTexCoords[i]); @@ -1697,12 +1731,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							tmp = tmp * *mTextureMatrix;  							tc.mV[0] = tmp.mV[0];  							tc.mV[1] = tmp.mV[1]; -							*tex_coords++ = tc;	 +							*tex_coords0++ = tc;	  						}  					}  				}  				else -				{ //no bump, no atlas, tex gen planar +				{ //no bump, tex gen planar  					LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR);  					if (do_tex_mat)  					{ @@ -1720,7 +1754,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							tc.mV[0] = tmp.mV[0];  							tc.mV[1] = tmp.mV[1]; -							*tex_coords++ = tc;	 +							*tex_coords0++ = tc;	  						}  					}  					else @@ -1736,7 +1770,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							xform(tc, cos_ang, sin_ang, os, ot, ms, mt); -							*tex_coords++ = tc;	 +							*tex_coords0++ = tc;	  						}  					}  				} @@ -1747,145 +1781,104 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  				}  			}  			else -			{ //either bump mapped or in atlas, just do the whole expensive loop +			{ //bump mapped or has material, just do the whole expensive loop  				LLFastTimer t(FTM_FACE_TEX_DEFAULT); -				mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range); - -				std::vector<LLVector2> bump_tc; -		 -				for (S32 i = 0; i < num_vertices; i++) -				{	 -					LLVector2 tc(vf.mTexCoords[i]); -			 -					LLVector4a& norm = vf.mNormals[i]; -				 -					LLVector4a& center = *(vf.mCenter); -		    -					if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) -					{ -						LLVector4a vec = vf.mPositions[i]; -						vec.mul(scalea); +				std::vector<LLVector2> bump_tc; -						switch (texgen) -						{ -							case LLTextureEntry::TEX_GEN_PLANAR: -								planarProjection(tc, norm, center, vec); -								break; -							case LLTextureEntry::TEX_GEN_SPHERICAL: -								sphericalProjection(tc, norm, center, vec); -								break; -							case LLTextureEntry::TEX_GEN_CYLINDRICAL: -								cylindricalProjection(tc, norm, center, vec); -								break; -							default: -								break; -						}		 -					} +				if (mat && !mat->getNormalID().isNull()) +				{ //writing out normal and specular texture coordinates, not bump offsets +					do_bump = false; +				} -					if (tex_mode && mTextureMatrix) -					{ -						LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); -						tmp = tmp * *mTextureMatrix; -						tc.mV[0] = tmp.mV[0]; -						tc.mV[1] = tmp.mV[1]; -					} -					else -					{ -						xform(tc, cos_ang, sin_ang, os, ot, ms, mt); -					} +				LLStrider<LLVector2> dst; -					if(in_atlas) +				for (U32 ch = 0; ch < 3; ++ch) +				{ +					switch (ch)  					{ -						// -						//manually calculate tex-coord per vertex for varying address modes. -						//should be removed if shader can handle this. -						// - -						S32 int_part = 0 ; -						switch(mTexture->getAddressMode()) -						{ -						case LLTexUnit::TAM_CLAMP: -							if(tc.mV[0] < 0.f) -							{ -								tc.mV[0] = 0.f ; -							} -							else if(tc.mV[0] > 1.f) -							{ -								tc.mV[0] = 1.f; -							} - -							if(tc.mV[1] < 0.f) -							{ -								tc.mV[1] = 0.f ; -							} -							else if(tc.mV[1] > 1.f) -							{ -								tc.mV[1] = 1.f; -							} +						case 0:  +							mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount, map_range);   							break; -						case LLTexUnit::TAM_MIRROR: -							if(tc.mV[0] < 0.f) -							{ -								tc.mV[0] = -tc.mV[0] ; -							} -							int_part = (S32)tc.mV[0] ; -							if(int_part & 1) //odd number -							{ -								tc.mV[0] = int_part + 1 - tc.mV[0] ; -							} -							else //even number +						case 1: +							if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))  							{ -								tc.mV[0] -= int_part ; -							} +								mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount, map_range); +								if (mat && !tex_anim) +								{ +									r  = mat->getNormalRotation(); +									mat->getNormalOffset(os, ot); +									mat->getNormalRepeat(ms, mt); -							if(tc.mV[1] < 0.f) -							{ -								tc.mV[1] = -tc.mV[1] ; -							} -							int_part = (S32)tc.mV[1] ; -							if(int_part & 1) //odd number -							{ -								tc.mV[1] = int_part + 1 - tc.mV[1] ; +									cos_ang = cos(r); +									sin_ang = sin(r); + +								}  							} -							else //even number +							else  							{ -								tc.mV[1] -= int_part ; +								continue;  							}  							break; -						case LLTexUnit::TAM_WRAP: -							if(tc.mV[0] > 1.f) -								tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ; -							else if(tc.mV[0] < -1.f) -								tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ; - -							if(tc.mV[1] > 1.f) -								tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ; -							else if(tc.mV[1] < -1.f) -								tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ; - -							if(tc.mV[0] < 0.f) +						case 2: +							if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2))  							{ -								tc.mV[0] = 1.0f + tc.mV[0] ; +								mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount, map_range); +								if (mat && !tex_anim) +								{ +									r  = mat->getSpecularRotation(); +									mat->getSpecularOffset(os, ot); +									mat->getSpecularRepeat(ms, mt); + +									cos_ang = cos(r); +									sin_ang = sin(r); +								}  							} -							if(tc.mV[1] < 0.f) +							else  							{ -								tc.mV[1] = 1.0f + tc.mV[1] ; +								continue;  							}  							break; -						default: -							break; -						} -				 -						tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ; -						tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ;  					} +					 + +					for (S32 i = 0; i < num_vertices; i++) +					{	 +						LLVector2 tc(vf.mTexCoords[i]); +			 +						LLVector4a& norm = vf.mNormals[i]; +				 +						LLVector4a& center = *(vf.mCenter); +		    +						if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) +						{ +							LLVector4a vec = vf.mPositions[i]; +							vec.mul(scalea); -					*tex_coords++ = tc; -					if (do_bump) -					{ -						bump_tc.push_back(tc); +							if (texgen == LLTextureEntry::TEX_GEN_PLANAR) +							{ +								planarProjection(tc, norm, center, vec); +							} +						} + +						if (tex_mode && mTextureMatrix) +						{ +							LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); +							tmp = tmp * *mTextureMatrix; +							tc.mV[0] = tmp.mV[0]; +							tc.mV[1] = tmp.mV[1]; +						} +						else +						{ +							xform(tc, cos_ang, sin_ang, os, ot, ms, mt); +						} + +						*dst++ = tc; +						if (do_bump) +						{ +							bump_tc.push_back(tc); +						}  					}  				} @@ -1894,17 +1887,20 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  					mVertexBuffer->flush();  				} -				if (do_bump) +				if (!mat && do_bump)  				{ -					mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range); +					mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount, map_range);  					for (S32 i = 0; i < num_vertices; i++)  					{ -						LLVector4a tangent; -						tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); +						LLVector4a tangent = vf.mTangents[i]; +						LLVector4a binorm; +						binorm.setCross3(vf.mNormals[i], tangent); +						binorm.mul(tangent.getF32ptr()[3]); +						  						LLMatrix4a tangent_to_object; -						tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]); +						tangent_to_object.setRows(tangent, binorm, vf.mNormals[i]);  						LLVector4a t;  						tangent_to_object.rotate(binormal_dir, t);  						LLVector4a binormal; @@ -1920,10 +1916,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  						}  						binormal.normalize3fast(); +  						LLVector2 tc = bump_tc[i];  						tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() ); -						*tex_coords2++ = tc; +						*tex_coords1++ = tc;  					}  					if (map_range) @@ -2006,7 +2003,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			LLFastTimer t(FTM_FACE_GEOM_NORMAL);  			mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);  			F32* normals = (F32*) norm.get(); -	  			for (S32 i = 0; i < num_vertices; i++)  			{	  				LLVector4a normal; @@ -2022,19 +2018,27 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			}  		} -		if (rebuild_binormal) +		if (rebuild_tangent)  		{ -			LLFastTimer t(FTM_FACE_GEOM_BINORMAL); -			mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range); -			F32* binormals = (F32*) binorm.get(); -		 +			LLFastTimer t(FTM_FACE_GEOM_TANGENT); +			mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range); +			F32* tangents = (F32*) tangent.get(); +			 +			mVObjp->getVolume()->genTangents(f); +			 +			LLVector4Logical mask; +			mask.clear(); +			mask.setElement<3>(); +  			for (S32 i = 0; i < num_vertices; i++) -			{	 -				LLVector4a binormal; -				mat_normal.rotate(vf.mBinormals[i], binormal); -				binormal.normalize3fast(); -				binormal.store4a(binormals); -				binormals += 4; +			{ +				LLVector4a tangent_out; +				mat_normal.rotate(vf.mTangents[i], tangent_out); +				tangent_out.normalize3fast(); +				tangent_out.setSelectWithMask(mask, vf.mTangents[i], tangent_out); +				tangent_out.store4a(tangents); +				 +				tangents += 4;  			}  			if (map_range) @@ -2097,11 +2101,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			LLVector4a src; -			U32 glow32 = glow | -						 (glow << 8) | -						 (glow << 16) | -						 (glow << 24); +			LLColor4U glow4u = LLColor4U(0,0,0,glow); +			U32 glow32 = glow4u.mAll; +			  			U32 vec[4];  			vec[0] = vec[1] = vec[2] = vec[3] = glow32; @@ -2153,9 +2156,9 @@ BOOL LLFace::hasMedia() const  	{  		return TRUE ;  	} -	if(mTexture.notNull())  +	if(mTexture[LLRender::DIFFUSE_MAP].notNull())   	{ -		return mTexture->hasParcelMedia() ;  //if has a parcel media +		return mTexture[LLRender::DIFFUSE_MAP]->hasParcelMedia() ;  //if has a parcel media  	}  	return FALSE ; //no media. @@ -2207,7 +2210,7 @@ F32 LLFace::getTextureVirtualSize()  	face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area) ;  	if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.  	{ -		if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture.notNull() && mTexture->isLargeImage()) +		if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->isLargeImage())  		{		  			face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius );  		}	 @@ -2246,7 +2249,7 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)  		dist *= 16.f;  	} -	lookAt.normalize3fast() ;	 +	lookAt.normalize3fast();	  	//get area of circle around node  	F32 app_angle = atanf((F32) sqrt(size_squared) / dist); @@ -2574,159 +2577,13 @@ LLVector3 LLFace::getPositionAgent() const  	}  } -// -//atlas -// -void LLFace::removeAtlas() -{ -	setAtlasInUse(FALSE) ; -	mAtlasInfop = NULL ;	 -} - -const LLTextureAtlas* LLFace::getAtlas()const  -{ -	if(mAtlasInfop) -	{ -		return mAtlasInfop->getAtlas() ; -	} -	return NULL ; -} - -const LLVector2* LLFace::getTexCoordOffset()const  -{ -	if(isAtlasInUse()) -	{ -		return mAtlasInfop->getTexCoordOffset() ; -	} -	return NULL ; -} -const LLVector2* LLFace::getTexCoordScale() const  -{ -	if(isAtlasInUse()) -	{ -		return mAtlasInfop->getTexCoordScale() ; -	} -	return NULL ; -} - -BOOL LLFace::isAtlasInUse()const -{ -	return mUsingAtlas ; -} - -BOOL LLFace::canUseAtlas()const +LLViewerTexture* LLFace::getTexture(U32 ch) const  { -	//no drawable or no spatial group, do not use atlas -	if(!mDrawablep || !mDrawablep->getSpatialGroup()) -	{ -		return FALSE ; -	} - -	//if bump face, do not use atlas -	if(getTextureEntry() && getTextureEntry()->getBumpmap()) -	{ -		return FALSE ; -	} - -	//if animated texture, do not use atlas -	if(isState(TEXTURE_ANIM)) -	{ -		return FALSE ; -	} +	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); -	return TRUE ; -} - -void LLFace::setAtlasInUse(BOOL flag) -{ -	//no valid atlas to use. -	if(flag && (!mAtlasInfop || !mAtlasInfop->isValid())) -	{ -		flag = FALSE ; -	} - -	if(!flag && !mUsingAtlas) -	{ -		return ; -	} - -	// -	//at this stage (flag || mUsingAtlas) is always true. -	// - -	//rebuild the tex coords -	if(mDrawablep) -	{ -		gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_TCOORD); -		mUsingAtlas = flag ; -	} -	else -	{ -		mUsingAtlas = FALSE ; -	} +	return mTexture[ch] ;  } -LLTextureAtlasSlot* LLFace::getAtlasInfo() -{ -	return mAtlasInfop ; -} - -void LLFace::setAtlasInfo(LLTextureAtlasSlot* atlasp) -{	 -	if(mAtlasInfop != atlasp) -	{ -		if(mAtlasInfop) -		{ -			//llerrs << "Atlas slot changed!" << llendl ; -		} -		mAtlasInfop = atlasp ; -	} -} - -LLViewerTexture* LLFace::getTexture() const -{ -	if(isAtlasInUse()) -	{ -		return (LLViewerTexture*)mAtlasInfop->getAtlas() ; -	} - -	return mTexture ; -} - -//switch to atlas or switch back to gl texture  -//return TRUE if using atlas. -BOOL LLFace::switchTexture() -{ -	//no valid atlas or texture -	if(!mAtlasInfop || !mAtlasInfop->isValid() || !mTexture) -	{ -		return FALSE ; -	} -	 -	if(mTexture->getTexelsInAtlas() >= (U32)mVSize ||  -		mTexture->getTexelsInAtlas() >= mTexture->getTexelsInGLTexture()) -	{ -		//switch to use atlas -		//atlas resolution is qualified, use it.		 -		if(!mUsingAtlas) -		{ -			setAtlasInUse(TRUE) ; -		} -	} -	else //if atlas not qualified. -	{ -		//switch back to GL texture -		if(mUsingAtlas && mTexture->isGLTextureCreated() &&  -			mTexture->getDiscardLevel() < mTexture->getDiscardLevelInAtlas()) -		{ -			setAtlasInUse(FALSE) ; -		} -	} - -	return mUsingAtlas ; -} - -  void LLFace::setVertexBuffer(LLVertexBuffer* buffer)  {  	mVertexBuffer = buffer; @@ -2742,6 +2599,22 @@ void LLFace::clearVertexBuffer()  U32 LLFace::getRiggedDataMask(U32 type)  {  	static const U32 rigged_data_mask[] = { +		LLDrawPoolAvatar::RIGGED_MATERIAL_MASK, +		LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_VMASK, +		LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_MASK_MASK, +		LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK, +		LLDrawPoolAvatar::RIGGED_SPECMAP_VMASK, +		LLDrawPoolAvatar::RIGGED_SPECMAP_BLEND_MASK, +		LLDrawPoolAvatar::RIGGED_SPECMAP_MASK_MASK, +		LLDrawPoolAvatar::RIGGED_SPECMAP_EMISSIVE_MASK, +		LLDrawPoolAvatar::RIGGED_NORMMAP_VMASK, +		LLDrawPoolAvatar::RIGGED_NORMMAP_BLEND_MASK, +		LLDrawPoolAvatar::RIGGED_NORMMAP_MASK_MASK, +		LLDrawPoolAvatar::RIGGED_NORMMAP_EMISSIVE_MASK, +		LLDrawPoolAvatar::RIGGED_NORMSPEC_VMASK, +		LLDrawPoolAvatar::RIGGED_NORMSPEC_BLEND_MASK, +		LLDrawPoolAvatar::RIGGED_NORMSPEC_MASK_MASK, +		LLDrawPoolAvatar::RIGGED_NORMSPEC_EMISSIVE_MASK,  		LLDrawPoolAvatar::RIGGED_SIMPLE_MASK,  		LLDrawPoolAvatar::RIGGED_FULLBRIGHT_MASK,  		LLDrawPoolAvatar::RIGGED_SHINY_MASK, diff --git a/indra/newview/llface.h b/indra/newview/llface.h index de4d03351c..0687544d53 100755 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -41,7 +41,6 @@  #include "llvertexbuffer.h"  #include "llviewertexture.h"  #include "lldrawable.h" -#include "lltextureatlasmanager.h"  class LLFacePool;  class LLVolume; @@ -50,7 +49,6 @@ class LLTextureEntry;  class LLVertexProgram;  class LLViewerTexture;  class LLGeometryManager; -class LLTextureAtlasSlot;  const F32 MIN_ALPHA_SIZE = 1024.f;  const F32 MIN_TEX_ANIM_SIZE = 512.f; @@ -110,13 +108,17 @@ public:  	U16				getGeomStart()		const	{ return mGeomIndex; }		// index into draw pool  	void			setTextureIndex(U8 index);  	U8				getTextureIndex() const		{ return mTextureIndex; } +	void			setTexture(U32 ch, LLViewerTexture* tex);  	void			setTexture(LLViewerTexture* tex) ; -	void            switchTexture(LLViewerTexture* new_texture); +	void			setDiffuseMap(LLViewerTexture* tex); +	void			setNormalMap(LLViewerTexture* tex); +	void			setSpecularMap(LLViewerTexture* tex); +	void            switchTexture(U32 ch, LLViewerTexture* new_texture);  	void            dirtyTexture();  	LLXformMatrix*	getXform()			const	{ return mXform; }  	BOOL			hasGeometry()		const	{ return mGeomCount > 0; }  	LLVector3		getPositionAgent()	const; -	LLVector2       surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal); +	LLVector2       surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal);  	void 			getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const;  	bool			calcAlignedPlanarTE(const LLFace* align_to, LLVector2* st_offset,  										LLVector2* st_scale, F32* st_rot) const; @@ -130,8 +132,8 @@ public:  	F32				getVirtualSize() const { return mVSize; }  	F32				getPixelArea() const { return mPixelArea; } -	S32             getIndexInTex() const {return mIndexInTex ;} -	void            setIndexInTex(S32 index) { mIndexInTex = index ;} +	S32             getIndexInTex(U32 ch) const {llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); return mIndexInTex[ch];} +	void            setIndexInTex(U32 ch, S32 index) { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);  mIndexInTex[ch] = index ;}  	void			renderSetColor() const;  	S32				renderElements(const U16 *index_array) const; @@ -149,7 +151,7 @@ public:  	S32				getLOD()			const	{ return mVObjp.notNull() ? mVObjp->getLOD() : 0; }  	void			setPoolType(U32 type)		{ mPoolType = type; }  	S32				getTEOffset()				{ return mTEOffset; } -	LLViewerTexture*	getTexture() const; +	LLViewerTexture*	getTexture(U32 ch = LLRender::DIFFUSE_MAP) const;  	void			setViewerObject(LLViewerObject* object);  	void			setPool(LLFacePool *pool, LLViewerTexture *texturep); @@ -223,16 +225,6 @@ public:  	void        setHasMedia(bool has_media)  { mHasMedia = has_media ;}  	BOOL        hasMedia() const ; -	//for atlas -	LLTextureAtlasSlot*   getAtlasInfo() ; -	void                  setAtlasInUse(BOOL flag); -	void                  setAtlasInfo(LLTextureAtlasSlot* atlasp); -	BOOL                  isAtlasInUse()const; -	BOOL                  canUseAtlas() const; -	const LLVector2*      getTexCoordScale() const ; -	const LLVector2*      getTexCoordOffset()const; -	const LLTextureAtlas* getAtlas()const ; -	void                  removeAtlas() ;  	BOOL                  switchTexture() ;  	//vertex buffer tracking @@ -266,6 +258,8 @@ public:  	F32			mLastSkinTime;  	F32			mLastMoveTime;  	LLMatrix4*	mTextureMatrix; +	LLMatrix4*	mSpecMapMatrix; +	LLMatrix4*	mNormalMapMatrix;  	LLDrawInfo* mDrawInfo;  private: @@ -281,10 +275,12 @@ private:  	U8			mTextureIndex;		// index of texture channel to use for pseudo-atlasing  	U32			mIndicesCount;  	U32			mIndicesIndex;		// index into draw pool for indices (yeah, I know!) -	S32         mIndexInTex ; +	S32         mIndexInTex[LLRender::NUM_TEXTURE_CHANNELS];  	LLXformMatrix* mXform; -	LLPointer<LLViewerTexture> mTexture; + +	LLPointer<LLViewerTexture> mTexture[LLRender::NUM_TEXTURE_CHANNELS]; +	  	LLPointer<LLDrawable> mDrawablep;  	LLPointer<LLViewerObject> mVObjp;  	S32			mTEOffset; @@ -302,9 +298,6 @@ private:  	F32         mBoundingSphereRadius ;  	bool        mHasMedia ; -	//atlas -	LLPointer<LLTextureAtlasSlot> mAtlasInfop ; -	BOOL                          mUsingAtlas ;  protected:  	static BOOL	sSafeRenderSelect; diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 58817485fb..b40789db9c 100755 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -2021,7 +2021,7 @@ void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)  	{  		LLMultiFloater::setMinimized(FALSE);  	} -	 +  	LLFloater::closeFloater(app_quitting);  } diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 49f36a2f32..56b0c15cb9 100755 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -328,7 +328,7 @@ void LLFloaterIMNearbyChat::onChatFontChange(LLFontGL* fontp)  void LLFloaterIMNearbyChat::show()  {  		openFloater(getKey()); -} +	}  bool LLFloaterIMNearbyChat::isChatVisible() const  { diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index bbf88060c1..55b03986d0 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1089,8 +1089,9 @@ void LLFloaterPreference::refreshEnabledState()  	ctrl_reflections->setEnabled(reflections);  	// Bump & Shiny	 +	LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");  	bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump"); -	getChild<LLCheckBoxCtrl>("BumpShiny")->setEnabled(bumpshiny ? TRUE : FALSE); +	bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE);  	radio_reflection_detail->setEnabled(reflections); @@ -1148,7 +1149,8 @@ void LLFloaterPreference::refreshEnabledState()  	//Deferred/SSAO/Shadows  	LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); -	BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&  +	BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && +						((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&  						shaders &&   						gGLManager.mHasFramebufferObject &&  						gSavedSettings.getBOOL("RenderAvatarVP") && @@ -1161,7 +1163,9 @@ void LLFloaterPreference::refreshEnabledState()  	LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail");  	enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE); -		 +	 +	ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred")); +  	ctrl_ssao->setEnabled(enabled);  	ctrl_dof->setEnabled(enabled); @@ -2319,3 +2323,4 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings()  	}  } + diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index 5c6ce9d311..16ed3f990c 100755 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -521,7 +521,7 @@ public:  	void fire(const LLUUID& inv_item_id)  	{  		LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); -		 +  		if (item)  			LLFriendCardsManager::instance().extractAvatarID(item->getCreatorUUID());  	} diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp index 7e1025c41b..825c2b31be 100755 --- a/indra/newview/llhudicon.cpp +++ b/indra/newview/llhudicon.cpp @@ -202,7 +202,7 @@ void LLHUDIcon::render()  	renderIcon(FALSE);  } -BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection) +BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)  {  	if (mHidden)  		return FALSE; @@ -275,23 +275,18 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  	LLVector4a upper_right;  	upper_right.setAdd(lower_right, y_scalea); -	LLVector4a enda; -	enda.load3(end.mV); -	LLVector4a starta; -	starta.load3(start.mV);  	LLVector4a dir; -	dir.setSub(enda, starta); +	dir.setSub(end, start);  	F32 a,b,t; -	if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, starta, dir, a,b,t) || -		LLTriangleRayIntersect(upper_left, lower_left, lower_right, starta, dir, a,b,t)) +	if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, start, dir, a,b,t) || +		LLTriangleRayIntersect(upper_left, lower_left, lower_right, start, dir, a,b,t))  	{  		if (intersection)  		{  			dir.mul(t); -			starta.add(dir); -			*intersection = LLVector3(starta.getF32ptr()); +			intersection->setAdd(start, dir);  		}  		return TRUE;  	} @@ -331,12 +326,12 @@ LLHUDIcon* LLHUDIcon::handlePick(S32 pick_id)  }  //static -LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection) +LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)  {  	icon_instance_t::iterator icon_it; -	LLVector3 local_end = end; -	LLVector3 position; +	LLVector4a local_end = end; +	LLVector4a position;  	LLHUDIcon* ret = NULL;  	for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it) diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h index 644daa0299..557252ab0b 100755 --- a/indra/newview/llhudicon.h +++ b/indra/newview/llhudicon.h @@ -62,7 +62,7 @@ public:  	static S32 generatePickIDs(S32 start_id, S32 step_size);  	static LLHUDIcon* handlePick(S32 pick_id); -	static LLHUDIcon* lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection); +	static LLHUDIcon* lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);  	static void updateAll();  	static void cleanupDeadIcons(); @@ -73,7 +73,7 @@ public:  	BOOL getHidden() const { return mHidden; }  	void setHidden( BOOL hide ) { mHidden = hide; } -	BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection); +	BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);  protected:  	LLHUDIcon(const U8 type); diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 3336097955..c3b49f739a 100755 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -116,7 +116,7 @@ LLHUDNameTag::~LLHUDNameTag()  } -BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render) +BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render)  {  	if (!mVisible || mHidden)  	{ @@ -199,15 +199,23 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&  		bg_pos + height_vec,  	}; -	LLVector3 dir = end-start; +	LLVector4a dir; +	dir.setSub(end,start);  	F32 a, b, t; -	if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) || -		LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) ) +	LLVector4a v0,v1,v2,v3; +	v0.load3(v[0].mV); +	v1.load3(v[1].mV); +	v2.load3(v[2].mV); +	v3.load3(v[3].mV); + +	if (LLTriangleRayIntersect(v0, v1, v2, start, dir, a, b, t) || +		LLTriangleRayIntersect(v2, v3, v0, start, dir, a, b, t) )  	{  		if (t <= 1.f)  		{ -			intersection = start + dir*t; +			dir.mul(t); +			intersection.setAdd(start, dir);  			return TRUE;  		}  	} diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h index 72647d5b26..38a4f18415 100755 --- a/indra/newview/llhudnametag.h +++ b/indra/newview/llhudnametag.h @@ -124,7 +124,7 @@ public:  	void setHidden( BOOL hide ) { mHidden = hide; }  	void shift(const LLVector3& offset); -	BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render = FALSE); +	BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render = FALSE);  	static void shiftAll(const LLVector3& offset);  	static void addPickable(std::set<LLViewerObject*> &pick_list); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 2c20409381..3b72ad3cd9 100755 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -228,7 +228,7 @@ void on_new_message(const LLSD& msg)      // 0. nothing - exit      if (("none" == user_preferences ||      		ON_TOP_AND_ITEM_IS_SELECTED == conversations_floater_status) -    	    && session_floater->isMessagePaneExpanded()) +    	&& session_floater->isMessagePaneExpanded())      {      	return;      } @@ -1561,7 +1561,7 @@ public:  	}  	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content) -	{ +	{		  		llwarns << "LLViewerChatterBoxInvitationAcceptResponder error [status:"  				<< statusNum << "]: " << content << llendl;  		//throw something back to the viewer here? diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index f2b39e7186..d88e0c3192 100755 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -686,23 +686,23 @@ void LLInventoryModelBackgroundFetch::bulkFetch()  	{  		if (folder_count)  		{ -			std::string url = region->getCapability("FetchInventoryDescendents2");   			 +			std::string url = region->getCapability("FetchInventoryDescendents2");     			if ( !url.empty() )  			{ -				mFetchCount++; -				if (folder_request_body["folders"].size()) -				{ -					LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats); -					LLHTTPClient::post(url, folder_request_body, fetcher, 300.0); -				} -				if (folder_request_body_lib["folders"].size()) -				{ -					std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2"); +			mFetchCount++; +			if (folder_request_body["folders"].size()) +			{ +				LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats); +				LLHTTPClient::post(url, folder_request_body, fetcher, 300.0); +			} +			if (folder_request_body_lib["folders"].size()) +			{ +				std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2"); -					LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats); -					LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0); -				} -			}					 +				LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats); +				LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0); +			} +		}  		}  		if (item_count)  		{ diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 25df4889b0..2d9385390b 100755 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -58,6 +58,8 @@  #include "lltexlayerparams.h"  #include "llvovolume.h"  #include "llnotificationsutil.h" +#include "pipeline.h" +#include "llmaterialmgr.h"  /*=======================================*/  /*  Formal declarations, constants, etc. */ @@ -339,7 +341,12 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)  		return;  	} -	updateUserPrims(old_id, new_id); +	// processing updates per channel; makes the process scalable. +	// the only actual difference is in SetTE* call i.e. SetTETexture, SetTENormal, etc. +	updateUserPrims(old_id, new_id, LLRender::DIFFUSE_MAP); +	updateUserPrims(old_id, new_id, LLRender::NORMAL_MAP); +	updateUserPrims(old_id, new_id, LLRender::SPECULAR_MAP); +	  	updateUserSculpts(old_id, new_id); // isn't there supposed to be an IMG_DEFAULT_SCULPT or something?  	// default safeguard image for layers @@ -367,15 +374,15 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)  // this function sorts the faces from a getFaceList[getNumFaces] into a list of objects  // in order to prevent multiple sendTEUpdate calls per object during updateUserPrims -std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id) +std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id, U32 channel)  {  	std::vector<LLViewerObject*> obj_list;  	LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id); - -	for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(); face_iterator++) +	 +	for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(channel); face_iterator++)  	{  		// getting an object from a face -		LLFace* face_to_object = (*old_texture->getFaceList())[face_iterator]; +		LLFace* face_to_object = (*old_texture->getFaceList(channel))[face_iterator];  		if(face_to_object)  		{ @@ -416,9 +423,9 @@ std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id)  	return obj_list;  } -void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id) +void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel)  { -	std::vector<LLViewerObject*> objectlist = prepUpdateObjects(old_id); +	std::vector<LLViewerObject*> objectlist = prepUpdateObjects(old_id, channel);  	for(std::vector<LLViewerObject*>::iterator object_iterator = objectlist.begin();  		object_iterator != objectlist.end(); object_iterator++) @@ -427,7 +434,8 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id)  		if(object)  		{ -			bool update_obj = false; +			bool update_tex = false; +			bool update_mat = false;  			S32 num_faces = object->getNumFaces();  			for (U8 face_iter = 0; face_iter < num_faces; face_iter++) @@ -435,20 +443,51 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id)  				if (object->mDrawable)  				{  					LLFace* face = object->mDrawable->getFace(face_iter); -					if (face && face->getTexture() && face->getTexture()->getID() == old_id) +					if (face && face->getTexture(channel) && face->getTexture(channel)->getID() == old_id)  					{ -						object->setTEImage(face_iter, LLViewerTextureManager::getFetchedTexture( -							new_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); +						// these things differ per channel, unless there already is a universal +						// texture setting function to setTE that takes channel as a param? +						// p.s.: switch for now, might become if - if an extra test is needed to verify before touching normalmap/specmap +						switch(channel) +						{ +							case LLRender::DIFFUSE_MAP: +							{ +                                object->setTETexture(face_iter, new_id); +                                update_tex = true; +								break; +							} + +							case LLRender::NORMAL_MAP: +							{ +								object->setTENormalMap(face_iter, new_id); +								update_mat = true; +								update_tex = true; +                                break; +							} + +							case LLRender::SPECULAR_MAP: +							{ +								object->setTESpecularMap(face_iter, new_id); +                                update_mat = true; +								update_tex = true; +                                break; +							} +						} +						// end switch -						update_obj = true;  					}  				}  			} -			if (update_obj) +			if (update_tex)  			{  				object->sendTEUpdate();  			} + +			if (update_mat) +			{ +                object->mDrawable->getVOVolume()->faceMappingChanged(); +			}  		}  	} diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index 580b6dfa7e..2ee84bf46e 100755 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -62,8 +62,8 @@ class LLLocalBitmap  	private: /* self update private section */  		bool decodeBitmap(LLPointer<LLImageRaw> raw);  		void replaceIDs(LLUUID old_id, LLUUID new_id); -		std::vector<LLViewerObject*> prepUpdateObjects(LLUUID old_id); -		void updateUserPrims(LLUUID old_id, LLUUID new_id); +		std::vector<LLViewerObject*> prepUpdateObjects(LLUUID old_id, U32 channel); +		void updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel);  		void updateUserSculpts(LLUUID old_id, LLUUID new_id);  		void updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type);  		LLAvatarAppearanceDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind); diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 977c50682f..f681c12747 100755 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -642,6 +642,8 @@ bool LLLoginInstance::handleLoginEvent(const LLSD& event)  void LLLoginInstance::handleLoginFailure(const LLSD& event)  { +	 +  	// Login has failed.   	// Figure out why and respond...  	LLSD response = event["data"]; @@ -654,10 +656,13 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)  	// to reconnect or to end the attempt in failure.  	if(reason_response == "tos")  	{ +		llinfos << "LLLoginInstance::handleLoginFailure ToS" << llendl; +  		LLSD data(LLSD::emptyMap());  		data["message"] = message_response;  		data["reply_pump"] = TOS_REPLY_PUMP; -		gViewerWindow->setShowProgress(FALSE); +		if (gViewerWindow) +			gViewerWindow->setShowProgress(FALSE);  		LLFloaterReg::showInstance("message_tos", data);  		LLEventPumps::instance().obtain(TOS_REPLY_PUMP)  			.listen(TOS_LISTENER_NAME, @@ -666,6 +671,8 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)  	}  	else if(reason_response == "critical")  	{ +		llinfos << "LLLoginInstance::handleLoginFailure Crit" << llendl; +  		LLSD data(LLSD::emptyMap());  		data["message"] = message_response;  		data["reply_pump"] = TOS_REPLY_PUMP; @@ -678,7 +685,9 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)  			data["certificate"] = response["certificate"];  		} -		gViewerWindow->setShowProgress(FALSE); +		if (gViewerWindow) +			gViewerWindow->setShowProgress(FALSE); +  		LLFloaterReg::showInstance("message_critical", data);  		LLEventPumps::instance().obtain(TOS_REPLY_PUMP)  			.listen(TOS_LISTENER_NAME, @@ -687,21 +696,28 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)  	}  	else if(reason_response == "update" || gSavedSettings.getBOOL("ForceMandatoryUpdate"))  	{ +		llinfos << "LLLoginInstance::handleLoginFailure update" << llendl; +  		gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE);  		updateApp(true, message_response);  	}  	else if(reason_response == "optional")  	{ +		llinfos << "LLLoginInstance::handleLoginFailure optional" << llendl; +  		updateApp(false, message_response);  	}  	else  	{	 +		llinfos << "LLLoginInstance::handleLoginFailure attemptComplete" << llendl;  		attemptComplete();  	}	  }  void LLLoginInstance::handleLoginSuccess(const LLSD& event)  { +	llinfos << "LLLoginInstance::handleLoginSuccess" << llendl; +  	if(gSavedSettings.getBOOL("ForceMandatoryUpdate"))  	{  		LLSD response = event["data"]; @@ -723,6 +739,8 @@ void LLLoginInstance::handleLoginSuccess(const LLSD& event)  void LLLoginInstance::handleDisconnect(const LLSD& event)  {      // placeholder + +	llinfos << "LLLoginInstance::handleDisconnect placeholder " << llendl;  }  void LLLoginInstance::handleIndeterminate(const LLSD& event) @@ -731,10 +749,13 @@ void LLLoginInstance::handleIndeterminate(const LLSD& event)  	// gave the viewer a new url and params to try.  	// The login module handles the retry, but it gives us the  	// server response so that we may show -	// the user some status. +	// the user some status.	 +  	LLSD message = event.get("data").get("message");  	if(message.isDefined())  	{ +		llinfos << "LLLoginInstance::handleIndeterminate " << message.asString() << llendl; +  		LLSD progress_update;  		progress_update["desc"] = message;  		LLEventPumps::getInstance()->obtain("LLProgressView").post(progress_update); @@ -745,12 +766,16 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key)  {  	if(accepted)  	{	 +		llinfos << "LLLoginInstance::handleTOSResponse: accepted" << llendl; +  		// Set the request data to true and retry login.  		mRequestData["params"][key] = true;   		reconnect();  	}  	else  	{ +		llinfos << "LLLoginInstance::handleTOSResponse: attemptComplete" << llendl; +  		attemptComplete();  	} diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp new file mode 100644 index 0000000000..16871adc4d --- /dev/null +++ b/indra/newview/llmaterialmgr.cpp @@ -0,0 +1,782 @@ +/** + * @file llmaterialmgr.cpp + * @brief Material manager + * + * $LicenseInfo:firstyear=2013&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llsdserialize.h" +#include "llsdutil.h" + +#include "llagent.h" +#include "llcallbacklist.h" +#include "llmaterialmgr.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llworld.h" + +/** + * Materials cap parameters + */ + +#define MATERIALS_CAPABILITY_NAME                 "RenderMaterials" + +#define MATERIALS_CAP_ZIP_FIELD                   "Zipped" + +#define MATERIALS_CAP_FULL_PER_FACE_FIELD         "FullMaterialsPerFace" +#define MATERIALS_CAP_FACE_FIELD                  "Face" +#define MATERIALS_CAP_MATERIAL_FIELD              "Material" +#define MATERIALS_CAP_OBJECT_ID_FIELD             "ID" +#define MATERIALS_CAP_MATERIAL_ID_FIELD           "MaterialID" + +#define MATERIALS_GET_MAX_ENTRIES                 50 +#define MATERIALS_GET_TIMEOUT                     (60.f * 20) +#define MATERIALS_POST_MAX_ENTRIES                50 +#define MATERIALS_POST_TIMEOUT                    (60.f * 5) +#define MATERIALS_PUT_THROTTLE_SECS               1.f +#define MATERIALS_PUT_MAX_ENTRIES                 50 + +/** + * LLMaterialsResponder helper class + */ + +class LLMaterialsResponder : public LLHTTPClient::Responder +{ +public: +	typedef boost::function<void (bool, const LLSD&)> CallbackFunction; + +	LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback); +	virtual ~LLMaterialsResponder(); + +	virtual void result(const LLSD& pContent); +	virtual void error(U32 pStatus, const std::string& pReason); + +private: +	std::string      mMethod; +	std::string      mCapabilityURL; +	CallbackFunction mCallback; +}; + +LLMaterialsResponder::LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback) +	: LLHTTPClient::Responder() +	, mMethod(pMethod) +	, mCapabilityURL(pCapabilityURL) +	, mCallback(pCallback) +{ +} + +LLMaterialsResponder::~LLMaterialsResponder() +{ +} + +void LLMaterialsResponder::result(const LLSD& pContent) +{ +	LL_DEBUGS("Materials") << LL_ENDL; +	mCallback(true, pContent); +} + +void LLMaterialsResponder::error(U32 pStatus, const std::string& pReason) +{ +	LL_WARNS("Materials") +		<< "\n--------------------------------------------------------------------------\n" +		<< mMethod << " Error[" << pStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME +		<< "'\n  with url '" << mCapabilityURL	<< "' because " << pReason  +		<< "\n--------------------------------------------------------------------------" +		<< LL_ENDL; + +	LLSD emptyResult; +	mCallback(false, emptyResult); +} + +/** + * LLMaterialMgr class + */ + +LLMaterialMgr::LLMaterialMgr() +{ +	mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(LLMaterialID::null, LLMaterialPtr(NULL))); +	gIdleCallbacks.addFunction(&LLMaterialMgr::onIdle, NULL); +	LLWorld::instance().setRegionRemovedCallback(boost::bind(&LLMaterialMgr::onRegionRemoved, this, _1)); +} + +LLMaterialMgr::~LLMaterialMgr() +{ +	gIdleCallbacks.deleteFunction(&LLMaterialMgr::onIdle, NULL); +} + +bool LLMaterialMgr::isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const +{ +	get_pending_map_t::const_iterator itPending = mGetPending.find(pending_material_t(region_id, material_id)); +	return (mGetPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_POST_TIMEOUT); +} + +void LLMaterialMgr::markGetPending(const LLUUID& region_id, const LLMaterialID& material_id) +{ +	get_pending_map_t::iterator itPending = mGetPending.find(pending_material_t(region_id, material_id)); +	if (mGetPending.end() == itPending) +	{ +		mGetPending.insert(std::pair<pending_material_t, F64>(pending_material_t(region_id, material_id), LLFrameTimer::getTotalSeconds())); +	} +	else +	{ +		itPending->second = LLFrameTimer::getTotalSeconds(); +	} +} + +const LLMaterialPtr LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id) +{ +	LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL; +	LLMaterialPtr material; +	material_map_t::const_iterator itMaterial = mMaterials.find(material_id); +	if (mMaterials.end() != itMaterial) +	{ +		material = itMaterial->second; +		LL_DEBUGS("Materials") << " found material " << LL_ENDL; +	} +	else +	{ +		if (!isGetPending(region_id, material_id)) +		{ +			LL_DEBUGS("Materials") << " material pending " << material_id << LL_ENDL; +			get_queue_t::iterator itQueue = mGetQueue.find(region_id); +			if (mGetQueue.end() == itQueue) +			{ +				LL_DEBUGS("Materials") << "mGetQueue add region " << region_id << " pending " << material_id << LL_ENDL; +				std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t())); +				itQueue = ret.first; +			} +			itQueue->second.insert(material_id); +			markGetPending(region_id, material_id); +		} +		LL_DEBUGS("Materials") << " returning empty material " << LL_ENDL; +		material = LLMaterialPtr(); +	} +	return material; +} + +boost::signals2::connection LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id, LLMaterialMgr::get_callback_t::slot_type cb) +{ +	boost::signals2::connection connection; +	 +	material_map_t::const_iterator itMaterial = mMaterials.find(material_id); +	if (itMaterial != mMaterials.end()) +	{ +		LL_DEBUGS("Materials") << "region " << region_id << " found materialid " << material_id << LL_ENDL; +		get_callback_t signal; +		signal.connect(cb); +		signal(material_id, itMaterial->second); +		connection = boost::signals2::connection(); +	} +	else +	{ +		if (!isGetPending(region_id, material_id)) +		{ +			get_queue_t::iterator itQueue = mGetQueue.find(region_id); +			if (mGetQueue.end() == itQueue) +			{ +				LL_DEBUGS("Materials") << "mGetQueue inserting region "<<region_id << LL_ENDL; +				std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t())); +				itQueue = ret.first; +			} +			LL_DEBUGS("Materials") << "adding material id " << material_id << LL_ENDL; +			itQueue->second.insert(material_id); +			markGetPending(region_id, material_id); +		} + +		get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id); +		if (itCallback == mGetCallbacks.end()) +		{ +			std::pair<get_callback_map_t::iterator, bool> ret = mGetCallbacks.insert(std::pair<LLMaterialID, get_callback_t*>(material_id, new get_callback_t())); +			itCallback = ret.first; +		} +		connection = itCallback->second->connect(cb);; +	} +	 +	return connection; +} + +boost::signals2::connection LLMaterialMgr::getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, LLMaterialMgr::get_callback_te_t::slot_type cb) +{ +	boost::signals2::connection connection; + +	material_map_t::const_iterator itMaterial = mMaterials.find(material_id); +	if (itMaterial != mMaterials.end()) +	{ +		LL_DEBUGS("Materials") << "region " << region_id << " found materialid " << material_id << LL_ENDL; +		get_callback_te_t signal; +		signal.connect(cb); +		signal(material_id, itMaterial->second, te); +		connection = boost::signals2::connection(); +	} +	else +	{ +		if (!isGetPending(region_id, material_id)) +		{ +			get_queue_t::iterator itQueue = mGetQueue.find(region_id); +			if (mGetQueue.end() == itQueue) +			{ +				LL_DEBUGS("Materials") << "mGetQueue inserting region "<<region_id << LL_ENDL; +				std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t())); +				itQueue = ret.first; +			} +			LL_DEBUGS("Materials") << "adding material id " << material_id << LL_ENDL; +			itQueue->second.insert(material_id); +			markGetPending(region_id, material_id); +		} + +		TEMaterialPair te_mat_pair; +		te_mat_pair.te = te; +		te_mat_pair.materialID = material_id; + +		get_callback_te_map_t::iterator itCallback = mGetTECallbacks.find(te_mat_pair); +		if (itCallback == mGetTECallbacks.end()) +		{ +			std::pair<get_callback_te_map_t::iterator, bool> ret = mGetTECallbacks.insert(std::pair<TEMaterialPair, get_callback_te_t*>(te_mat_pair, new get_callback_te_t())); +			itCallback = ret.first; +		} +		connection = itCallback->second->connect(cb); +	} + +	return connection; +} + +bool LLMaterialMgr::isGetAllPending(const LLUUID& region_id) const +{ +	getall_pending_map_t::const_iterator itPending = mGetAllPending.find(region_id); +	return (mGetAllPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_GET_TIMEOUT); +} + +void LLMaterialMgr::getAll(const LLUUID& region_id) +{ +	if (!isGetAllPending(region_id)) +	{ +		LL_DEBUGS("Materials") << "queuing for region " << region_id << LL_ENDL; +		mGetAllQueue.insert(region_id); +	} +	else +	{ +		LL_DEBUGS("Materials") << "already pending for region " << region_id << LL_ENDL; +	} +} + +boost::signals2::connection LLMaterialMgr::getAll(const LLUUID& region_id, LLMaterialMgr::getall_callback_t::slot_type cb) +{ +	if (!isGetAllPending(region_id)) +	{ +		mGetAllQueue.insert(region_id); +	} + +	getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id); +	if (mGetAllCallbacks.end() == itCallback) +	{ +		std::pair<getall_callback_map_t::iterator, bool> ret = mGetAllCallbacks.insert(std::pair<LLUUID, getall_callback_t*>(region_id, new getall_callback_t())); +		itCallback = ret.first; +	} +	return itCallback->second->connect(cb);; +} + +void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial& material) +{ +	put_queue_t::iterator itQueue = mPutQueue.find(object_id); +	if (mPutQueue.end() == itQueue) +	{ +		LL_DEBUGS("Materials") << "mPutQueue insert object " << object_id << LL_ENDL; +		mPutQueue.insert(std::pair<LLUUID, facematerial_map_t>(object_id, facematerial_map_t())); +		itQueue = mPutQueue.find(object_id); +	} + +	facematerial_map_t::iterator itFace = itQueue->second.find(te); +	if (itQueue->second.end() == itFace) +	{ +		itQueue->second.insert(std::pair<U8, LLMaterial>(te, material)); +	} +	else +	{ +		itFace->second = material; +	} +} + +void LLMaterialMgr::remove(const LLUUID& object_id, const U8 te) +{ +	put(object_id, te, LLMaterial::null); +} + +const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data) +{ +	LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL; +	material_map_t::const_iterator itMaterial = mMaterials.find(material_id); +	if (mMaterials.end() == itMaterial) +	{ +		LL_DEBUGS("Materials") << "new material" << LL_ENDL; +		LLMaterialPtr newMaterial(new LLMaterial(material_data)); +		std::pair<material_map_t::const_iterator, bool> ret = mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(material_id, newMaterial)); +		itMaterial = ret.first; +	} + +	TEMaterialPair te_mat_pair; +	te_mat_pair.materialID = material_id; + +	U32 i = 0; +	while (i < LLTEContents::MAX_TES) +	{ +		te_mat_pair.te = i++; +		get_callback_te_map_t::iterator itCallbackTE = mGetTECallbacks.find(te_mat_pair); +		if (itCallbackTE != mGetTECallbacks.end()) +		{ +			(*itCallbackTE->second)(material_id, itMaterial->second, te_mat_pair.te); +			delete itCallbackTE->second; +			mGetTECallbacks.erase(itCallbackTE); +		} +	} + +	get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id); +	if (itCallback != mGetCallbacks.end()) +	{ +		(*itCallback->second)(material_id, itMaterial->second); + +		delete itCallback->second; +		mGetCallbacks.erase(itCallback); +	} + +	mGetPending.erase(pending_material_t(region_id, material_id)); + +	return itMaterial->second; +} + +void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUID& region_id) +{ +	if (!success) +	{ +		// *TODO: is there any kind of error handling we can do here? +		LL_WARNS("Materials")<< "failed"<<LL_ENDL; +		return; +	} + +	llassert(content.isMap()); +	llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); +	llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); + +	LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); +	std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size()); +	std::istringstream content_stream(content_string); + +	LLSD response_data; +	if (!unzip_llsd(response_data, content_stream, content_binary.size())) +	{ +		LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL; +		return; +	} + +	llassert(response_data.isArray()); +	LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL; +	for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial) +	{ +		const LLSD& material_data = *itMaterial; +		llassert(material_data.isMap()); + +		llassert(material_data.has(MATERIALS_CAP_OBJECT_ID_FIELD)); +		llassert(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].isBinary()); +		LLMaterialID material_id(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].asBinary()); + +		llassert(material_data.has(MATERIALS_CAP_MATERIAL_FIELD)); +		llassert(material_data[MATERIALS_CAP_MATERIAL_FIELD].isMap()); +			 +		setMaterial(region_id, material_id, material_data[MATERIALS_CAP_MATERIAL_FIELD]); +	} +} + +void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id) +{ +	if (!success) +	{ +		// *TODO: is there any kind of error handling we can do here? +		LL_WARNS("Materials")<< "failed"<<LL_ENDL; +		return; +	} + +	llassert(content.isMap()); +	llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); +	llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); + +	LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); +	std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size()); +	std::istringstream content_stream(content_string); + +	LLSD response_data; +	if (!unzip_llsd(response_data, content_stream, content_binary.size())) +	{ +		LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL; +		return; +	} + +	get_queue_t::iterator itQueue = mGetQueue.find(region_id); +	material_map_t materials; + +	llassert(response_data.isArray()); +	LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL; +	for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial) +	{ +		const LLSD& material_data = *itMaterial; +		llassert(material_data.isMap()); + +		llassert(material_data.has(MATERIALS_CAP_OBJECT_ID_FIELD)); +		llassert(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].isBinary()); +		LLMaterialID material_id(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].asBinary()); +		if (mGetQueue.end() != itQueue) +		{ +			itQueue->second.erase(material_id); +		} + +		llassert(material_data.has(MATERIALS_CAP_MATERIAL_FIELD)); +		llassert(material_data[MATERIALS_CAP_MATERIAL_FIELD].isMap()); +		LLMaterialPtr material = setMaterial(region_id, material_id, material_data[MATERIALS_CAP_MATERIAL_FIELD]); +		 +		materials[material_id] = material; +	} + +	getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id); +	if (itCallback != mGetAllCallbacks.end()) +	{ +		(*itCallback->second)(region_id, materials); + +		delete itCallback->second; +		mGetAllCallbacks.erase(itCallback); +	} + +	if ( (mGetQueue.end() != itQueue) && (itQueue->second.empty()) ) +	{ +		mGetQueue.erase(itQueue); +	} + +	LL_DEBUGS("Materials")<< "recording that getAll has been done for region id " << region_id << LL_ENDL;	 +	mGetAllRequested.insert(region_id); // prevents subsequent getAll requests for this region +	mGetAllPending.erase(region_id);	// Invalidates region_id +} + +void LLMaterialMgr::onPutResponse(bool success, const LLSD& content) +{ +	if (!success) +	{ +		// *TODO: is there any kind of error handling we can do here? +		LL_WARNS("Materials")<< "failed"<<LL_ENDL; +		return; +	} + +	llassert(content.isMap()); +	llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); +	llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); + +	LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); +	std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size()); +	std::istringstream content_stream(content_string); + +	LLSD response_data; +	if (!unzip_llsd(response_data, content_stream, content_binary.size())) +	{ +		LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL; +		return; +	} +	else +	{ +		llassert(response_data.isArray()); +		LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL; +		for (LLSD::array_const_iterator faceIter = response_data.beginArray(); faceIter != response_data.endArray(); ++faceIter) +		{ +#           ifndef LL_RELEASE_FOR_DOWNLOAD +			const LLSD& face_data = *faceIter; // conditional to avoid unused variable warning +#           endif +			llassert(face_data.isMap()); + +			llassert(face_data.has(MATERIALS_CAP_OBJECT_ID_FIELD)); +			llassert(face_data[MATERIALS_CAP_OBJECT_ID_FIELD].isInteger()); +			// U32 local_id = face_data[MATERIALS_CAP_OBJECT_ID_FIELD].asInteger(); + +			llassert(face_data.has(MATERIALS_CAP_FACE_FIELD)); +			llassert(face_data[MATERIALS_CAP_FACE_FIELD].isInteger()); +			// S32 te = face_data[MATERIALS_CAP_FACE_FIELD].asInteger(); + +			llassert(face_data.has(MATERIALS_CAP_MATERIAL_ID_FIELD)); +			llassert(face_data[MATERIALS_CAP_MATERIAL_ID_FIELD].isBinary()); +			// LLMaterialID material_id(face_data[MATERIALS_CAP_MATERIAL_ID_FIELD].asBinary()); + +			// *TODO: do we really still need to process this? +		} +	} +} + +static LLFastTimer::DeclareTimer FTM_MATERIALS_IDLE("Materials"); + +void LLMaterialMgr::onIdle(void*) +{ +	LLFastTimer t(FTM_MATERIALS_IDLE); + +	LLMaterialMgr* instancep = LLMaterialMgr::getInstance(); + +	if (!instancep->mGetQueue.empty()) +	{ +		instancep->processGetQueue(); +	} + +	if (!instancep->mGetAllQueue.empty()) +	{ +		instancep->processGetAllQueue(); +	} + +	static LLFrameTimer mPutTimer; +	if ( (!instancep->mPutQueue.empty()) && (mPutTimer.hasExpired()) ) +	{ +		instancep->processPutQueue(); +		mPutTimer.resetWithExpiry(MATERIALS_PUT_THROTTLE_SECS); +	} +} + +void LLMaterialMgr::processGetQueue() +{ +	get_queue_t::iterator loopRegionQueue = mGetQueue.begin(); +	while (mGetQueue.end() != loopRegionQueue) +	{ +		get_queue_t::iterator itRegionQueue = loopRegionQueue++; + +		const LLUUID& region_id = itRegionQueue->first; +		if (isGetAllPending(region_id)) +		{ +			continue; +		} + +		const LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id); +		if (!regionp) +		{ +			LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL; +			mGetQueue.erase(itRegionQueue); +			continue; +		} +		else if (!regionp->capabilitiesReceived()) +		{ +			continue; +		} +		else if (mGetAllRequested.end() == mGetAllRequested.find(region_id)) +		{ +			LL_DEBUGS("Materials") << "calling getAll for " << regionp->getName() << LL_ENDL; +			getAll(region_id); +			continue; +		} + +		const std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME); +		if (capURL.empty()) +		{ +			LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME +				<< "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL; +			mGetQueue.erase(itRegionQueue); +			continue; +		} + +		LLSD materialsData = LLSD::emptyArray(); + +		material_queue_t& materials = itRegionQueue->second; +		material_queue_t::iterator loopMaterial = materials.begin(); +		while ( (materials.end() != loopMaterial) && (materialsData.size() <= MATERIALS_GET_MAX_ENTRIES) ) +		{ +			material_queue_t::iterator itMaterial = loopMaterial++; +			materialsData.append((*itMaterial).asLLSD()); +			materials.erase(itMaterial); +			markGetPending(region_id, *itMaterial); +		} +		if (materials.empty()) +		{ +			mGetQueue.erase(itRegionQueue); +		} +		 +		std::string materialString = zip_llsd(materialsData); + +		S32 materialSize = materialString.size(); +		if (materialSize <= 0) +		{ +			LL_ERRS("Materials") << "cannot zip LLSD binary content" << LL_ENDL; +			return; +		} + +		LLSD::Binary materialBinary; +		materialBinary.resize(materialSize); +		memcpy(materialBinary.data(), materialString.data(), materialSize); + +		LLSD postData = LLSD::emptyMap(); +		postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary; + +		LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("POST", capURL, boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id)); +		LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials."  +			<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL; +		LLHTTPClient::post(capURL, postData, materialsResponder); +	} +} + +void LLMaterialMgr::processGetAllQueue() +{ +	getall_queue_t::iterator loopRegion = mGetAllQueue.begin(); +	while (mGetAllQueue.end() != loopRegion) +	{ +		getall_queue_t::iterator itRegion = loopRegion++; + +		const LLUUID& region_id = *itRegion; +		LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id); +		if (regionp == NULL) +		{ +			LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL; +			clearGetQueues(region_id);		// Invalidates region_id +			continue; +		} +		else if (!regionp->capabilitiesReceived()) +		{ +			continue; +		} + +		std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME); +		if (capURL.empty()) +		{ +			LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME +				<< "' is not defined on the current region '" << regionp->getName() << "'" << LL_ENDL; +			clearGetQueues(region_id);		// Invalidates region_id +			continue; +		} + +		LL_DEBUGS("Materials") << "GET all for region " << region_id << "url " << capURL << LL_ENDL; +		LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("GET", capURL, boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion)); +		LLHTTPClient::get(capURL, materialsResponder); +		mGetAllPending.insert(std::pair<LLUUID, F64>(region_id, LLFrameTimer::getTotalSeconds())); +		mGetAllQueue.erase(itRegion);	// Invalidates region_id +	} +} + +void LLMaterialMgr::processPutQueue() +{ +	typedef std::map<const LLViewerRegion*, LLSD> regionput_request_map; +	regionput_request_map requests; + +	put_queue_t::iterator loopQueue = mPutQueue.begin(); +	while (mPutQueue.end() != loopQueue) +	{ +		put_queue_t::iterator itQueue = loopQueue++; + +		const LLUUID& object_id = itQueue->first; +		const LLViewerObject* objectp = gObjectList.findObject(object_id); +		if ( (!objectp) || (!objectp->getRegion()) ) +		{ +			LL_WARNS("Materials") << "Object or object region is NULL" << LL_ENDL; + +			mPutQueue.erase(itQueue); +			continue; +		} + +		const LLViewerRegion* regionp = objectp->getRegion(); +		if (!regionp->capabilitiesReceived()) +		{ +			continue; +		} + +		LLSD& facesData = requests[regionp]; + +		facematerial_map_t& face_map = itQueue->second; +		facematerial_map_t::iterator itFace = face_map.begin(); +		while ( (face_map.end() != itFace) && (facesData.size() < MATERIALS_GET_MAX_ENTRIES) ) +		{ +			LLSD faceData = LLSD::emptyMap(); +			faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first); +			faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID()); +			if (!itFace->second.isNull()) +			{ +				faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD(); +			} +			facesData.append(faceData); +			face_map.erase(itFace++); +		} +		if (face_map.empty()) +		{ +			mPutQueue.erase(itQueue); +		} +	} + +	for (regionput_request_map::const_iterator itRequest = requests.begin(); itRequest != requests.end(); ++itRequest) +	{ +		std::string capURL = itRequest->first->getCapability(MATERIALS_CAPABILITY_NAME); +		if (capURL.empty()) +		{ +			LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME +				<< "' is not defined on region '" << itRequest->first->getName() << "'" << LL_ENDL; +			continue; +		} + +		LLSD materialsData = LLSD::emptyMap(); +		materialsData[MATERIALS_CAP_FULL_PER_FACE_FIELD] = itRequest->second; + +		std::string materialString = zip_llsd(materialsData); + +		S32 materialSize = materialString.size(); + +		if (materialSize > 0) +		{ +			LLSD::Binary materialBinary; +			materialBinary.resize(materialSize); +			memcpy(materialBinary.data(), materialString.data(), materialSize); + +			LLSD putData = LLSD::emptyMap(); +			putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary; + +			LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL; +			LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2)); +			LLHTTPClient::put(capURL, putData, materialsResponder); +		} +		else +		{ +			LL_ERRS("debugMaterials") << "cannot zip LLSD binary content" << LL_ENDL; +		} +	} +} + +void LLMaterialMgr::clearGetQueues(const LLUUID& region_id) +{ +	mGetQueue.erase(region_id); +	for (get_pending_map_t::iterator itPending = mGetPending.begin(); itPending != mGetPending.end();) +	{ +		if (region_id == itPending->first.first) +		{ +			mGetPending.erase(itPending++); +		} +		else +		{ +			++itPending; +		} +	} + +	mGetAllQueue.erase(region_id); +	mGetAllRequested.erase(region_id); +	mGetAllPending.erase(region_id); +	mGetAllCallbacks.erase(region_id); +} + +void LLMaterialMgr::onRegionRemoved(LLViewerRegion* regionp) +{ +	clearGetQueues(regionp->getRegionID()); +	// Put doesn't need clearing: objects that can't be found will clean up in processPutQueue() +} + diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h new file mode 100644 index 0000000000..e317a791ad --- /dev/null +++ b/indra/newview/llmaterialmgr.h @@ -0,0 +1,130 @@ +/** + * @file llmaterialmgr.h + * @brief Material manager + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLMATERIALMGR_H +#define LL_LLMATERIALMGR_H + +#include "llmaterial.h" +#include "llmaterialid.h" +#include "llsingleton.h" + +class LLViewerRegion; + +class LLMaterialMgr : public LLSingleton<LLMaterialMgr> +{ +	friend class LLSingleton<LLMaterialMgr>; +protected: +	LLMaterialMgr(); +	virtual ~LLMaterialMgr(); + +public: +	typedef std::map<LLMaterialID, LLMaterialPtr> material_map_t; + +	typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr)> get_callback_t; +	const LLMaterialPtr         get(const LLUUID& region_id, const LLMaterialID& material_id); +	boost::signals2::connection get(const LLUUID& region_id, const LLMaterialID& material_id, get_callback_t::slot_type cb); + +	typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr, U32 te)> get_callback_te_t; +	boost::signals2::connection getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, get_callback_te_t::slot_type cb); + +	typedef boost::signals2::signal<void (const LLUUID&, const material_map_t&)> getall_callback_t; +	void                        getAll(const LLUUID& region_id); +	boost::signals2::connection getAll(const LLUUID& region_id, getall_callback_t::slot_type cb); +	void put(const LLUUID& object_id, const U8 te, const LLMaterial& material); +	void remove(const LLUUID& object_id, const U8 te); + +protected: +	void clearGetQueues(const LLUUID& region_id); +	bool isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const; +	bool isGetAllPending(const LLUUID& region_id) const; +	void markGetPending(const LLUUID& region_id, const LLMaterialID& material_id); +	const LLMaterialPtr setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data); + +	static void onIdle(void*); +	void processGetQueue(); +	void onGetResponse(bool success, const LLSD& content, const LLUUID& region_id); +	void processGetAllQueue(); +	void onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id); +	void processPutQueue(); +	void onPutResponse(bool success, const LLSD& content); +	void onRegionRemoved(LLViewerRegion* regionp); + +protected: +	typedef std::set<LLMaterialID> material_queue_t; +	typedef std::map<LLUUID, material_queue_t> get_queue_t; +	get_queue_t        mGetQueue; +	typedef std::pair<const LLUUID, LLMaterialID> pending_material_t; +	typedef std::map<const pending_material_t, F64> get_pending_map_t; +	get_pending_map_t  mGetPending; +	typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t; +	get_callback_map_t mGetCallbacks; + +	// struct for TE-specific material ID query +	class TEMaterialPair +	{ +	public: + +		U32 te; +		LLMaterialID materialID; + +		bool operator==(const TEMaterialPair& b) const { return (materialID == b.materialID) && (te == b.te); } +	}; +	 +	friend inline bool operator<( +		const LLMaterialMgr::TEMaterialPair& lhs, +		const LLMaterialMgr::TEMaterialPair& rhs) +	{ +		return (lhs.te	< rhs.te) ? TRUE : +			(lhs.materialID < rhs.materialID); +	} + +	struct TEMaterialPairHasher +	{ +		enum { bucket_size = 8 }; +		size_t operator()(const TEMaterialPair& key_value) const { return *((size_t*)key_value.materialID.get());  } // cheesy, but effective +		bool   operator()(const TEMaterialPair& left, const TEMaterialPair& right) const { return left < right; } +	}; + +	typedef boost::unordered_map<TEMaterialPair, get_callback_te_t*, TEMaterialPairHasher> get_callback_te_map_t; +	get_callback_te_map_t mGetTECallbacks; + +	typedef std::set<LLUUID> getall_queue_t; +	getall_queue_t        mGetAllQueue; +	getall_queue_t        mGetAllRequested; +	typedef std::map<LLUUID, F64> getall_pending_map_t; +	getall_pending_map_t  mGetAllPending; +	typedef std::map<LLUUID, getall_callback_t*> getall_callback_map_t; +	getall_callback_map_t mGetAllCallbacks; + +	typedef std::map<U8, LLMaterial> facematerial_map_t; +	typedef std::map<LLUUID, facematerial_map_t> put_queue_t; +	put_queue_t mPutQueue; + +	material_map_t mMaterials; +}; + +#endif // LL_LLMATERIALMGR_H + diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index 6533d55f2f..81acc31863 100755 --- a/indra/newview/llpaneleditwearable.h +++ b/indra/newview/llpaneleditwearable.h @@ -95,7 +95,7 @@ private:  	void				toggleTypeSpecificControls(LLWearableType::EType type);  	void				updateTypeSpecificControls(LLWearableType::EType type); -	// alpha mask checkboxes +	//alpha mask checkboxes  	void configureAlphaCheckbox(LLAvatarAppearanceDefines::ETextureIndex te, const std::string& name);  	void onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te);  	void updateAlphaCheckboxes(); @@ -155,7 +155,7 @@ private:  	LLPanel *mPanelEyes;  	LLPanel *mPanelHair; -	// clothes +	//clothes  	LLPanel *mPanelShirt;  	LLPanel *mPanelPants;  	LLPanel *mPanelShoes; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 445c0d811f..911af9df04 100755 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -46,6 +46,7 @@  #include "lldrawpoolbump.h"  #include "llface.h"  #include "lllineeditor.h" +#include "llmaterialmgr.h"  #include "llmediaentry.h"  #include "llnotificationsutil.h"  #include "llresmgr.h" @@ -55,10 +56,12 @@  #include "lltexturectrl.h"  #include "lltextureentry.h"  #include "lltooldraganddrop.h" +#include "lltrans.h"  #include "llui.h"  #include "llviewercontrol.h"  #include "llviewermedia.h"  #include "llviewerobject.h" +#include "llviewerregion.h"  #include "llviewerstats.h"  #include "llvovolume.h"  #include "lluictrlfactory.h" @@ -66,6 +69,48 @@  #include "llviewertexturelist.h"  // +// Constant definitions for comboboxes +// Must match the commbobox definitions in panel_tools_texture.xml +// +const S32 MATMEDIA_MATERIAL = 0;	// Material +const S32 MATMEDIA_MEDIA = 1;		// Media +const S32 MATTYPE_DIFFUSE = 0;		// Diffuse material texture +const S32 MATTYPE_NORMAL = 1;		// Normal map +const S32 MATTYPE_SPECULAR = 2;		// Specular map +const S32 ALPHAMODE_NONE = 0;		// No alpha mask applied +const S32 ALPHAMODE_BLEND = 1;		// Alpha blending mode +const S32 ALPHAMODE_MASK = 2;		// Alpha masking mode +const S32 BUMPY_TEXTURE = 18;		// use supplied normal map +const S32 SHINY_TEXTURE = 4;		// use supplied specular map + +// +// "Use texture" label for normal/specular type comboboxes +// Filled in at initialization from translated strings +// +std::string USE_TEXTURE; + +// Things the UI provides... +// +LLUUID	LLPanelFace::getCurrentNormalMap()			{ return getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID();	} +LLUUID	LLPanelFace::getCurrentSpecularMap()		{ return getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID();	} +U32		LLPanelFace::getCurrentShininess()			{ return getChild<LLComboBox>("combobox shininess")->getCurrentIndex();			} +U32		LLPanelFace::getCurrentBumpiness()			{ return getChild<LLComboBox>("combobox bumpiness")->getCurrentIndex();			} +U8			LLPanelFace::getCurrentDiffuseAlphaMode()	{ return (U8)getChild<LLComboBox>("combobox alphamode")->getCurrentIndex();	} +U8			LLPanelFace::getCurrentAlphaMaskCutoff()	{ return (U8)getChild<LLUICtrl>("maskcutoff")->getValue().asInteger();			} +U8			LLPanelFace::getCurrentEnvIntensity()		{ return (U8)getChild<LLUICtrl>("environment")->getValue().asInteger();			} +U8			LLPanelFace::getCurrentGlossiness()			{ return (U8)getChild<LLUICtrl>("glossiness")->getValue().asInteger();			} +F32		LLPanelFace::getCurrentBumpyRot()			{ return getChild<LLUICtrl>("bumpyRot")->getValue().asReal();						} +F32		LLPanelFace::getCurrentBumpyScaleU()		{ return getChild<LLUICtrl>("bumpyScaleU")->getValue().asReal();					} +F32		LLPanelFace::getCurrentBumpyScaleV()		{ return getChild<LLUICtrl>("bumpyScaleV")->getValue().asReal();					} +F32		LLPanelFace::getCurrentBumpyOffsetU()		{ return getChild<LLUICtrl>("bumpyOffsetU")->getValue().asReal();					} +F32		LLPanelFace::getCurrentBumpyOffsetV()		{ return getChild<LLUICtrl>("bumpyOffsetV")->getValue().asReal();					} +F32		LLPanelFace::getCurrentShinyRot()			{ return getChild<LLUICtrl>("shinyRot")->getValue().asReal();						} +F32		LLPanelFace::getCurrentShinyScaleU()		{ return getChild<LLUICtrl>("shinyScaleU")->getValue().asReal();					} +F32		LLPanelFace::getCurrentShinyScaleV()		{ return getChild<LLUICtrl>("shinyScaleV")->getValue().asReal();					} +F32		LLPanelFace::getCurrentShinyOffsetU()		{ return getChild<LLUICtrl>("shinyOffsetU")->getValue().asReal();					} +F32		LLPanelFace::getCurrentShinyOffsetV()		{ return getChild<LLUICtrl>("shinyOffsetV")->getValue().asReal();					} + +//  // Methods  // @@ -73,21 +118,40 @@ BOOL	LLPanelFace::postBuild()  {  	childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);  	childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this); +	childSetCommitCallback("combobox alphamode",&LLPanelFace::onCommitAlphaMode,this);  	childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this); -	childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this);  	childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this); -	childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this);  	childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this); -	childSetAction("button apply",&LLPanelFace::onClickApply,this); +	childSetCommitCallback("rptctrl",&LLPanelFace::onCommitRepeatsPerMeter, this);  	childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this);  	childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);  	childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this); + +	childSetCommitCallback("bumpyScaleU",&LLPanelFace::onCommitMaterialBumpyScaleX, this); +	childSetCommitCallback("bumpyScaleV",&LLPanelFace::onCommitMaterialBumpyScaleY, this); +	childSetCommitCallback("bumpyRot",&LLPanelFace::onCommitMaterialBumpyRot, this); +	childSetCommitCallback("bumpyOffsetU",&LLPanelFace::onCommitMaterialBumpyOffsetX, this); +	childSetCommitCallback("bumpyOffsetV",&LLPanelFace::onCommitMaterialBumpyOffsetY, this); +	childSetCommitCallback("shinyScaleU",&LLPanelFace::onCommitMaterialShinyScaleX, this); +	childSetCommitCallback("shinyScaleV",&LLPanelFace::onCommitMaterialShinyScaleY, this); +	childSetCommitCallback("shinyRot",&LLPanelFace::onCommitMaterialShinyRot, this); +	childSetCommitCallback("shinyOffsetU",&LLPanelFace::onCommitMaterialShinyOffsetX, this); +	childSetCommitCallback("shinyOffsetV",&LLPanelFace::onCommitMaterialShinyOffsetY, this); +	childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this); +	childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this); +	childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this); +  	childSetAction("button align",&LLPanelFace::onClickAutoFix,this);  	LLTextureCtrl*	mTextureCtrl; +	LLTextureCtrl*	mShinyTextureCtrl; +	LLTextureCtrl*	mBumpyTextureCtrl;  	LLColorSwatchCtrl*	mColorSwatch; +	LLColorSwatchCtrl*	mShinyColorSwatch;  	LLComboBox*		mComboTexGen; +	LLComboBox*		mComboMatMedia; +	LLComboBox*		mComboMatType;  	LLCheckBoxCtrl	*mCheckFullbright; @@ -97,6 +161,7 @@ BOOL	LLPanelFace::postBuild()  	LLSpinCtrl*     mCtrlGlow;  	setMouseOpaque(FALSE); +  	mTextureCtrl = getChild<LLTextureCtrl>("texture control");  	if(mTextureCtrl)  	{ @@ -106,12 +171,49 @@ BOOL	LLPanelFace::postBuild()  		mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );  		mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));  		mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); +		mTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); +  		mTextureCtrl->setFollowsTop();  		mTextureCtrl->setFollowsLeft();  		mTextureCtrl->setImmediateFilterPermMask(PERM_NONE);  		mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);  	} +	mShinyTextureCtrl = getChild<LLTextureCtrl>("shinytexture control"); +	if(mShinyTextureCtrl) +	{ +		mShinyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectSpecularTexture" ))); +		mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitSpecularTexture, this, _2) ); +		mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelSpecularTexture, this, _2) ); +		mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectSpecularTexture, this, _2) ); +		mShinyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); +		 +		mShinyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); +		mShinyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); +		mShinyTextureCtrl->setFollowsTop(); +		mShinyTextureCtrl->setFollowsLeft(); +		mShinyTextureCtrl->setImmediateFilterPermMask(PERM_NONE); +		mShinyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); +	} + +	mBumpyTextureCtrl = getChild<LLTextureCtrl>("bumpytexture control"); +	if(mBumpyTextureCtrl) +	{ +		mBumpyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectNormalTexture" ))); +		mBumpyTextureCtrl->setBlankImageAssetID(LLUUID( gSavedSettings.getString( "DefaultBlankNormalTexture" ))); +		mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitNormalTexture, this, _2) ); +		mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelNormalTexture, this, _2) ); +		mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectNormalTexture, this, _2) ); +		mBumpyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); + +		mBumpyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); +		mBumpyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); +		mBumpyTextureCtrl->setFollowsTop(); +		mBumpyTextureCtrl->setFollowsLeft(); +		mBumpyTextureCtrl->setImmediateFilterPermMask(PERM_NONE); +		mBumpyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); +	} +  	mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");  	if(mColorSwatch)  	{ @@ -123,6 +225,15 @@ BOOL	LLPanelFace::postBuild()  		mColorSwatch->setCanApplyImmediately(TRUE);  	} +	mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch"); +	if(mShinyColorSwatch) +	{ +		mShinyColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitShinyColor, this, _2)); +		mShinyColorSwatch->setFollowsTop(); +		mShinyColorSwatch->setFollowsLeft(); +		mShinyColorSwatch->setCanApplyImmediately(TRUE); +	} +  	mLabelColorTransp = getChild<LLTextBox>("color trans");  	if(mLabelColorTransp)  	{ @@ -152,6 +263,20 @@ BOOL	LLPanelFace::postBuild()  		mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);	  	} +	mComboMatMedia = getChild<LLComboBox>("combobox matmedia"); +	if(mComboMatMedia) +	{ +		mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this); +		mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL); +	} + +	mComboMatType = getChild<LLComboBox>("combobox mattype"); +	if(mComboMatType) +	{ +		mComboMatType->setCommitCallback(LLPanelFace::onCommitMaterialType, this); +		mComboMatType->selectNthItem(MATTYPE_DIFFUSE); +	} +  	mCtrlGlow = getChild<LLSpinCtrl>("glow");  	if(mCtrlGlow)  	{ @@ -165,8 +290,10 @@ BOOL	LLPanelFace::postBuild()  }  LLPanelFace::LLPanelFace() -:	LLPanel() +:	LLPanel(), +	mIsAlpha(false)  { +	USE_TEXTURE = LLTrans::getString("use_texture");  } @@ -193,12 +320,32 @@ void LLPanelFace::sendTexture()  	}  } -void LLPanelFace::sendBump() +void LLPanelFace::sendBump(U32 bumpiness)  {	 -	LLComboBox*	mComboBumpiness = getChild<LLComboBox>("combobox bumpiness"); -	if(!mComboBumpiness)return; -	U8 bump = (U8) mComboBumpiness->getCurrentIndex() & TEM_BUMP_MASK; -	LLSelectMgr::getInstance()->selectionSetBumpmap( bump ); +	LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); +	if (bumpiness < BUMPY_TEXTURE) +	{ +		LL_DEBUGS("Materials") << "clearing bumptexture control" << LL_ENDL;	 +		bumpytexture_ctrl->clear(); +		bumpytexture_ctrl->setImageAssetID(LLUUID());		 +	} + +	updateBumpyControls(bumpiness == BUMPY_TEXTURE, true); + +	LLUUID current_normal_map = bumpytexture_ctrl->getImageAssetID(); + +	U8 bump = (U8) bumpiness & TEM_BUMP_MASK; + +	// Clear legacy bump to None when using an actual normal map +	// +	if (!current_normal_map.isNull()) +		bump = 0; + +	// Set the normal map or reset it to null as appropriate +	// +	LLSelectedTEMaterial::setNormalID(this, current_normal_map); + +	LLSelectMgr::getInstance()->selectionSetBumpmap( bump );	  }  void LLPanelFace::sendTexGen() @@ -209,12 +356,28 @@ void LLPanelFace::sendTexGen()  	LLSelectMgr::getInstance()->selectionSetTexGen( tex_gen );  } -void LLPanelFace::sendShiny() +void LLPanelFace::sendShiny(U32 shininess)  { -	LLComboBox*	mComboShininess = getChild<LLComboBox>("combobox shininess"); -	if(!mComboShininess)return; -	U8 shiny = (U8) mComboShininess->getCurrentIndex() & TEM_SHINY_MASK; +	LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control"); + +	if (shininess < SHINY_TEXTURE) +	{		 +		texture_ctrl->clear(); +		texture_ctrl->setImageAssetID(LLUUID());		 +	} + +	LLUUID specmap = getCurrentSpecularMap(); + +	U8 shiny = (U8) shininess & TEM_SHINY_MASK; +	if (!specmap.isNull()) +		shiny = 0; + +	LLSelectedTEMaterial::setSpecularID(this, specmap); +  	LLSelectMgr::getInstance()->selectionSetShiny( shiny ); + +	updateShinyControls(!specmap.isNull(), true); +	  }  void LLPanelFace::sendFullbright() @@ -268,22 +431,16 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor  		LLSpinCtrl*	ctrlTexOffsetS = mPanel->getChild<LLSpinCtrl>("TexOffsetU");  		LLSpinCtrl*	ctrlTexOffsetT = mPanel->getChild<LLSpinCtrl>("TexOffsetV");  		LLSpinCtrl*	ctrlTexRotation = mPanel->getChild<LLSpinCtrl>("TexRot"); -		LLCheckBoxCtrl*	checkFlipScaleS = mPanel->getChild<LLCheckBoxCtrl>("checkbox flip s"); -		LLCheckBoxCtrl*	checkFlipScaleT = mPanel->getChild<LLCheckBoxCtrl>("checkbox flip t");  		LLComboBox*		comboTexGen = mPanel->getChild<LLComboBox>("combobox texgen");  		llassert(comboTexGen);  		llassert(object);  		if (ctrlTexScaleS)  		{ -			valid = !ctrlTexScaleS->getTentative() || !checkFlipScaleS->getTentative(); +			valid = !ctrlTexScaleS->getTentative(); // || !checkFlipScaleS->getTentative();  			if (valid)  			{  				value = ctrlTexScaleS->get(); -				if( checkFlipScaleS->get() ) -				{ -					value = -value; -				}  				if (comboTexGen &&  				    comboTexGen->getCurrentIndex() == 1)  				{ @@ -295,14 +452,14 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor  		if (ctrlTexScaleT)  		{ -			valid = !ctrlTexScaleT->getTentative() || !checkFlipScaleT->getTentative(); +			valid = !ctrlTexScaleT->getTentative(); // || !checkFlipScaleT->getTentative();  			if (valid)  			{  				value = ctrlTexScaleT->get(); -				if( checkFlipScaleT->get() ) -				{ -					value = -value; -				} +				//if( checkFlipScaleT->get() ) +				//{ +				//	value = -value; +				//}  				if (comboTexGen &&  				    comboTexGen->getCurrentIndex() == 1)  				{ @@ -458,16 +615,9 @@ void LLPanelFace::sendTextureInfo()  {  	if ((bool)childGetValue("checkbox planar align").asBoolean())  	{ -		struct f1 : public LLSelectedTEGetFunctor<LLFace *> -		{ -			LLFace* get(LLViewerObject* object, S32 te) -			{ -				return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; -			} -		} get_last_face_func; -		LLFace* last_face; -		LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_last_face_func, last_face); - +		LLFace* last_face = NULL; +		bool identical_face =false; +		LLSelectedTE::getFace(last_face, identical_face);		  		LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face);  		LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);  	} @@ -483,6 +633,11 @@ void LLPanelFace::sendTextureInfo()  void LLPanelFace::getState()  { +	updateUI(); +} + +void LLPanelFace::updateUI() +{ //set state of UI to match state of texture entry(ies)  (calls setEnabled, setValue, etc, but NOT setVisible)  	LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();  	if( objectp @@ -492,409 +647,727 @@ void LLPanelFace::getState()  		BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();  		// only turn on auto-adjust button if there is a media renderer and the media is loaded -		getChildView("textbox autofix")->setEnabled(editable);  		getChildView("button align")->setEnabled(editable); + +		LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia"); +		if (combobox_matmedia) +		{ +			if (combobox_matmedia->getCurrentIndex() < MATMEDIA_MATERIAL) +			{ +				combobox_matmedia->selectNthItem(MATMEDIA_MATERIAL); +			} +		} +		else +		{ +			llwarns << "failed getChild for 'combobox matmedia'" << llendl; +		} +		getChildView("combobox matmedia")->setEnabled(editable); + +		LLComboBox* combobox_mattype = getChild<LLComboBox>("combobox mattype"); +		if (combobox_mattype) +		{ +			if (combobox_mattype->getCurrentIndex() < MATTYPE_DIFFUSE) +			{ +				combobox_mattype->selectNthItem(MATTYPE_DIFFUSE); +			} +		} +		else +		{ +			LL_WARNS("Materials") << "failed getChild for 'combobox mattype'" << LL_ENDL; +		} +		getChildView("combobox mattype")->setEnabled(editable); + +		updateVisibility(); + +		bool identical				= true;	// true because it is anded below +      bool identical_diffuse	= false; +      bool identical_norm		= false; +      bool identical_spec		= false; +         +		LLTextureCtrl*	texture_ctrl		= getChild<LLTextureCtrl>("texture control"); +		LLTextureCtrl*	shinytexture_ctrl = getChild<LLTextureCtrl>("shinytexture control"); +		LLTextureCtrl*	bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); -		//if ( LLMediaEngine::getInstance()->getMediaRenderer () ) -		//	if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () ) -		//	{	 -		//		 -		//		//mLabelTexAutoFix->setEnabled ( editable ); -		//		 -		//		//mBtnAutoFix->setEnabled ( editable ); -		//	} -		getChildView("button apply")->setEnabled(editable); - -		bool identical; -		LLTextureCtrl*	texture_ctrl = getChild<LLTextureCtrl>("texture control"); +		LLUUID id; +		LLUUID normmap_id; +		LLUUID specmap_id; + +		// Color swatch +		{ +			getChildView("color label")->setEnabled(editable); +		} +		LLColorSwatchCtrl*	mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch"); + +		LLColor4 color					= LLColor4::white; +		bool		identical_color	= false; + +		if(mColorSwatch) +		{ +			LLSelectedTE::getColor(color, identical_color); + +			mColorSwatch->setOriginal(color); +			mColorSwatch->set(color, TRUE); + +			mColorSwatch->setValid(editable); +			mColorSwatch->setEnabled( editable ); +			mColorSwatch->setCanApplyImmediately( editable ); +		} + +		// Color transparency +		getChildView("color trans")->setEnabled(editable); + +		F32 transparency = (1.f - color.mV[VALPHA]) * 100.f; +		getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0); +		getChildView("ColorTrans")->setEnabled(editable); + +		// Specular map +		LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec); -		// Texture +		U8 shiny = 0; +		bool identical_shiny = false; + +		// Shiny +		LLSelectedTE::getShiny(shiny, identical_shiny); +		identical = identical && identical_shiny; + +		shiny = specmap_id.isNull() ? shiny : SHINY_TEXTURE; + +		LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess"); +		if (combobox_shininess)  		{ -			LLUUID id; -			struct f1 : public LLSelectedTEGetFunctor<LLUUID> +			combobox_shininess->selectNthItem((S32)shiny); +		} + +		getChildView("label shininess")->setEnabled(editable); +		getChildView("combobox shininess")->setEnabled(editable); + +		getChildView("label glossiness")->setEnabled(editable);			 +		getChildView("glossiness")->setEnabled(editable); + +		getChildView("label environment")->setEnabled(editable); +		getChildView("environment")->setEnabled(editable); +		getChildView("label shinycolor")->setEnabled(editable); + +		getChild<LLUICtrl>("combobox shininess")->setTentative(!identical_spec); +		getChild<LLUICtrl>("glossiness")->setTentative(!identical_spec); +		getChild<LLUICtrl>("environment")->setTentative(!identical_spec);			 +		getChild<LLUICtrl>("shinycolorswatch")->setTentative(!identical_spec); + +		LLColorSwatchCtrl*	mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch"); +		if(mShinyColorSwatch) +		{ +			mShinyColorSwatch->setValid(editable); +			mShinyColorSwatch->setEnabled( editable ); +			mShinyColorSwatch->setCanApplyImmediately( editable ); +		} + +		U8 bumpy = 0; +		// Bumpy +		{		 +			bool identical_bumpy = false; +			LLSelectedTE::getBumpmap(bumpy,identical_bumpy); + +			LLUUID norm_map_id = getCurrentNormalMap(); +			LLCtrlSelectionInterface* combobox_bumpiness = childGetSelectionInterface("combobox bumpiness"); + +			bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE; + +			if (combobox_bumpiness)  			{ -				LLUUID get(LLViewerObject* object, S32 te_index) -				{ -					LLUUID id; -					 -					LLViewerTexture* image = object->getTEImage(te_index); -					if (image) id = image->getID(); -					 -					if (!id.isNull() && LLViewerMedia::textureHasMedia(id)) -					{ -						LLTextureEntry *te = object->getTE(te_index); -						if (te) -						{ -							LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL ; -							if(!tex) -							{ -								tex = LLViewerFetchedTexture::sDefaultImagep; -							} -							if (tex) -							{ -								id = tex->getID(); -							} -						} -					} -					return id; -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); +				combobox_bumpiness->selectNthItem((S32)bumpy); +			} +			else +			{ +				llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl; +			} + +			getChildView("combobox bumpiness")->setEnabled(editable); +			getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical_bumpy); +			getChildView("label bumpiness")->setEnabled(editable); +		} + +		// Texture +		{ +			LLSelectedTE::getTexId(id,identical_diffuse); + +			// Normal map +			LLSelectedTEMaterial::getNormalID(normmap_id, identical_norm); + +			mIsAlpha = FALSE; +			LLGLenum image_format = GL_RGB; +			bool identical_image_format = false; +			LLSelectedTE::getImageFormat(image_format, identical_image_format); +             +         mIsAlpha = FALSE; +         switch (image_format) +         { +               case GL_RGBA: +               case GL_ALPHA: +               { +                  mIsAlpha = TRUE; +               } +               break; + +               case GL_RGB: break; +               default: +               { +                  llwarns << "Unexpected tex format in LLPanelFace...resorting to no alpha" << llendl; +               } +               break; +         }  			if(LLViewerMedia::textureHasMedia(id))  			{ -				getChildView("textbox autofix")->setEnabled(editable);  				getChildView("button align")->setEnabled(editable);  			} -			if (identical) +			// Diffuse Alpha Mode + +			// Init to the default that is appropriate for the alpha content of the asset +			// +			U8 alpha_mode = mIsAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + +			bool identical_alpha_mode = false; + +			// See if that's been overridden by a material setting for same... +			// +			LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha); + +			LLCtrlSelectionInterface* combobox_alphamode = childGetSelectionInterface("combobox alphamode"); +			if (combobox_alphamode) +			{ +				//it is invalid to have any alpha mode other than blend if transparency is greater than zero ...  +				// Want masking? Want emissive? Tough! You get BLEND! +				alpha_mode = (transparency > 0.f) ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : alpha_mode; + +				// ... unless there is no alpha channel in the texture, in which case alpha mode MUST be none +				alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + +				combobox_alphamode->selectNthItem(alpha_mode); +			} +			else +			{ +				llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl; +			} + +			updateAlphaControls(); +			 +			if(texture_ctrl)  			{ -				// All selected have the same texture -				if(texture_ctrl) +				if (identical_diffuse) +				{ +					texture_ctrl->setTentative( FALSE ); +					texture_ctrl->setEnabled( editable ); +					texture_ctrl->setImageAssetID( id ); +					getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f); +					getChildView("label alphamode")->setEnabled(editable && mIsAlpha); +					getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); +					getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); +				} +				else if (id.isNull())  				{ +					// None selected  					texture_ctrl->setTentative( FALSE ); +					texture_ctrl->setEnabled( FALSE ); +					texture_ctrl->setImageAssetID( LLUUID::null ); +					getChildView("combobox alphamode")->setEnabled( FALSE ); +					getChildView("label alphamode")->setEnabled( FALSE ); +					getChildView("maskcutoff")->setEnabled( FALSE); +					getChildView("label maskcutoff")->setEnabled( FALSE ); +				} +				else +				{ +					// Tentative: multiple selected with different textures +					texture_ctrl->setTentative( TRUE );  					texture_ctrl->setEnabled( editable );  					texture_ctrl->setImageAssetID( id ); +					getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f); +					getChildView("label alphamode")->setEnabled(editable && mIsAlpha); +					getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); +					getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);  				}  			} -			else -			{ -				if(texture_ctrl) +             +         if (shinytexture_ctrl) +         { +				if (identical_spec && (shiny == SHINY_TEXTURE))  				{ -					if( id.isNull() ) -					{ -						// None selected -						texture_ctrl->setTentative( FALSE ); -						texture_ctrl->setEnabled( FALSE ); -						texture_ctrl->setImageAssetID( LLUUID::null ); -					} -					else -					{ -						// Tentative: multiple selected with different textures -						texture_ctrl->setTentative( TRUE ); -						texture_ctrl->setEnabled( editable ); -						texture_ctrl->setImageAssetID( id ); -					} +					shinytexture_ctrl->setTentative( FALSE ); +					shinytexture_ctrl->setEnabled( editable ); +					shinytexture_ctrl->setImageAssetID( specmap_id ); +            } +            else if (specmap_id.isNull()) +				{ +               shinytexture_ctrl->setTentative( FALSE ); +               shinytexture_ctrl->setEnabled( editable ); +					shinytexture_ctrl->setImageAssetID( LLUUID::null ); +            } +            else +            { +					shinytexture_ctrl->setTentative( TRUE ); +					shinytexture_ctrl->setEnabled( editable ); +					shinytexture_ctrl->setImageAssetID( specmap_id ); +				} +         } + +         if (bumpytexture_ctrl) +         { +				if (identical_norm && (bumpy == BUMPY_TEXTURE)) +				{ +					bumpytexture_ctrl->setTentative( FALSE ); +					bumpytexture_ctrl->setEnabled( editable ); +					bumpytexture_ctrl->setImageAssetID( normmap_id ); +				} +				else if (normmap_id.isNull()) +				{ +					bumpytexture_ctrl->setTentative( FALSE ); +					bumpytexture_ctrl->setEnabled( editable ); +					bumpytexture_ctrl->setImageAssetID( LLUUID::null ); +				} +            else +            { +					bumpytexture_ctrl->setTentative( TRUE ); +					bumpytexture_ctrl->setEnabled( editable ); +					bumpytexture_ctrl->setImageAssetID( normmap_id );  				}  			}  		} -  		// planar align  		bool align_planar = false;  		bool identical_planar_aligned = false; -		bool is_planar = false;  		{  			LLCheckBoxCtrl*	cb_planar_align = getChild<LLCheckBoxCtrl>("checkbox planar align");  			align_planar = (cb_planar_align && cb_planar_align->get()); -			struct f1 : public LLSelectedTEGetFunctor<bool> -			{ -				bool get(LLViewerObject* object, S32 face) -				{ -					return (object->getTE(face)->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR); -				} -			} func; - -			bool texgens_identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, is_planar ); -			bool enabled = (editable && texgens_identical && is_planar); +			 +			bool enabled = (editable && isIdenticalPlanarTexgen());  			childSetValue("checkbox planar align", align_planar && enabled);  			childSetEnabled("checkbox planar align", enabled);  			if (align_planar && enabled)  			{ -				struct f2 : public LLSelectedTEGetFunctor<LLFace *> -				{ -					LLFace* get(LLViewerObject* object, S32 te) -					{ -						return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; -					} -				} get_te_face_func; -				LLFace* last_face; -				LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, last_face); +				LLFace* last_face = NULL; +				bool identical_face = false; +				LLSelectedTE::getFace(last_face, identical_face); +  				LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face);  				// this will determine if the texture param controls are tentative:  				identical_planar_aligned = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&get_is_aligend_func);  			}  		} +		// Needs to be public and before tex scale settings below to properly reflect +		// behavior when in planar vs default texgen modes in the +		// NORSPEC-84 et al +		// +		LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT; +		bool identical_texgen = true;		 +		bool identical_planar_texgen = false; + +		{	 +			LLSelectedTE::getTexGen(selected_texgen, identical_texgen); +			identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); +		} +  		// Texture scale  		{ -			F32 scale_s = 1.f; -			struct f2 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return object->getTE(face)->mScaleS; -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_s ); +			bool identical_diff_scale_s = false; +			bool identical_spec_scale_s = false; +			bool identical_norm_scale_s = false; +  			identical = align_planar ? identical_planar_aligned : identical; -			getChild<LLUICtrl>("TexScaleU")->setValue(editable ? llabs(scale_s) : 0); -			getChild<LLUICtrl>("TexScaleU")->setTentative(LLSD((BOOL)(!identical))); + +			F32 diff_scale_s = 1.f;			 +			F32 spec_scale_s = 1.f; +			F32 norm_scale_s = 1.f; + +			LLSelectedTE::getScaleS(						diff_scale_s, identical_diff_scale_s);			 +			LLSelectedTEMaterial::getSpecularRepeatX( spec_scale_s, identical_spec_scale_s); +			LLSelectedTEMaterial::getNormalRepeatX(	norm_scale_s, identical_norm_scale_s); + +			diff_scale_s = editable ? diff_scale_s : 1.0f; +			diff_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; +			 +			norm_scale_s = editable ? norm_scale_s : 1.0f; +			norm_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; + +			spec_scale_s = editable ? spec_scale_s : 1.0f; +			spec_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; + +			getChild<LLUICtrl>("TexScaleU")->setValue(diff_scale_s); +			getChild<LLUICtrl>("shinyScaleU")->setValue(spec_scale_s); +			getChild<LLUICtrl>("bumpyScaleU")->setValue(norm_scale_s); +  			getChildView("TexScaleU")->setEnabled(editable); -			getChild<LLUICtrl>("checkbox flip s")->setValue(LLSD((BOOL)(scale_s < 0 ? TRUE : FALSE ))); -			getChild<LLUICtrl>("checkbox flip s")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE ))); -			getChildView("checkbox flip s")->setEnabled(editable); +			getChildView("shinyScaleU")->setEnabled(editable && specmap_id.notNull()); +			getChildView("bumpyScaleU")->setEnabled(editable && normmap_id.notNull()); + +			BOOL diff_scale_tentative = !(identical && identical_diff_scale_s); +			BOOL norm_scale_tentative = !(identical && identical_norm_scale_s); +			BOOL spec_scale_tentative = !(identical && identical_spec_scale_s); + +			getChild<LLUICtrl>("TexScaleU")->setTentative(  LLSD(diff_scale_tentative));			 +			getChild<LLUICtrl>("shinyScaleU")->setTentative(LLSD(spec_scale_tentative));			 +			getChild<LLUICtrl>("bumpyScaleU")->setTentative(LLSD(norm_scale_tentative));  		}  		{ -			F32 scale_t = 1.f; -			struct f3 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return object->getTE(face)->mScaleT; -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_t ); -			identical = align_planar ? identical_planar_aligned : identical; +			bool identical_diff_scale_t = false; +			bool identical_spec_scale_t = false; +			bool identical_norm_scale_t = false; + +			F32 diff_scale_t = 1.f;			 +			F32 spec_scale_t = 1.f; +			F32 norm_scale_t = 1.f; + +			LLSelectedTE::getScaleT(diff_scale_t, identical_diff_scale_t); +			LLSelectedTEMaterial::getSpecularRepeatY(spec_scale_t, identical_spec_scale_t); +			LLSelectedTEMaterial::getNormalRepeatY(norm_scale_t, identical_norm_scale_t); + +			diff_scale_t = editable ? diff_scale_t : 1.0f; +			diff_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; + +			norm_scale_t = editable ? norm_scale_t : 1.0f; +			norm_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; + +			spec_scale_t = editable ? spec_scale_t : 1.0f; +			spec_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; + +			BOOL diff_scale_tentative = !identical_diff_scale_t; +			BOOL norm_scale_tentative = !identical_norm_scale_t; +			BOOL spec_scale_tentative = !identical_spec_scale_t; -			getChild<LLUICtrl>("TexScaleV")->setValue(llabs(editable ? llabs(scale_t) : 0)); -			getChild<LLUICtrl>("TexScaleV")->setTentative(LLSD((BOOL)(!identical)));  			getChildView("TexScaleV")->setEnabled(editable); -			getChild<LLUICtrl>("checkbox flip t")->setValue(LLSD((BOOL)(scale_t< 0 ? TRUE : FALSE ))); -			getChild<LLUICtrl>("checkbox flip t")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE ))); -			getChildView("checkbox flip t")->setEnabled(editable); +			getChildView("shinyScaleV")->setEnabled(editable && specmap_id.notNull()); +			getChildView("bumpyScaleV")->setEnabled(editable && normmap_id.notNull()); + +			getChild<LLUICtrl>("TexScaleV")->setValue(diff_scale_t); +			getChild<LLUICtrl>("shinyScaleV")->setValue(norm_scale_t); +			getChild<LLUICtrl>("bumpyScaleV")->setValue(spec_scale_t); + +			getChild<LLUICtrl>("TexScaleV")->setTentative(LLSD(diff_scale_tentative)); +			getChild<LLUICtrl>("shinyScaleV")->setTentative(LLSD(norm_scale_tentative)); +			getChild<LLUICtrl>("bumpyScaleV")->setTentative(LLSD(spec_scale_tentative));  		}  		// Texture offset  		{ -			getChildView("tex offset")->setEnabled(editable); -			F32 offset_s = 0.f; -			struct f4 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return object->getTE(face)->mOffsetS; -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_s ); -			identical = align_planar ? identical_planar_aligned : identical; -			getChild<LLUICtrl>("TexOffsetU")->setValue(editable ? offset_s : 0); -			getChild<LLUICtrl>("TexOffsetU")->setTentative(!identical); +			bool identical_diff_offset_s = false; +			bool identical_norm_offset_s = false; +			bool identical_spec_offset_s = false; + +			F32 diff_offset_s = 0.0f; +			F32 norm_offset_s = 0.0f; +			F32 spec_offset_s = 0.0f; + +			LLSelectedTE::getOffsetS(diff_offset_s, identical_diff_offset_s); +			LLSelectedTEMaterial::getNormalOffsetX(norm_offset_s, identical_norm_offset_s); +			LLSelectedTEMaterial::getSpecularOffsetX(spec_offset_s, identical_spec_offset_s); + +			BOOL diff_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_s); +			BOOL norm_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_s); +			BOOL spec_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_s); + +			getChild<LLUICtrl>("TexOffsetU")->setValue(  editable ? diff_offset_s : 0.0f); +			getChild<LLUICtrl>("bumpyOffsetU")->setValue(editable ? norm_offset_s : 0.0f); +			getChild<LLUICtrl>("shinyOffsetU")->setValue(editable ? spec_offset_s : 0.0f); + +			getChild<LLUICtrl>("TexOffsetU")->setTentative(LLSD(diff_offset_u_tentative)); +			getChild<LLUICtrl>("shinyOffsetU")->setTentative(LLSD(norm_offset_u_tentative)); +			getChild<LLUICtrl>("bumpyOffsetU")->setTentative(LLSD(spec_offset_u_tentative)); +  			getChildView("TexOffsetU")->setEnabled(editable); +			getChildView("shinyOffsetU")->setEnabled(editable && specmap_id.notNull()); +			getChildView("bumpyOffsetU")->setEnabled(editable && normmap_id.notNull());  		}  		{ -			F32 offset_t = 0.f; -			struct f5 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return object->getTE(face)->mOffsetT; -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_t ); -			identical = align_planar ? identical_planar_aligned : identical; -			getChild<LLUICtrl>("TexOffsetV")->setValue(editable ? offset_t : 0); -			getChild<LLUICtrl>("TexOffsetV")->setTentative(!identical); +			bool identical_diff_offset_t = false; +			bool identical_norm_offset_t = false; +			bool identical_spec_offset_t = false; + +			F32 diff_offset_t = 0.0f; +			F32 norm_offset_t = 0.0f; +			F32 spec_offset_t = 0.0f; + +			LLSelectedTE::getOffsetT(diff_offset_t, identical_diff_offset_t); +			LLSelectedTEMaterial::getNormalOffsetY(norm_offset_t, identical_norm_offset_t); +			LLSelectedTEMaterial::getSpecularOffsetY(spec_offset_t, identical_spec_offset_t); +			 +			BOOL diff_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_t); +			BOOL norm_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_t); +			BOOL spec_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_t); + +			getChild<LLUICtrl>("TexOffsetV")->setValue(  editable ? diff_offset_t : 0.0f); +			getChild<LLUICtrl>("bumpyOffsetV")->setValue(editable ? norm_offset_t : 0.0f); +			getChild<LLUICtrl>("shinyOffsetV")->setValue(editable ? spec_offset_t : 0.0f); + +			getChild<LLUICtrl>("TexOffsetV")->setTentative(LLSD(diff_offset_v_tentative)); +			getChild<LLUICtrl>("shinyOffsetV")->setTentative(LLSD(norm_offset_v_tentative)); +			getChild<LLUICtrl>("bumpyOffsetV")->setTentative(LLSD(spec_offset_v_tentative)); +  			getChildView("TexOffsetV")->setEnabled(editable); +			getChildView("shinyOffsetV")->setEnabled(editable && specmap_id.notNull()); +			getChildView("bumpyOffsetV")->setEnabled(editable && normmap_id.notNull());  		}  		// Texture rotation  		{ -			F32 rotation = 0.f; -			struct f6 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return object->getTE(face)->mRotation; -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, rotation ); -			identical = align_planar ? identical_planar_aligned : identical; -			getChild<LLUICtrl>("TexRot")->setValue(editable ? rotation * RAD_TO_DEG : 0); -			getChild<LLUICtrl>("TexRot")->setTentative(!identical); -			getChildView("TexRot")->setEnabled(editable); -		} +			bool identical_diff_rotation = false; +			bool identical_norm_rotation = false; +			bool identical_spec_rotation = false; -		// Color swatch -		LLColorSwatchCtrl*	mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch"); -		LLColor4 color = LLColor4::white; -		if(mColorSwatch) -		{ -			struct f7 : public LLSelectedTEGetFunctor<LLColor4> -			{ -				LLColor4 get(LLViewerObject* object, S32 face) -				{ -					return object->getTE(face)->getColor(); -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, color ); -			 -			mColorSwatch->setOriginal(color); -			mColorSwatch->set(color, TRUE); +			F32 diff_rotation = 0.f; +			F32 norm_rotation = 0.f; +			F32 spec_rotation = 0.f; -			mColorSwatch->setValid(editable); -			mColorSwatch->setEnabled( editable ); -			mColorSwatch->setCanApplyImmediately( editable ); -		} -		// Color transparency -		{ -			getChildView("color trans")->setEnabled(editable); -		} +			LLSelectedTE::getRotation(diff_rotation,identical_diff_rotation); +			LLSelectedTEMaterial::getSpecularRotation(spec_rotation,identical_spec_rotation); +			LLSelectedTEMaterial::getNormalRotation(norm_rotation,identical_norm_rotation); -		F32 transparency = (1.f - color.mV[VALPHA]) * 100.f; -		{ -			getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0); -			getChildView("ColorTrans")->setEnabled(editable); -		} +			BOOL diff_rot_tentative = !(align_planar ? identical_planar_aligned : identical_diff_rotation); +			BOOL norm_rot_tentative = !(align_planar ? identical_planar_aligned : identical_norm_rotation); +			BOOL spec_rot_tentative = !(align_planar ? identical_planar_aligned : identical_spec_rotation); -		{ -			F32 glow = 0.f; -			struct f8 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return object->getTE(face)->getGlow(); -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, glow ); +			F32 diff_rot_deg = diff_rotation * RAD_TO_DEG; +			F32 norm_rot_deg = norm_rotation * RAD_TO_DEG; +			F32 spec_rot_deg = spec_rotation * RAD_TO_DEG; -			getChild<LLUICtrl>("glow")->setValue(glow); -			getChildView("glow")->setEnabled(editable); -			getChild<LLUICtrl>("glow")->setTentative(!identical); -			getChildView("glow label")->setEnabled(editable); +			getChildView("TexRot")->setEnabled(editable); +			getChildView("shinyRot")->setEnabled(editable && specmap_id.notNull()); +			getChildView("bumpyRot")->setEnabled(editable && normmap_id.notNull()); -		} +			getChild<LLUICtrl>("TexRot")->setTentative(diff_rot_tentative); +			getChild<LLUICtrl>("shinyRot")->setTentative(LLSD(norm_rot_tentative)); +			getChild<LLUICtrl>("bumpyRot")->setTentative(LLSD(spec_rot_tentative)); -		// Bump -		{ -			F32 shinyf = 0.f; -			struct f9 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return (F32)(object->getTE(face)->getShiny()); -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, shinyf ); -			LLCtrlSelectionInterface* combobox_shininess = -			      childGetSelectionInterface("combobox shininess"); -			if (combobox_shininess) -			{ -				combobox_shininess->selectNthItem((S32)shinyf); -			} -			else -			{ -				llwarns << "failed childGetSelectionInterface for 'combobox shininess'" << llendl; -			} -			getChildView("combobox shininess")->setEnabled(editable); -			getChild<LLUICtrl>("combobox shininess")->setTentative(!identical); -			getChildView("label shininess")->setEnabled(editable); +			getChild<LLUICtrl>("TexRot")->setValue(  editable ? diff_rot_deg : 0.0f);			 +			getChild<LLUICtrl>("shinyRot")->setValue(editable ? spec_rot_deg : 0.0f); +			getChild<LLUICtrl>("bumpyRot")->setValue(editable ? norm_rot_deg : 0.0f);  		}  		{ -			F32 bumpf = 0.f; -			struct f10 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return (F32)(object->getTE(face)->getBumpmap()); -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, bumpf ); -			LLCtrlSelectionInterface* combobox_bumpiness = -			      childGetSelectionInterface("combobox bumpiness"); -			if (combobox_bumpiness) -			{ -				combobox_bumpiness->selectNthItem((S32)bumpf); -			} -			else -			{ -				llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl; -			} -			getChildView("combobox bumpiness")->setEnabled(editable); -			getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical); -			getChildView("label bumpiness")->setEnabled(editable); +			F32 glow = 0.f; +			bool identical_glow = false; +			LLSelectedTE::getGlow(glow,identical_glow); +			getChild<LLUICtrl>("glow")->setValue(glow); +			getChild<LLUICtrl>("glow")->setTentative(!identical_glow); +			getChildView("glow")->setEnabled(editable); +			getChildView("glow label")->setEnabled(editable);			  		} -		{ -			F32 genf = 0.f; -			struct f11 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return (F32)(object->getTE(face)->getTexGen()); -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, genf ); -			S32 selected_texgen = ((S32) genf) >> TEM_TEX_GEN_SHIFT; -			LLCtrlSelectionInterface* combobox_texgen = -			      childGetSelectionInterface("combobox texgen"); +		{			 +			LLCtrlSelectionInterface* combobox_texgen = childGetSelectionInterface("combobox texgen");  			if (combobox_texgen)  			{ -				combobox_texgen->selectNthItem(selected_texgen); +				// Maps from enum to combobox entry index +				combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1);  			}  			else  			{  				llwarns << "failed childGetSelectionInterface for 'combobox texgen'" << llendl;  			} +  			getChildView("combobox texgen")->setEnabled(editable);  			getChild<LLUICtrl>("combobox texgen")->setTentative(!identical);  			getChildView("tex gen")->setEnabled(editable); -			if (selected_texgen == 1) +			if (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)  			{ -				getChild<LLUICtrl>("TexScaleU")->setValue(2.0f * getChild<LLUICtrl>("TexScaleU")->getValue().asReal() ); -				getChild<LLUICtrl>("TexScaleV")->setValue(2.0f * getChild<LLUICtrl>("TexScaleV")->getValue().asReal() ); -  				// EXP-1507 (change label based on the mapping mode)  				getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per meter"));  			}  			else -			if (selected_texgen == 0)  // FIXME: should not be magic numbers +			if (selected_texgen == LLTextureEntry::TEX_GEN_DEFAULT)  			{  				getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per face"));  			}  		}  		{ -			F32 fullbrightf = 0.f; -			struct f12 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return (F32)(object->getTE(face)->getFullbright()); -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, fullbrightf ); +			U8 fullbright_flag = 0; +			bool identical_fullbright = false; +			 +			LLSelectedTE::getFullbright(fullbright_flag,identical_fullbright); -			getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)fullbrightf); +			getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)(fullbright_flag != 0));  			getChildView("checkbox fullbright")->setEnabled(editable); -			getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical); +			getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical_fullbright);  		} -		// Repeats per meter label +		// Repeats per meter  		{ -			getChildView("rpt")->setEnabled(editable); +			F32 repeats_diff = 1.f; +			F32 repeats_norm = 1.f; +			F32 repeats_spec = 1.f; + +			bool identical_diff_repeats = false; +			bool identical_norm_repeats = false; +			bool identical_spec_repeats = false; + +			LLSelectedTE::getMaxDiffuseRepeats(repeats_diff, identical_diff_repeats); +			LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats); +			LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats);			 + +			LLComboBox*	mComboTexGen = getChild<LLComboBox>("combobox texgen"); +			if (mComboTexGen) +			{ +				S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0; +				BOOL enabled = editable && (index != 1); +				BOOL identical_repeats = true; +				F32  repeats = 1.0f; + +				U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? combobox_mattype->getCurrentIndex() : MATTYPE_DIFFUSE; +				switch (material_type) +				{ +					default: +					case MATTYPE_DIFFUSE: +					{ +						enabled = editable && !id.isNull(); +						identical_repeats = identical_diff_repeats; +						repeats = repeats_diff; +					} +					break; + +					case MATTYPE_SPECULAR: +					{ +						enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull())); +						identical_repeats = identical_spec_repeats; +						repeats = repeats_spec; +					} +					break; + +					case MATTYPE_NORMAL: +					{ +						enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull())); +						identical_repeats = identical_norm_repeats; +						repeats = repeats_norm; +					} +					break; +				} + +				BOOL repeats_tentative = !identical_repeats; + +				getChildView("rptctrl")->setEnabled(identical_planar_texgen ? FALSE : enabled); +				getChild<LLUICtrl>("rptctrl")->setValue(editable ? repeats : 1.0f); +				getChild<LLUICtrl>("rptctrl")->setTentative(LLSD(repeats_tentative)); +			}  		} -		// Repeats per meter +		// Materials  		{ -			F32 repeats = 1.f; -			struct f13 : public LLSelectedTEGetFunctor<F32> +			LLMaterialPtr material; +			LLSelectedTEMaterial::getCurrent(material, identical); + +			if (material && editable)  			{ -				F32 get(LLViewerObject* object, S32 face) +				LL_DEBUGS("Materials: OnMatererialsLoaded:") << material->asLLSD() << LL_ENDL; + +				// Alpha +				LLCtrlSelectionInterface* combobox_alphamode = +					childGetSelectionInterface("combobox alphamode"); +				if (combobox_alphamode) +				{ +					U32 alpha_mode = material->getDiffuseAlphaMode(); + +					if (transparency > 0.f) +					{ //it is invalid to have any alpha mode other than blend if transparency is greater than zero ...  +						alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; +					} + +					if (!mIsAlpha) +					{ // ... unless there is no alpha channel in the texture, in which case alpha mode MUST ebe none +						alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; +					} + +					combobox_alphamode->selectNthItem(alpha_mode); +				} +				else  				{ -					U32 s_axis = VX; -					U32 t_axis = VY; -					// BUG: Only repeats along S axis -					// BUG: Only works for boxes. -					LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); -					return object->getTE(face)->mScaleS / object->getScale().mV[s_axis]; +					llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl;  				} -			} func;			 -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, repeats ); -			 -			getChild<LLUICtrl>("rptctrl")->setValue(editable ? repeats : 0); -			getChild<LLUICtrl>("rptctrl")->setTentative(!identical); -			LLComboBox*	mComboTexGen = getChild<LLComboBox>("combobox texgen"); -			if (mComboTexGen) +				getChild<LLUICtrl>("maskcutoff")->setValue(material->getAlphaMaskCutoff()); +				updateAlphaControls(); + +				identical_planar_texgen = isIdenticalPlanarTexgen(); + +				// Shiny (specular) +				F32 offset_x, offset_y, repeat_x, repeat_y, rot; +				LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control"); +				texture_ctrl->setImageAssetID(material->getSpecularID()); + +				if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE)) +				{ +					material->getSpecularOffset(offset_x,offset_y); +					material->getSpecularRepeat(repeat_x,repeat_y); + +					if (identical_planar_texgen) +					{ +						repeat_x *= 2.0f; +						repeat_y *= 2.0f; +					} + +					rot = material->getSpecularRotation(); +					getChild<LLUICtrl>("shinyScaleU")->setValue(repeat_x); +					getChild<LLUICtrl>("shinyScaleV")->setValue(repeat_y); +					getChild<LLUICtrl>("shinyRot")->setValue(rot*RAD_TO_DEG); +					getChild<LLUICtrl>("shinyOffsetU")->setValue(offset_x); +					getChild<LLUICtrl>("shinyOffsetV")->setValue(offset_y); +					getChild<LLUICtrl>("glossiness")->setValue(material->getSpecularLightExponent()); +					getChild<LLUICtrl>("environment")->setValue(material->getEnvironmentIntensity()); + +					updateShinyControls(!material->getSpecularID().isNull(), true); +				} + +				// Assert desired colorswatch color to match material AFTER updateShinyControls +				// to avoid getting overwritten with the default on some UI state changes. +				// +				if (!material->getSpecularID().isNull()) +				{ +					getChild<LLColorSwatchCtrl>("shinycolorswatch")->setOriginal(material->getSpecularLightColor()); +					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()); + +				if (!material->getNormalID().isNull()) +				{ +					material->getNormalOffset(offset_x,offset_y); +					material->getNormalRepeat(repeat_x,repeat_y); + +					if (identical_planar_texgen) +					{ +						repeat_x *= 2.0f; +						repeat_y *= 2.0f; +					} + +					rot = material->getNormalRotation(); +					getChild<LLUICtrl>("bumpyScaleU")->setValue(repeat_x); +					getChild<LLUICtrl>("bumpyScaleV")->setValue(repeat_y); +					getChild<LLUICtrl>("bumpyRot")->setValue(rot*RAD_TO_DEG); +					getChild<LLUICtrl>("bumpyOffsetU")->setValue(offset_x); +					getChild<LLUICtrl>("bumpyOffsetV")->setValue(offset_y); + +					updateBumpyControls(!material->getNormalID().isNull(), true); +				} +			} +			else  			{ -				BOOL enabled = editable && (!mComboTexGen || mComboTexGen->getCurrentIndex() != 1); -				getChildView("rptctrl")->setEnabled(enabled); -				getChildView("button apply")->setEnabled(enabled); +				LLSelectMgr::getInstance()->setTextureChannel(LLRender::DIFFUSE_MAP);  			}  		} @@ -934,14 +1407,11 @@ void LLPanelFace::getState()  		getChildView("tex gen")->setEnabled(FALSE);  		getChildView("label shininess")->setEnabled(FALSE);  		getChildView("label bumpiness")->setEnabled(FALSE); - -		getChildView("textbox autofix")->setEnabled(FALSE); -  		getChildView("button align")->setEnabled(FALSE); -		getChildView("button apply")->setEnabled(FALSE);  		//getChildView("has media")->setEnabled(FALSE);  		//getChildView("media info set")->setEnabled(FALSE); -		 + +		updateVisibility();  		// Set variable values for numeric expressions  		LLCalc* calcp = LLCalc::getInstance(); @@ -958,6 +1428,7 @@ void LLPanelFace::getState()  void LLPanelFace::refresh()  { +	LL_DEBUGS("Materials") << LL_ENDL;  	getState();  } @@ -977,6 +1448,11 @@ void LLPanelFace::onCommitColor(const LLSD& data)  	sendColor();  } +void LLPanelFace::onCommitShinyColor(const LLSD& data) +{ +	LLSelectedTEMaterial::setSpecularLightColor(this, getChild<LLColorSwatchCtrl>("shinycolorswatch")->get()); +} +  void LLPanelFace::onCommitAlpha(const LLSD& data)  {  	sendAlpha(); @@ -994,10 +1470,121 @@ void LLPanelFace::onSelectColor(const LLSD& data)  }  // static +void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	// Force to default states to side-step problems with menu contents +	// and generally reflecting old state when switching tabs or objects +	// +	self->updateShinyControls(false,true); +	self->updateBumpyControls(false,true); +	self->updateUI(); +} + +// static +void LLPanelFace::updateVisibility() +{	 +	LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia"); +	LLComboBox* combo_mattype = getChild<LLComboBox>("combobox mattype"); +	LLComboBox* combo_shininess = getChild<LLComboBox>("combobox shininess"); +	LLComboBox* combo_bumpiness = getChild<LLComboBox>("combobox bumpiness"); +	if (!combo_mattype || !combo_matmedia || !combo_shininess || !combo_bumpiness) +	{ +		LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL; +		return; +	} +	U32 materials_media = combo_matmedia->getCurrentIndex(); +	U32 material_type = combo_mattype->getCurrentIndex(); +	bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled(); +	bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && combo_matmedia->getEnabled())); +	bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && combo_matmedia->getEnabled(); +	bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled(); +	getChildView("combobox mattype")->setVisible(!show_media); +	getChildView("rptctrl")->setVisible(true); + +	// Media controls +	getChildView("media_info")->setVisible(show_media); +	getChildView("add_media")->setVisible(show_media); +	getChildView("delete_media")->setVisible(show_media); +	getChildView("button align")->setVisible(show_media); + +	// Diffuse texture controls +	getChildView("texture control")->setVisible(show_texture && !show_media); +	getChildView("label alphamode")->setVisible(show_texture && !show_media); +	getChildView("combobox alphamode")->setVisible(show_texture && !show_media); +	getChildView("label maskcutoff")->setVisible(false); +	getChildView("maskcutoff")->setVisible(false); +	if (show_texture && !show_media) +	{ +		updateAlphaControls(); +	} +	getChildView("TexScaleU")->setVisible(show_texture); +	getChildView("TexScaleV")->setVisible(show_texture); +	getChildView("TexRot")->setVisible(show_texture); +	getChildView("TexOffsetU")->setVisible(show_texture); +	getChildView("TexOffsetV")->setVisible(show_texture); + +	// Specular map controls +	getChildView("shinytexture control")->setVisible(show_shininess); +	getChildView("combobox shininess")->setVisible(show_shininess); +	getChildView("label shininess")->setVisible(show_shininess); +	getChildView("label glossiness")->setVisible(false); +	getChildView("glossiness")->setVisible(false); +	getChildView("label environment")->setVisible(false); +	getChildView("environment")->setVisible(false); +	getChildView("label shinycolor")->setVisible(false); +	getChildView("shinycolorswatch")->setVisible(false); +	if (show_shininess) +	{ +		updateShinyControls(); +	} +	getChildView("shinyScaleU")->setVisible(show_shininess); +	getChildView("shinyScaleV")->setVisible(show_shininess); +	getChildView("shinyRot")->setVisible(show_shininess); +	getChildView("shinyOffsetU")->setVisible(show_shininess); +	getChildView("shinyOffsetV")->setVisible(show_shininess); + +	// Normal map controls +	if (show_bumpiness) +	{ +		updateBumpyControls(); +	} +	getChildView("bumpytexture control")->setVisible(show_bumpiness); +	getChildView("combobox bumpiness")->setVisible(show_bumpiness); +	getChildView("label bumpiness")->setVisible(show_bumpiness); +	getChildView("bumpyScaleU")->setVisible(show_bumpiness); +	getChildView("bumpyScaleV")->setVisible(show_bumpiness); +	getChildView("bumpyRot")->setVisible(show_bumpiness); +	getChildView("bumpyOffsetU")->setVisible(show_bumpiness); +	getChildView("bumpyOffsetV")->setVisible(show_bumpiness); + + +} + +// static +void LLPanelFace::onCommitMaterialType(LLUICtrl* ctrl, void* userdata) +{ +    LLPanelFace* self = (LLPanelFace*) userdata; +	 // Force to default states to side-step problems with menu contents +	 // and generally reflecting old state when switching tabs or objects +	 // +	 self->updateShinyControls(false,true); +	 self->updateBumpyControls(false,true); +    self->updateUI(); +} + +// static  void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata)  {  	LLPanelFace* self = (LLPanelFace*) userdata; -	self->sendBump(); + +	LLComboBox*	mComboBumpiness = self->getChild<LLComboBox>("combobox bumpiness"); +	if(!mComboBumpiness) +		return; + +	U32 bumpiness = mComboBumpiness->getCurrentIndex(); + +	self->sendBump(bumpiness);  }  // static @@ -1008,10 +1595,143 @@ void LLPanelFace::onCommitTexGen(LLUICtrl* ctrl, void* userdata)  }  // static +void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_shiny_combobox) +{ +	LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control"); +	LLUUID shiny_texture_ID = texture_ctrl->getImageAssetID(); +	LL_DEBUGS("Materials") << "Shiny texture selected: " << shiny_texture_ID << LL_ENDL; +	LLComboBox* comboShiny = getChild<LLComboBox>("combobox shininess"); + +	if(mess_with_shiny_combobox) +	{ +		if (!comboShiny) +		{ +			return; +		} +		if (!shiny_texture_ID.isNull() && is_setting_texture) +		{ +			if (!comboShiny->itemExists(USE_TEXTURE)) +			{ +				comboShiny->add(USE_TEXTURE); +			} +			comboShiny->setSimple(USE_TEXTURE); +		} +		else +		{ +			if (comboShiny->itemExists(USE_TEXTURE)) +			{ +				comboShiny->remove(SHINY_TEXTURE); +				comboShiny->selectFirstItem(); +			} +		} +	} + +	LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia"); +	LLComboBox* combo_mattype = getChild<LLComboBox>("combobox mattype"); +	U32 materials_media = combo_matmedia->getCurrentIndex(); +	U32 material_type = combo_mattype->getCurrentIndex(); +	bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled(); +	bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled(); +	U32 shiny_value = comboShiny->getCurrentIndex(); +	bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture +	getChildView("label glossiness")->setVisible(show_shinyctrls); +	getChildView("glossiness")->setVisible(show_shinyctrls); +	getChildView("label environment")->setVisible(show_shinyctrls); +	getChildView("environment")->setVisible(show_shinyctrls); +	getChildView("label shinycolor")->setVisible(show_shinyctrls); +	getChildView("shinycolorswatch")->setVisible(show_shinyctrls); +} + +// static +void LLPanelFace::updateBumpyControls(bool is_setting_texture, bool mess_with_combobox) +{ +	LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); +	LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID(); +	LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL; +	LLComboBox* comboBumpy = getChild<LLComboBox>("combobox bumpiness"); +	if (!comboBumpy) +	{ +		return; +	} + +	if (mess_with_combobox) +	{ +		LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); +		LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID(); +		LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL; + +		if (!bumpy_texture_ID.isNull() && is_setting_texture) +		{ +			if (!comboBumpy->itemExists(USE_TEXTURE)) +			{ +				comboBumpy->add(USE_TEXTURE); +			} +			comboBumpy->setSimple(USE_TEXTURE); +		} +		else +		{ +			if (comboBumpy->itemExists(USE_TEXTURE)) +			{ +				comboBumpy->remove(BUMPY_TEXTURE); +				comboBumpy->selectFirstItem(); +			} +		} +	} +} + +// static  void LLPanelFace::onCommitShiny(LLUICtrl* ctrl, void* userdata)  {  	LLPanelFace* self = (LLPanelFace*) userdata; -	self->sendShiny(); + + +	LLComboBox*	mComboShininess = self->getChild<LLComboBox>("combobox shininess"); +	if(!mComboShininess) +		return; +	 +	U32 shininess = mComboShininess->getCurrentIndex(); + +	self->sendShiny(shininess); +} + +// static +void LLPanelFace::updateAlphaControls() +{ +	LLComboBox* comboAlphaMode = getChild<LLComboBox>("combobox alphamode"); +	if (!comboAlphaMode) +	{ +		return; +	} +	U32 alpha_value = comboAlphaMode->getCurrentIndex(); +	bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking +     +    LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia"); +    U32 mat_media = MATMEDIA_MATERIAL; +    if (combobox_matmedia) +    { +        mat_media = combobox_matmedia->getCurrentIndex(); +    } +     +    LLComboBox* combobox_mattype = getChild<LLComboBox>("combobox mattype"); +    U32 mat_type = MATTYPE_DIFFUSE; +    if (combobox_mattype) +    { +        mat_type = combobox_mattype->getCurrentIndex(); +    } + +    show_alphactrls = show_alphactrls && (mat_media == MATMEDIA_MATERIAL); +    show_alphactrls = show_alphactrls && (mat_type == MATTYPE_DIFFUSE); +     +	getChildView("label maskcutoff")->setVisible(show_alphactrls); +	getChildView("maskcutoff")->setVisible(show_alphactrls); +} + +// static +void LLPanelFace::onCommitAlphaMode(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	self->updateAlphaControls(); +	LLSelectedTEMaterial::setDiffuseAlphaMode(self,self->getCurrentDiffuseAlphaMode());  }  // static @@ -1061,8 +1781,211 @@ void LLPanelFace::onSelectTexture(const LLSD& data)  {  	LLSelectMgr::getInstance()->saveSelectedObjectTextures();  	sendTexture(); + +	LLGLenum image_format; +	bool identical_image_format = false; +	LLSelectedTE::getImageFormat(image_format, identical_image_format); +     +	LLCtrlSelectionInterface* combobox_alphamode = +		childGetSelectionInterface("combobox alphamode"); + +	U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; +	if (combobox_alphamode) +	{ +		switch (image_format) +		{ +		case GL_RGBA: +		case GL_ALPHA: +			{ +				alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; +			} +			break; + +		case GL_RGB: break; +		default: +			{ +				llwarns << "Unexpected tex format in LLPanelFace...resorting to no alpha" << llendl; +			} +			break; +		} + +		combobox_alphamode->selectNthItem(alpha_mode); +	} +	LLSelectedTEMaterial::setDiffuseAlphaMode(this, getCurrentDiffuseAlphaMode()); +} + +void LLPanelFace::onCloseTexturePicker(const LLSD& data) +{ +	LL_DEBUGS("Materials") << data << LL_ENDL; +	updateUI(); +} + +void LLPanelFace::onCommitSpecularTexture( const LLSD& data ) +{ +	LL_DEBUGS("Materials") << data << LL_ENDL; +	sendShiny(SHINY_TEXTURE); +} + +void LLPanelFace::onCommitNormalTexture( const LLSD& data ) +{ +	LL_DEBUGS("Materials") << data << LL_ENDL; +	LLUUID nmap_id = getCurrentNormalMap(); +	sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE); +} + +void LLPanelFace::onCancelSpecularTexture(const LLSD& data) +{ +	U8 shiny = 0; +	bool identical_shiny = false; +	LLSelectedTE::getShiny(shiny, identical_shiny); +	LLUUID spec_map_id = getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID(); +	shiny = spec_map_id.isNull() ? shiny : SHINY_TEXTURE; +	sendShiny(shiny); +} + +void LLPanelFace::onCancelNormalTexture(const LLSD& data) +{ +	U8 bumpy = 0; +	bool identical_bumpy = false; +	LLSelectedTE::getBumpmap(bumpy, identical_bumpy); +	sendBump(bumpy);  } +void LLPanelFace::onSelectSpecularTexture(const LLSD& data) +{ +	LL_DEBUGS("Materials") << data << LL_ENDL; +	sendShiny(SHINY_TEXTURE); +} + +void LLPanelFace::onSelectNormalTexture(const LLSD& data) +{ +	LL_DEBUGS("Materials") << data << LL_ENDL; +	LLUUID nmap_id = getCurrentNormalMap(); +	sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE); +} + +//static +void LLPanelFace::onCommitMaterialBumpyOffsetX(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setNormalOffsetX(self,self->getCurrentBumpyOffsetU()); +} + +//static +void LLPanelFace::onCommitMaterialBumpyOffsetY(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setNormalOffsetY(self,self->getCurrentBumpyOffsetV()); +} + +//static +void LLPanelFace::onCommitMaterialShinyOffsetX(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setSpecularOffsetX(self,self->getCurrentShinyOffsetU()); +} + +//static +void LLPanelFace::onCommitMaterialShinyOffsetY(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setSpecularOffsetY(self,self->getCurrentShinyOffsetV()); +} + +//static +void LLPanelFace::onCommitMaterialBumpyScaleX(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	F32 bumpy_scale_u = self->getCurrentBumpyScaleU(); +	if (self->isIdenticalPlanarTexgen()) +	{ +		bumpy_scale_u *= 0.5f; +	} +	LLSelectedTEMaterial::setNormalRepeatX(self,bumpy_scale_u); +} + +//static +void LLPanelFace::onCommitMaterialBumpyScaleY(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	F32 bumpy_scale_v = self->getCurrentBumpyScaleV(); +	if (self->isIdenticalPlanarTexgen()) +	{ +		bumpy_scale_v *= 0.5f; +	} +	LLSelectedTEMaterial::setNormalRepeatY(self,bumpy_scale_v); +} + +//static +void LLPanelFace::onCommitMaterialShinyScaleX(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	F32 shiny_scale_u = self->getCurrentShinyScaleU(); +	if (self->isIdenticalPlanarTexgen()) +	{ +		shiny_scale_u *= 0.5f; +	} +	LLSelectedTEMaterial::setSpecularRepeatX(self,shiny_scale_u); +} + +//static +void LLPanelFace::onCommitMaterialShinyScaleY(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	F32 shiny_scale_v = self->getCurrentShinyScaleV(); +	if (self->isIdenticalPlanarTexgen()) +	{ +		shiny_scale_v *= 0.5f; +	} +	LLSelectedTEMaterial::setSpecularRepeatY(self,shiny_scale_v); +} + +//static +void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setNormalRotation(self,self->getCurrentBumpyRot() * DEG_TO_RAD); +} + +//static +void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setSpecularRotation(self,self->getCurrentShinyRot() * DEG_TO_RAD); +} + +//static +void LLPanelFace::onCommitMaterialGloss(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setSpecularLightExponent(self,self->getCurrentGlossiness()); +} + +//static +void LLPanelFace::onCommitMaterialEnv(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setEnvironmentIntensity(self,self->getCurrentEnvIntensity()); +} + +//static +void LLPanelFace::onCommitMaterialMaskCutoff(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	LLSelectedTEMaterial::setAlphaMaskCutoff(self,self->getCurrentAlphaMaskCutoff()); +}  // static  void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata ) @@ -1073,15 +1996,67 @@ void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata )  // Commit the number of repeats per meter  // static -void LLPanelFace::onClickApply(void* userdata) +void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)  {  	LLPanelFace* self = (LLPanelFace*) userdata; -	gFocusMgr.setKeyboardFocus( NULL ); +	LLUICtrl*	repeats_ctrl	= self->getChild<LLUICtrl>("rptctrl"); +	LLComboBox* combo_matmedia = self->getChild<LLComboBox>("combobox matmedia"); +	LLComboBox* combo_mattype	= self->getChild<LLComboBox>("combobox mattype"); +	 +	U32 materials_media = combo_matmedia->getCurrentIndex(); +	 + +	U32 material_type			= (materials_media == MATMEDIA_MATERIAL) ? combo_mattype->getCurrentIndex() : 0; +	F32 repeats_per_meter	= repeats_ctrl->getValue().asReal(); +	 +   F32 obj_scale_s = 1.0f; +   F32 obj_scale_t = 1.0f; + +	bool identical_scale_s = false; +	bool identical_scale_t = false; + +	LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s); +	LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t); +  +	switch (material_type) +	{ +		case MATTYPE_DIFFUSE: +		{ +			LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); +		} +		break; + +		case MATTYPE_NORMAL: +		{ +			LLUICtrl* bumpy_scale_u = self->getChild<LLUICtrl>("bumpyScaleU"); +			LLUICtrl* bumpy_scale_v = self->getChild<LLUICtrl>("bumpyScaleV"); +			 +			bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter); +			bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter); + +			LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter); +			LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter); +		} +		break; -	//F32 repeats_per_meter = self->mCtrlRepeatsPerMeter->get(); -	F32 repeats_per_meter = (F32)self->getChild<LLUICtrl>("rptctrl")->getValue().asReal();//self->mCtrlRepeatsPerMeter->get(); -	LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); +		case MATTYPE_SPECULAR: +		{ +			LLUICtrl* shiny_scale_u = self->getChild<LLUICtrl>("shinyScaleU"); +			LLUICtrl* shiny_scale_v = self->getChild<LLUICtrl>("shinyScaleV"); +			 +			shiny_scale_u->setValue(obj_scale_s * repeats_per_meter); +			shiny_scale_v->setValue(obj_scale_t * repeats_per_meter); + +			LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter); +			LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter); +		} +		break; + +		default: +			llassert(false); +		break; +	}  }  struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor @@ -1155,7 +2130,26 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)  void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)  { -	LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control"); +	LL_DEBUGS("Materials") << "item asset " << itemp->getAssetUUID() << LL_ENDL; +	LLComboBox* combo_mattype = getChild<LLComboBox>("combobox mattype"); +	if (!combo_mattype) +	{ +		return; +	} +	U32 mattype = combo_mattype->getCurrentIndex(); +	std::string which_control="texture control"; +	switch (mattype) +	{ +		case MATTYPE_SPECULAR: +			which_control = "shinytexture control"; +			break; +		case MATTYPE_NORMAL: +			which_control = "bumpytexture control"; +			break; +		// no default needed +	} +	LL_DEBUGS("Materials") << "control " << which_control << LL_ENDL; +	LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>(which_control);  	if (texture_ctrl)  	{  		LLUUID obj_owner_id; @@ -1185,3 +2179,212 @@ void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)  		}  	}  } + +bool LLPanelFace::isIdenticalPlanarTexgen() +{ +	LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT; +	bool identical_texgen = false; +	LLSelectedTE::getTexGen(selected_texgen, identical_texgen); +	return (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); +} + +void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical_face) +{		 +	struct LLSelectedTEGetFace : public LLSelectedTEGetFunctor<LLFace *> +	{ +		LLFace* get(LLViewerObject* object, S32 te) +		{ +			return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; +		} +	} get_te_face_func; +	identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return); +} + +void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face) +{ +	LLGLenum image_format; +	struct LLSelectedTEGetImageFormat : public LLSelectedTEGetFunctor<LLGLenum> +	{ +		LLGLenum get(LLViewerObject* object, S32 te_index) +		{ +			LLViewerTexture* image = object->getTEImage(te_index); +			return image ? image->getPrimaryFormat() : GL_RGB; +		} +	} get_glenum; +	identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_glenum, image_format); +	image_format_to_return = image_format; +} + +void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical) +{		 +	struct LLSelectedTEGetTexId : public LLSelectedTEGetFunctor<LLUUID> +	{ +		LLUUID get(LLViewerObject* object, S32 te_index) +		{ +			LLUUID id; +			LLViewerTexture* image = object->getTEImage(te_index); +			if (image) +			{ +				id = image->getID(); +			} + +			if (!id.isNull() && LLViewerMedia::textureHasMedia(id)) +			{ +				LLTextureEntry *te = object->getTE(te_index); +				if (te) +				{ +					LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL; +					if(!tex) +					{ +						tex = LLViewerFetchedTexture::sDefaultImagep; +					} +					if (tex) +					{ +						id = tex->getID(); +					} +				} +			} +			return id; +		} +	} func; +	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); +} + +void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, bool& identical_material) +{ +	struct MaterialFunctor : public LLSelectedTEGetFunctor<LLMaterialPtr> +	{ +		LLMaterialPtr get(LLViewerObject* object, S32 te_index) +		{ +			return object->getTE(te_index)->getMaterialParams(); +		} +	} func; +	identical_material = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_ptr); +} + +void LLPanelFace::LLSelectedTEMaterial::getMaxSpecularRepeats(F32& repeats, bool& identical) +{ +	struct LLSelectedTEGetMaxSpecRepeats : public LLSelectedTEGetFunctor<F32> +	{ +		F32 get(LLViewerObject* object, S32 face) +		{ +			LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); +			U32 s_axis = VX; +			U32 t_axis = VY; +			F32 repeats_s = 1.0f; +			F32 repeats_t = 1.0f; +			if (mat) +			{ +				mat->getSpecularRepeat(repeats_s, repeats_t); +				repeats_s /= object->getScale().mV[s_axis]; +				repeats_t /= object->getScale().mV[t_axis]; +			}					 +			return llmax(repeats_s, repeats_t); +		} + +	} max_spec_repeats_func; +	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_spec_repeats_func, repeats); +} + +void LLPanelFace::LLSelectedTEMaterial::getMaxNormalRepeats(F32& repeats, bool& identical) +{ +	struct LLSelectedTEGetMaxNormRepeats : public LLSelectedTEGetFunctor<F32> +	{ +		F32 get(LLViewerObject* object, S32 face) +		{ +			LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); +			U32 s_axis = VX; +			U32 t_axis = VY; +			F32 repeats_s = 1.0f; +			F32 repeats_t = 1.0f; +			if (mat) +			{ +				mat->getNormalRepeat(repeats_s, repeats_t); +				repeats_s /= object->getScale().mV[s_axis]; +				repeats_t /= object->getScale().mV[t_axis]; +			}					 +			return llmax(repeats_s, repeats_t); +		} + +	} max_norm_repeats_func; +	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_norm_repeats_func, repeats); +} + +void LLPanelFace::LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha) +{ +	struct LLSelectedTEGetDiffuseAlphaMode : public LLSelectedTEGetFunctor<U8> +	{ +		LLSelectedTEGetDiffuseAlphaMode() : _isAlpha(false) {} +		LLSelectedTEGetDiffuseAlphaMode(bool diffuse_texture_has_alpha) : _isAlpha(diffuse_texture_has_alpha) {} +		virtual ~LLSelectedTEGetDiffuseAlphaMode() {} + +		U8 get(LLViewerObject* object, S32 face) +		{ +			U8 diffuse_mode = _isAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + +			LLTextureEntry* tep = object->getTE(face); +			if (tep) +			{ +				LLMaterial* mat = tep->getMaterialParams().get(); +				if (mat) +				{ +					diffuse_mode = mat->getDiffuseAlphaMode(); +				} +			} +			 +			return diffuse_mode; +		} +		bool _isAlpha; // whether or not the diffuse texture selected contains alpha information +	} get_diff_mode(diffuse_texture_has_alpha); +	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode); +} + +void LLPanelFace::LLSelectedTE::getObjectScaleS(F32& scale_s, bool& identical) +{	 +	struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32> +	{ +		F32 get(LLViewerObject* object, S32 face) +		{ +			U32 s_axis = VX; +			U32 t_axis = VY; +			LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); +			return object->getScale().mV[s_axis]; +		} + +	} scale_s_func; +	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_s_func, scale_s ); +} + +void LLPanelFace::LLSelectedTE::getObjectScaleT(F32& scale_t, bool& identical) +{	 +	struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32> +	{ +		F32 get(LLViewerObject* object, S32 face) +		{ +			U32 s_axis = VX; +			U32 t_axis = VY; +			LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); +			return object->getScale().mV[t_axis]; +		} + +	} scale_t_func; +	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_t_func, scale_t ); +} + +void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identical) +{ +	struct LLSelectedTEGetMaxDiffuseRepeats : public LLSelectedTEGetFunctor<F32> +	{ +		F32 get(LLViewerObject* object, S32 face) +		{ +			U32 s_axis = VX; +			U32 t_axis = VY; +			LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); +			F32 repeats_s = object->getTE(face)->mScaleS / object->getScale().mV[s_axis]; +			F32 repeats_t = object->getTE(face)->mScaleT / object->getScale().mV[t_axis]; +			return llmax(repeats_s, repeats_t); +		} + +	} max_diff_repeats_func; +	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats ); +} diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 3b5a9b1398..42c1f6bd48 100755 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -29,6 +29,10 @@  #include "v4color.h"  #include "llpanel.h" +#include "llmaterial.h" +#include "llmaterialmgr.h" +#include "lltextureentry.h" +#include "llselectmgr.h"  class LLButton;  class LLCheckBoxCtrl; @@ -42,6 +46,48 @@ class LLTextureCtrl;  class LLUICtrl;  class LLViewerObject;  class LLFloater; +class LLMaterialID; + +// Represents an edit for use in replicating the op across one or more materials in the selection set. +// +// The apply function optionally performs the edit which it implements +// as a functor taking Data that calls member func MaterialFunc taking SetValueType +// on an instance of the LLMaterial class. +// +// boost who? +// +template< +	typename DataType, +	typename SetValueType, +	void (LLMaterial::*MaterialEditFunc)(SetValueType data) > +class LLMaterialEditFunctor +{ +public: +	LLMaterialEditFunctor(const DataType& data) : _data(data) {} +	virtual ~LLMaterialEditFunctor() {} +	virtual void apply(LLMaterialPtr& material) { (material->*(MaterialEditFunc))(_data); } +	DataType _data; +}; + +template< +	typename DataType, +	DataType (LLMaterial::*MaterialGetFunc)() > +class LLMaterialGetFunctor +{ +public: +	LLMaterialGetFunctor() {} +	virtual DataType get(LLMaterialPtr& material) { return (material->*(MaterialGetFunc)); } +}; + +template< +	typename DataType, +	DataType (LLTextureEntry::*TEGetFunc)() > +class LLTEGetFunctor +{ +public: +	LLTEGetFunctor() {} +	virtual DataType get(LLTextureEntry* entry) { return (entry*(TEGetFunc)); } +};  class LLPanelFace : public LLPanel  { @@ -61,11 +107,11 @@ protected:  	void			sendTextureInfo();		// applies and sends texture scale, offset, etc.  	void			sendColor();			// applies and sends color  	void			sendAlpha();			// applies and sends transparency -	void			sendBump();				// applies and sends bump map +	void			sendBump(U32 bumpiness);				// applies and sends bump map  	void			sendTexGen();				// applies and sends bump map -	void			sendShiny();			// applies and sends shininess +	void			sendShiny(U32 shininess);			// applies and sends shininess  	void			sendFullbright();		// applies and sends full bright -	void            sendGlow(); +	void        sendGlow();  	void			sendMedia();  	// this function is to return TRUE if the drag should succeed. @@ -74,25 +120,228 @@ protected:  	void 	onCommitTexture(const LLSD& data);  	void 	onCancelTexture(const LLSD& data);  	void 	onSelectTexture(const LLSD& data); +	void 	onCommitSpecularTexture(const LLSD& data); +	void 	onCancelSpecularTexture(const LLSD& data); +	void 	onSelectSpecularTexture(const LLSD& data); +	void 	onCommitNormalTexture(const LLSD& data); +	void 	onCancelNormalTexture(const LLSD& data); +	void 	onSelectNormalTexture(const LLSD& data);  	void 	onCommitColor(const LLSD& data); +	void 	onCommitShinyColor(const LLSD& data);  	void 	onCommitAlpha(const LLSD& data);  	void 	onCancelColor(const LLSD& data);  	void 	onSelectColor(const LLSD& data); -	 -	static 	void onCommitTextureInfo( 		LLUICtrl* ctrl, void* userdata); -	static void		onCommitBump(			LLUICtrl* ctrl, void* userdata); + +	void 	onCloseTexturePicker(const LLSD& data); + +	// Make UI reflect state of currently selected material (refresh) +	// and UI mode (e.g. editing normal map v diffuse map) +	// +	void updateUI(); + +	// Convenience func to determine if all faces in selection have +	// identical planar texgen settings during edits +	//  +	bool isIdenticalPlanarTexgen(); + +	// Callback funcs for individual controls +	// +	static void		onCommitTextureInfo( 	LLUICtrl* ctrl, void* userdata); + +	static void		onCommitMaterialBumpyScaleX(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialBumpyScaleY(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialBumpyRot(		LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialBumpyOffsetX(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialBumpyOffsetY(	LLUICtrl* ctrl, void* userdata); + +	static void		onCommitMaterialShinyScaleX(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialShinyScaleY(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialShinyRot(		LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialShinyOffsetX(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialShinyOffsetY(	LLUICtrl* ctrl, void* userdata); + +	static void		onCommitMaterialGloss(			LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialEnv(				LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialMaskCutoff(	LLUICtrl* ctrl, void* userdata); + +	static void		onCommitMaterialsMedia(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialType(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitBump(				LLUICtrl* ctrl, void* userdata);  	static void		onCommitTexGen(			LLUICtrl* ctrl, void* userdata); -	static void		onCommitShiny(			LLUICtrl* ctrl, void* userdata); +	static void		onCommitShiny(				LLUICtrl* ctrl, void* userdata); +	static void		onCommitAlphaMode(		LLUICtrl* ctrl, void* userdata);  	static void		onCommitFullbright(		LLUICtrl* ctrl, void* userdata); -	static void     onCommitGlow(           LLUICtrl* ctrl, void *userdata); -	static void		onCommitPlanarAlign(	LLUICtrl* ctrl, void* userdata); -	 -	static void		onClickApply(void*); +	static void    onCommitGlow(				LLUICtrl* ctrl, void *userdata); +	static void		onCommitPlanarAlign(		LLUICtrl* ctrl, void* userdata); +	static void		onCommitRepeatsPerMeter(	LLUICtrl* ctrl, void* userinfo);  	static void		onClickAutoFix(void*); -	static F32      valueGlow(LLViewerObject* object, S32 face); + +	static F32     valueGlow(LLViewerObject* object, S32 face);  private: +	bool		isAlpha() { return mIsAlpha; } + +	// Convenience funcs to keep the visual flack to a minimum +	// +	LLUUID	getCurrentNormalMap(); +	LLUUID	getCurrentSpecularMap(); +	U32		getCurrentShininess(); +	U32		getCurrentBumpiness(); +	U8			getCurrentDiffuseAlphaMode(); +	U8			getCurrentAlphaMaskCutoff(); +	U8			getCurrentEnvIntensity(); +	U8			getCurrentGlossiness(); +	F32		getCurrentBumpyRot(); +	F32		getCurrentBumpyScaleU(); +	F32		getCurrentBumpyScaleV(); +	F32		getCurrentBumpyOffsetU(); +	F32		getCurrentBumpyOffsetV(); +	F32		getCurrentShinyRot(); +	F32		getCurrentShinyScaleU(); +	F32		getCurrentShinyScaleV(); +	F32		getCurrentShinyOffsetU(); +	F32		getCurrentShinyOffsetV(); + +	// Update visibility of controls to match current UI mode +	// (e.g. materials vs media editing) +	// +	// Do NOT call updateUI from within this function. +	// +	void updateVisibility(); + +	// Make material(s) reflect current state of UI (apply edit) +	// +	void updateMaterial(); + +	// Hey look everyone, a type-safe alternative to copy and paste! :) +	// + +	// Update material parameters by applying 'edit_func' to selected TEs +	// +	template< +		typename DataType, +		typename SetValueType, +		void (LLMaterial::*MaterialEditFunc)(SetValueType data) > +	static void edit(LLPanelFace* p, DataType data) +	{ +		LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data); +		struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor +		{ +			LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp) : _panel(panel), _edit(editp) {} +			virtual ~LLSelectedTEEditMaterial() {}; +			virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) +			{ +				if (_edit) +				{ +					LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial()); +					llassert_always(new_material); + +					// Determine correct alpha mode for current diffuse texture +					// (i.e. does it have an alpha channel that makes alpha mode useful) +					// +					U8 default_alpha_mode = (_panel->isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE); + +					// Default to matching expected state of UI +					// +					new_material->setDiffuseAlphaMode(current_material.isNull() ? default_alpha_mode : current_material->getDiffuseAlphaMode()); + +					// Do "It"! +					// +					_edit->apply(new_material); + +					U32		new_alpha_mode			= new_material->getDiffuseAlphaMode(); +					LLUUID	new_normal_map_id		= new_material->getNormalID(); +					LLUUID	new_spec_map_id		= new_material->getSpecularID(); + +					bool is_default_blend_mode		= (new_alpha_mode == default_alpha_mode); +					bool is_need_material			= !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull(); + +					if (!is_need_material) +					{ +						LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; +						LLMaterialMgr::getInstance()->remove(object->getID(),face); +						new_material = NULL; +					} +					else +					{ +						LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << new_material->asLLSD() << LL_ENDL; +						LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material); +					} + +					object->setTEMaterialParams(face, new_material); +					return new_material; +				} +				return NULL; +			} +			LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >*	_edit; +			LLPanelFace*																			_panel; +		} editor(p, &edit); +		LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor); +	} + +	template< +		typename DataType, +		typename ReturnType, +		ReturnType (LLMaterial::* const MaterialGetFunc)() const  > +	static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value) +	{ +		DataType data_value; +		struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType> +		{ +			GetTEMaterialVal(DataType default_value) : _default(default_value) {} +			virtual ~GetTEMaterialVal() {} + +			DataType get(LLViewerObject* object, S32 face) +			{ +				DataType ret = _default; +				LLMaterialPtr material_ptr; +				LLTextureEntry* tep = object ? object->getTE(face) : NULL; +				if (tep) +				{ +					material_ptr = tep->getMaterialParams(); +					if (!material_ptr.isNull()) +					{ +						ret = (material_ptr->*(MaterialGetFunc))(); +					} +				} +				return ret; +			} +			DataType _default; +		} GetFunc(default_value); +		identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value); +		data_to_return = data_value; +	} + +	template< +		typename DataType, +		typename ReturnType, // some kids just have to different... +		ReturnType (LLTextureEntry::* const TEGetFunc)() const > +	static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value) +	{ +		DataType data_value; +		struct GetTEVal : public LLSelectedTEGetFunctor<DataType> +		{ +			GetTEVal(DataType default_value) : _default(default_value) {} +			virtual ~GetTEVal() {} + +			DataType get(LLViewerObject* object, S32 face) { +				LLTextureEntry* tep = object ? object->getTE(face) : NULL; +				return tep ? ((tep->*(TEGetFunc))()) : _default; +			} +			DataType _default; +		} GetTEValFunc(default_value); +		identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value ); +		data_to_return = data_value; +	} + +	// Update vis and enabling of specific subsets of controls based on material params +	// (e.g. hide the spec controls if no spec texture is applied) +	// +	void updateShinyControls(bool is_setting_texture = false, bool mess_with_combobox = false); +	void updateBumpyControls(bool is_setting_texture = false, bool mess_with_combobox = false); +	void updateAlphaControls(); +  	/*  	 * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object.  	 * If agent selects texture which is not allowed to be applied for the currently selected object, @@ -100,6 +349,126 @@ private:  	 */  	void onTextureSelectionChanged(LLInventoryItem* itemp); +	bool mIsAlpha; +	 +	/* These variables interlock processing of materials updates sent to +	 * the sim.  mUpdateInFlight is set to flag that an update has been +	 * sent to the sim and not acknowledged yet, and cleared when an +	 * update is received from the sim.  mUpdatePending is set when +	 * there's an update in flight and another UI change has been made +	 * that needs to be sent as a materials update, and cleared when the +	 * update is sent.  This prevents the sim from getting spammed with +	 * update messages when, for example, the user holds down the +	 * up-arrow on a spinner, and avoids running afoul of its throttle. +	 */ +	bool mUpdateInFlight; +	bool mUpdatePending; + +	#if defined(DEF_GET_MAT_STATE) +		#undef DEF_GET_MAT_STATE +	#endif + +	#if defined(DEF_GET_TE_STATE) +		#undef DEF_GET_TE_STATE +	#endif + +	#if defined(DEF_EDIT_MAT_STATE) +		DEF_EDIT_MAT_STATE +	#endif + +	// Accessors for selected TE material state +	// +	#define DEF_GET_MAT_STATE(DataType,ReturnType,MaterialMemberFunc,DefaultValue)												\ +		static void MaterialMemberFunc(DataType& data, bool& identical)																\ +		{																																					\ +			getTEMaterialValue< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(data, identical,DefaultValue);	\ +		} + +	// Mutators for selected TE material +	// +	#define DEF_EDIT_MAT_STATE(DataType,ReturnType,MaterialMemberFunc)																\ +		static void MaterialMemberFunc(LLPanelFace* p,DataType data)																	\ +		{																																					\ +			edit< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(p,data);													\ +		} + +	// Accessors for selected TE state proper (legacy settings etc) +	// +	#define DEF_GET_TE_STATE(DataType,ReturnType,TexEntryMemberFunc,DefaultValue)													\ +		static void TexEntryMemberFunc(DataType& data, bool& identical)																\ +		{																																					\ +			getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical,DefaultValue);		\ +		} + +	class LLSelectedTEMaterial +	{ +	public: +		static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material); +		static void getMaxSpecularRepeats(F32& repeats, bool& identical); +		static void getMaxNormalRepeats(F32& repeats, bool& identical); +		static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha); + +		DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null) +		DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null) +		DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f) +		DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f) +		DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f) +		DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f) +		DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f) + +		DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f) +		DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f) +		DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f) +		DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f) +		DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f) + +		DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode); +		DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff); + +		DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetX); +		DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetY); +		DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatX); +		DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatY); +		DEF_EDIT_MAT_STATE(F32,F32,setNormalRotation); + +		DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetX); +		DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetY); +		DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatX); +		DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatY); +		DEF_EDIT_MAT_STATE(F32,F32,setSpecularRotation); + +		DEF_EDIT_MAT_STATE(U8,U8,setEnvironmentIntensity); +		DEF_EDIT_MAT_STATE(U8,U8,setSpecularLightExponent); + +		DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID); +		DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID); +		DEF_EDIT_MAT_STATE(LLColor4U,	const LLColor4U&,setSpecularLightColor); +	}; + +	class LLSelectedTE +	{ +	public: + +		static void getFace(LLFace*& face_to_return, bool& identical_face); +		static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face); +		static void getTexId(LLUUID& id, bool& identical); +		static void getObjectScaleS(F32& scale_s, bool& identical); +		static void getObjectScaleT(F32& scale_t, bool& identical); +		static void getMaxDiffuseRepeats(F32& repeats, bool& identical); + +		DEF_GET_TE_STATE(U8,U8,getBumpmap,0) +		DEF_GET_TE_STATE(U8,U8,getShiny,0) +		DEF_GET_TE_STATE(U8,U8,getFullbright,0) +		DEF_GET_TE_STATE(F32,F32,getRotation,0.0f) +		DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f) +		DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f) +		DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f) +		DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f) +		DEF_GET_TE_STATE(F32,F32,getGlow,0.0f) +		DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT) +		DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white)		 +	};  };  #endif + diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 3ee0746412..18b85cc9c3 100755 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -428,13 +428,13 @@ F32 LLPhysicsMotion::toLocal(const LLVector3 &world)  F32 LLPhysicsMotion::calculateVelocity_local()  {  	const F32 world_to_model_scale = 100.0f; -	LLJoint *joint = mJointState->getJoint(); -	const LLVector3 position_world = joint->getWorldPosition(); -	const LLVector3 last_position_world = mPosition_world; +        LLJoint *joint = mJointState->getJoint(); +        const LLVector3 position_world = joint->getWorldPosition(); +        const LLVector3 last_position_world = mPosition_world;  	const LLVector3 positionchange_world = (position_world-last_position_world) * world_to_model_scale; -	const LLVector3 velocity_world = positionchange_world; -	const F32 velocity_local = toLocal(velocity_world); -	return velocity_local; +        const LLVector3 velocity_world = positionchange_world; +        const F32 velocity_local = toLocal(velocity_world); +        return velocity_local;  }  F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local) diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 4681efd3e5..0cbdbe16a3 100755 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -29,6 +29,7 @@  // file include  #define LLSELECTMGR_CPP  #include "llselectmgr.h" +#include "llmaterialmgr.h"  // library includes  #include "llcachename.h" @@ -103,7 +104,6 @@ const F32 SILHOUETTE_UPDATE_THRESHOLD_SQUARED = 0.02f;  const S32 MAX_ACTION_QUEUE_SIZE = 20;  const S32 MAX_SILS_PER_FRAME = 50;  const S32 MAX_OBJECTS_PER_PACKET = 254; -const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF;  //  // Globals @@ -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() @@ -815,6 +818,7 @@ void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to  			if (objectp->getNumTEs() > 0)  			{  				nodep->selectAllTEs(TRUE); +				objectp->setAllTESelected(true);  			}  			else  			{ @@ -843,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)  	{ @@ -872,10 +880,12 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab  	else if (face == SELECT_ALL_TES)  	{  		nodep->selectAllTEs(TRUE); +		objectp->setAllTESelected(true);  	}  	else if (0 <= face && face < SELECT_MAX_TES)  	{  		nodep->selectTE(face, TRUE); +		objectp->setTESelected(face, true);  	}  	else  	{ @@ -1095,6 +1105,7 @@ LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects()  		// flag this object as selected  		objectp->setSelected(TRUE); +		objectp->setAllTESelected(true);  		mSelectedObjects->mSelectType = getSelectTypeForObject(objectp); @@ -1318,6 +1329,7 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable)  		if (nodep->isTESelected(te))  		{  			nodep->selectTE(te, FALSE); +			objectp->setTESelected(te, false);  		}  		else  		{ @@ -2004,6 +2016,76 @@ void LLSelectMgr::selectionSetGlow(F32 glow)  	mSelectedObjects->applyToObjects( &func2 );  } +void LLSelectMgr::selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func) +{ +	struct f1 : public LLSelectedTEFunctor +	{ +		LLMaterialPtr mMaterial; +		f1(LLSelectedTEMaterialFunctor* material_func) : _material_func(material_func) {} + +		bool apply(LLViewerObject* object, S32 face) +		{ +			if (object && object->permModify() && _material_func) +			{ +				LLTextureEntry* tep = object->getTE(face); +				if (tep) +				{ +					LLMaterialPtr current_material = tep->getMaterialParams(); +					_material_func->apply(object, face, tep, current_material); +				} +			} +			return true; +		} + +		LLSelectedTEMaterialFunctor* _material_func; +	} func1(material_func); +	mSelectedObjects->applyToTEs( &func1 ); + +	struct f2 : public LLSelectedObjectFunctor +	{ +		virtual bool apply(LLViewerObject* object) +		{ +			if (object->permModify()) +			{ +				object->sendTEUpdate(); +			} +			return true; +		} +	} func2; +	mSelectedObjects->applyToObjects( &func2 ); +} + +void LLSelectMgr::selectionRemoveMaterial() +{ +	struct f1 : public LLSelectedTEFunctor +	{ +		bool apply(LLViewerObject* object, S32 face) +		{ +			if (object->permModify()) +			{ +			        LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; +				LLMaterialMgr::getInstance()->remove(object->getID(),face); +				object->setTEMaterialParams(face, NULL); +			} +			return true; +		} +	} func1; +	mSelectedObjects->applyToTEs( &func1 ); + +	struct f2 : public LLSelectedObjectFunctor +	{ +		virtual bool apply(LLViewerObject* object) +		{ +			if (object->permModify()) +			{ +				object->sendTEUpdate(); +			} +			return true; +		} +	} func2; +	mSelectedObjects->applyToObjects( &func2 ); +} +  //-----------------------------------------------------------------------------  // findObjectPermissions() @@ -2425,19 +2507,66 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)  					continue;  				} -				LLVector3 scale_ratio = selectNode->mTextureScaleRatios[te_num];   				LLVector3 object_scale = object->getScale(); +				LLVector3 diffuse_scale_ratio  = selectNode->mTextureScaleRatios[te_num];  + +				// We like these to track together. NORSPEC-96 +				// +				LLVector3 normal_scale_ratio   = diffuse_scale_ratio;  +				LLVector3 specular_scale_ratio = diffuse_scale_ratio;   				// Apply new scale to face  				if (planar)  				{ -					object->setTEScale(te_num, 1.f/object_scale.mV[s_axis]*scale_ratio.mV[s_axis], -										1.f/object_scale.mV[t_axis]*scale_ratio.mV[t_axis]); +					F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; +					F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; + +					F32 normal_scale_s = normal_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; +					F32 normal_scale_t = normal_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; + +					F32 specular_scale_s = specular_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; +					F32 specular_scale_t = specular_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; + +					object->setTEScale(te_num, diffuse_scale_s, diffuse_scale_t); + +					LLTextureEntry* tep = object->getTE(te_num); + +					if (tep && !tep->getMaterialParams().isNull()) +					{ +						LLMaterialPtr orig = tep->getMaterialParams(); +						LLMaterialPtr p = new LLMaterial(orig->asLLSD()); +						p->setNormalRepeat(normal_scale_s, normal_scale_t); +						p->setSpecularRepeat(specular_scale_s, specular_scale_t); + +						LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p); +					}  				}  				else  				{ -					object->setTEScale(te_num, scale_ratio.mV[s_axis]*object_scale.mV[s_axis], -											scale_ratio.mV[t_axis]*object_scale.mV[t_axis]); + +					F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; +					F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; + +					F32 normal_scale_s = normal_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; +					F32 normal_scale_t = normal_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; + +					F32 specular_scale_s = specular_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; +					F32 specular_scale_t = specular_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; + +					object->setTEScale(te_num, diffuse_scale_s,diffuse_scale_t); + +					LLTextureEntry* tep = object->getTE(te_num); + +					if (tep && !tep->getMaterialParams().isNull()) +					{ +						LLMaterialPtr orig = tep->getMaterialParams(); + +						LLMaterialPtr p = new LLMaterial(orig->asLLSD()); +						p->setNormalRepeat(normal_scale_s, normal_scale_t); +						p->setSpecularRepeat(specular_scale_s, specular_scale_t); + +						LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p); +					}  				}  				send = send_to_sim;  			} @@ -4398,7 +4527,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(); @@ -4445,10 +4575,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(); @@ -5759,36 +5889,43 @@ 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 diffuse_s = 1.0f; +			F32 diffuse_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; +			U32 s_axis = VX; +			U32 t_axis = VY;  			LLPrimitive::getTESTAxes(i, &s_axis, &t_axis); -			LLVector3 v; -			LLVector3 scale = mObject->getScale(); - +			tep->getScale(&diffuse_s,&diffuse_t); +			  			if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR)  			{ -				v.mV[s_axis] = s*scale.mV[s_axis]; -				v.mV[t_axis] = t*scale.mV[t_axis]; +				v.mV[s_axis] = diffuse_s*scale.mV[s_axis]; +				v.mV[t_axis] = diffuse_t*scale.mV[t_axis]; +				mTextureScaleRatios.push_back(v);  			}  			else  			{ -				v.mV[s_axis] = s/scale.mV[s_axis]; -				v.mV[t_axis] = t/scale.mV[t_axis]; -			} - -			mTextureScaleRatios.push_back(v); +				v.mV[s_axis] = diffuse_s/scale.mV[s_axis]; +				v.mV[t_axis] = diffuse_t/scale.mV[t_axis]; +				mTextureScaleRatios.push_back(v); +			}			  		}  	}  } diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index cc78e35869..d4b736640c 100755 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -43,10 +43,12 @@  #include "llpermissions.h"  #include "llcontrol.h"  #include "llviewerobject.h"	// LLObjectSelection::getSelectedTEValue template +#include "llmaterial.h"  #include <deque>  #include <boost/iterator/filter_iterator.hpp>  #include <boost/signals2.hpp> +#include <boost/make_shared.hpp>	// boost::make_shared  class LLMessageSystem;  class LLViewerTexture; @@ -83,6 +85,12 @@ struct LLSelectedTEFunctor  	virtual bool apply(LLViewerObject* object, S32 face) = 0;  }; +struct LLSelectedTEMaterialFunctor +{ +	virtual ~LLSelectedTEMaterialFunctor() {}; +	virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) = 0; +}; +  template <typename T> struct LLSelectedTEGetFunctor  {  	virtual ~LLSelectedTEGetFunctor() {}; @@ -121,6 +129,8 @@ typedef enum e_selection_type  	SELECT_TYPE_HUD  }ESelectType; +const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF; +  // Contains information about a selected object, particularly which TEs are selected.  class LLSelectNode  { @@ -143,7 +153,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; @@ -510,6 +520,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); @@ -540,6 +555,8 @@ public:  	void selectionSetClickAction(U8 action);  	void selectionSetIncludeInSearch(bool include_in_search);  	void selectionSetGlow(const F32 glow); +	void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func); +	void selectionRemoveMaterial();  	void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE);  	void selectionSetObjectName(const std::string& name); @@ -771,6 +788,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/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 74fa5a87bb..df413ab849 100755 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -231,7 +231,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)  		{  			gAgentCamera.changeCameraToDefault();  			gAgentCamera.resetView(); -		}	 +		}  	}  } diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h index 762f557a80..b0a6b9cf91 100755 --- a/indra/newview/llsidepanelappearance.h +++ b/indra/newview/llsidepanelappearance.h @@ -47,7 +47,7 @@ public:  	virtual ~LLSidepanelAppearance();  	/*virtual*/ BOOL postBuild(); -	/*virtual*/ void onOpen(const LLSD& key);	 +	/*virtual*/ void onOpen(const LLSD& key);  	void refreshCurrentOutfitName(const std::string& name = ""); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index f85e855fd3..78401020a6 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3039,9 +3039,9 @@ void renderNormals(LLDrawable* drawablep)  				gGL.vertex3fv(face.mPositions[j].getF32ptr());  				gGL.vertex3fv(p.getF32ptr()); -				if (face.mBinormals) +				if (face.mTangents)  				{ -					n.setMul(face.mBinormals[j], scale); +					n.setMul(face.mTangents[j], scale);  					p.setAdd(face.mPositions[j], n);  					gGL.diffuseColor4f(0,1,1,1); @@ -3888,11 +3888,17 @@ void renderRaycast(LLDrawable* drawablep)  					gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);					  					gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix); -					LLVector3 start, end; +					LLVector4a start, end;  					if (transform)  					{ -						start = vobj->agentPositionToVolume(gDebugRaycastStart); -						end = vobj->agentPositionToVolume(gDebugRaycastEnd); +						LLVector3 v_start(gDebugRaycastStart.getF32ptr()); +						LLVector3 v_end(gDebugRaycastEnd.getF32ptr()); + +						v_start = vobj->agentPositionToVolume(v_start); +						v_end = vobj->agentPositionToVolume(v_end); + +						start.load3(v_start.mV); +						end.load3(v_end.mV);  					}  					else  					{ @@ -3900,11 +3906,8 @@ void renderRaycast(LLDrawable* drawablep)  						end = gDebugRaycastEnd;  					} -					LLVector4a starta, enda; -					starta.load3(start.mV); -					enda.load3(end.mV);  					LLVector4a dir; -					dir.setSub(enda, starta); +					dir.setSub(end, start);  					gGL.flush();  					glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);				 @@ -3927,7 +3930,7 @@ void renderRaycast(LLDrawable* drawablep)  							((LLVolumeFace*) &face)->createOctree();   						} -						LLRenderOctreeRaycast render(starta, dir, &t); +						LLRenderOctreeRaycast render(start, dir, &t);  						render.traverse(face.mOctree);  					} @@ -3952,10 +3955,18 @@ void renderRaycast(LLDrawable* drawablep)  			// draw intersection point  			gGL.pushMatrix();  			gGL.loadMatrix(gGLModelView); -			LLVector3 translate = gDebugRaycastIntersection; +			LLVector3 translate(gDebugRaycastIntersection.getF32ptr());  			gGL.translatef(translate.mV[0], translate.mV[1], translate.mV[2]);  			LLCoordFrame orient; -			orient.lookDir(gDebugRaycastNormal, gDebugRaycastBinormal); +			LLVector4a debug_binormal; +			 +			debug_binormal.setCross3(gDebugRaycastNormal, gDebugRaycastTangent); +			debug_binormal.mul(gDebugRaycastTangent.getF32ptr()[3]); + +			LLVector3 normal(gDebugRaycastNormal.getF32ptr()); +			LLVector3 binormal(debug_binormal.getF32ptr()); +						 +			orient.lookDir(normal, binormal);  			LLMatrix4 rotation;  			orient.getRotMatrixToParent(rotation);  			gGL.multMatrix((float*)rotation.mMatrix); @@ -4457,28 +4468,30 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v)  	return TRUE;  } +LL_ALIGN_PREFIX(16)  class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler  {  public: -	LLVector3 mStart; -	LLVector3 mEnd; +	LL_ALIGN_16(LLVector4a mStart); +	LL_ALIGN_16(LLVector4a mEnd); +  	S32       *mFaceHit; -	LLVector3 *mIntersection; +	LLVector4a *mIntersection;  	LLVector2 *mTexCoord; -	LLVector3 *mNormal; -	LLVector3 *mBinormal; +	LLVector4a *mNormal; +	LLVector4a *mTangent;  	LLDrawable* mHit;  	BOOL mPickTransparent; -	LLOctreeIntersect(LLVector3 start, LLVector3 end, BOOL pick_transparent, -					  S32* face_hit, LLVector3* intersection, LLVector2* tex_coord, LLVector3* normal, LLVector3* binormal) +	LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, +					  S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  		: mStart(start),  		  mEnd(end),  		  mFaceHit(face_hit),  		  mIntersection(intersection),  		  mTexCoord(tex_coord),  		  mNormal(normal), -		  mBinormal(binormal), +		  mTangent(tangent),  		  mHit(NULL),  		  mPickTransparent(pick_transparent)  	{ @@ -4509,23 +4522,22 @@ public:  			size = group->mBounds[1];  			center = group->mBounds[0]; -			LLVector3 local_start = mStart; -			LLVector3 local_end   = mEnd; +			LLVector4a local_start = mStart; +			LLVector4a local_end   = mEnd;  			if (group->mSpatialPartition->isBridge())  			{  				LLMatrix4 local_matrix = group->mSpatialPartition->asBridge()->mDrawable->getRenderMatrix();  				local_matrix.invert(); -				 -				local_start = mStart * local_matrix; -				local_end   = mEnd   * local_matrix; -			} -			LLVector4a start, end; -			start.load3(local_start.mV); -			end.load3(local_end.mV); +				LLMatrix4a local_matrix4a; +				local_matrix4a.loadu(local_matrix); -			if (LLLineSegmentBoxIntersect(start, end, center, size)) +				local_matrix4a.affineTransform(mStart, local_start); +				local_matrix4a.affineTransform(mEnd, local_end); +			} + +			if (LLLineSegmentBoxIntersect(local_start, local_end, center, size))  			{  				check(child);  			} @@ -4556,14 +4568,14 @@ public:  			if (vobj)  			{ -				LLVector3 intersection; +				LLVector4a intersection;  				bool skip_check = false;  				if (vobj->isAvatar())  				{  					LLVOAvatar* avatar = (LLVOAvatar*) vobj;  					if (avatar->isSelf() && LLFloater::isVisible(gFloaterTools))  					{ -						LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal); +						LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);  						if (hit)  						{  							mEnd = intersection; @@ -4579,7 +4591,7 @@ public:  					}  				} -				if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal)) +				if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))  				{  					mEnd = intersection;  // shorten ray so we only find CLOSER hits  					if (mIntersection) @@ -4594,19 +4606,19 @@ public:  		return false;  	} -}; +} LL_ALIGN_POSTFIX(16); -LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  													 BOOL pick_transparent,													  													 S32* face_hit,                   // return the face hit -													 LLVector3* intersection,         // return the intersection point +													 LLVector4a* intersection,         // return the intersection point  													 LLVector2* tex_coord,            // return the texture coordinates of the intersection point -													 LLVector3* normal,               // return the surface normal at the intersection point -													 LLVector3* bi_normal             // return the surface bi-normal at the intersection point +													 LLVector4a* normal,               // return the surface normal at the intersection point +													 LLVector4a* tangent			// return the surface tangent at the intersection point  	)  { -	LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal); +	LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);  	LLDrawable* drawable = intersect.check(mOctree);  	return drawable; @@ -4632,7 +4644,13 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,  	mGroup(NULL),  	mFace(NULL),  	mDistance(0.f), -	mDrawMode(LLRender::TRIANGLES) +	mDrawMode(LLRender::TRIANGLES), +	mMaterial(NULL), +	mShaderMask(0), +	mSpecColor(1.0f, 1.0f, 1.0f, 0.5f), +	mEnvIntensity(0.0f), +	mAlphaMaskCutoff(0.5f), +	mDiffuseAlphaMode(0)  {  	mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index b1706d9d35..9732be90af 100755 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -112,6 +112,7 @@ public:  	U32 mOffset;  	BOOL mFullbright;  	U8 mBump; +	U8 mShiny;  	BOOL mParticle;  	F32 mPartSize;  	F32 mVSize; @@ -119,6 +120,18 @@ public:  	LL_ALIGN_16(LLFace* mFace); //associated face  	F32 mDistance;  	U32 mDrawMode; +	LLMaterialPtr mMaterial; // If this is null, the following parameters are unused. +	LLMaterialID mMaterialID; +	U32 mShaderMask; +	LLPointer<LLViewerTexture> mSpecularMap; +	const LLMatrix4* mSpecularMapMatrix; +	LLPointer<LLViewerTexture> mNormalMap; +	const LLMatrix4* mNormalMapMatrix; +	LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent +	F32  mEnvIntensity; +	F32  mAlphaMaskCutoff; +	U8   mDiffuseAlphaMode; +  	struct CompareTexture  	{ @@ -169,7 +182,7 @@ public:  		}  	}; - +	  	struct CompareBump  	{  		bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)  @@ -191,7 +204,7 @@ public:  	};  }; -LL_ALIGN_PREFIX(16) +LL_ALIGN_PREFIX(64)  class LLSpatialGroup : public LLOctreeListener<LLDrawable>  {  	friend class LLSpatialPartition; @@ -477,13 +490,13 @@ public:  	LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE);  	BOOL remove(LLDrawable *drawablep, LLSpatialGroup *curp); -	LLDrawable* lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +	LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  									 BOOL pick_transparent,   									 S32* face_hit,                          // return the face hit -									 LLVector3* intersection = NULL,         // return the intersection point +									 LLVector4a* intersection = NULL,         // return the intersection point  									 LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -									 LLVector3* normal = NULL,               // return the surface normal at the intersection point -									 LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point +									 LLVector4a* normal = NULL,               // return the surface normal at the intersection point +									 LLVector4a* tangent = NULL             // return the surface tangent at the intersection point  		); @@ -739,7 +752,7 @@ class LLVolumeGeometryManager: public LLGeometryManager  	virtual void rebuildGeom(LLSpatialGroup* group);  	virtual void rebuildMesh(LLSpatialGroup* group);  	virtual void getGeometry(LLSpatialGroup* group); -	void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE); +	void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE);  	void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);  }; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 90111f9a98..3f8f5e282a 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -646,7 +646,7 @@ bool idle_startup()  				gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();  			}  #endif -             +  			if (gAudiop)  			{  #if LL_WINDOWS diff --git a/indra/newview/lltextureatlas.cpp b/indra/newview/lltextureatlas.cpp index f8c1bca8ae..dbbe331954 100755 --- a/indra/newview/lltextureatlas.cpp +++ b/indra/newview/lltextureatlas.cpp @@ -71,7 +71,7 @@ LLTextureAtlas::~LLTextureAtlas()  //virtual   S8 LLTextureAtlas::getType() const  { -	return LLViewerTexture::ATLAS_TEXTURE ; +	return 0; //LLViewerTexture::ATLAS_TEXTURE ;  }  void LLTextureAtlas::getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yoffset) diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 305f6fca0f..36a7aeb590 100755 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -568,8 +568,11 @@ bool LLTextureCacheRemoteWorker::doWrite()  			idx = mCache->setHeaderCacheEntry(mID, entry, mImageSize, mDataSize); // create the new entry.  			if(idx >= 0)  			{ -				//write to the fast cache. -				llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel)); +				// (almost always) write to the fast cache. +				if (mRawImage->getDataSize()) +				{ +					llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel)); +				}  			}  		}  		else @@ -1895,10 +1898,17 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d  bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)  {  	//rescale image if needed +	if (raw.isNull() || !raw->getData()) +	{ +		llerrs << "Attempted to write NULL raw image to fastcache" << llendl; +		return false; +	} +  	S32 w, h, c;  	w = raw->getWidth();  	h = raw->getHeight();  	c = raw->getComponents(); +  	S32 i = 0 ;  	while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index e3fc957fd2..deaacc4975 100755 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -24,7 +24,7 @@   * $/LicenseInfo$   */ -#ifndef LL_LLTEXTURECACHE_ +#ifndef LL_LLTEXTURECACHE_H  #define LL_LLTEXTURECACHE_H  #include "lldir.h" diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index e2d0fdf357..4676f7b251 100755 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -144,7 +144,7 @@ public:  	static void		onBtnCancel( void* userdata );  		   void		onBtnPipette( );  	//static void		onBtnRevert( void* userdata ); -	static void		onBtnWhite( void* userdata ); +	static void		onBtnBlank( void* userdata );  	static void		onBtnNone( void* userdata );  	static void		onBtnClear( void* userdata );  		   void		onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action); @@ -165,7 +165,6 @@ protected:  	LLUUID				mImageAssetID; // Currently selected texture  	LLUIImagePtr		mFallbackImage; // What to show if currently selected texture is null. -	LLUUID				mWhiteImageAssetID;  	LLUUID				mSpecialCurrentImageAssetID;  // Used when the asset id has no corresponding texture in the user's inventory.  	LLUUID				mOriginalImageAssetID; @@ -208,8 +207,7 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(  :	LLFloater(LLSD()),  	mOwner( owner ),  	mImageAssetID( owner->getImageAssetID() ), -	mFallbackImage( fallback_image ), -	mWhiteImageAssetID( gSavedSettings.getString( "UIImgWhiteUUID" ) ), +	mFallbackImage( fallback_image ),	  	mOriginalImageAssetID(owner->getImageAssetID()),  	mLabel(label),  	mTentativeLabel(NULL), @@ -426,7 +424,7 @@ BOOL LLFloaterTexturePicker::postBuild()  	childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this);  	childSetAction("None", LLFloaterTexturePicker::onBtnNone,this); -	childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this); +	childSetAction("Blank", LLFloaterTexturePicker::onBtnBlank,this);  	childSetCommitCallback("show_folders_check", onShowFolders, this); @@ -581,7 +579,7 @@ void LLFloaterTexturePicker::draw()  		}  		getChildView("Default")->setEnabled(mImageAssetID != mOwner->getDefaultImageAssetID()); -		getChildView("Blank")->setEnabled(mImageAssetID != mWhiteImageAssetID ); +		getChildView("Blank")->setEnabled(mImageAssetID != mOwner->getBlankImageAssetID());  		getChildView("None")->setEnabled(mOwner->getAllowNoTexture() && !mImageAssetID.isNull() );  		LLFloater::draw(); @@ -721,11 +719,11 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)  }  // static -void LLFloaterTexturePicker::onBtnWhite(void* userdata) +void LLFloaterTexturePicker::onBtnBlank(void* userdata)  {  	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;  	self->setCanApply(true, true); -	self->setImageID( self->mWhiteImageAssetID ); +	self->setImageID( self->mOwner->getBlankImageAssetID() );  	self->commitIfImmediateSet();  } @@ -1042,6 +1040,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)  	mDragCallback(NULL),  	mDropCallback(NULL),  	mOnCancelCallback(NULL), +	mOnCloseCallback(NULL),  	mOnSelectCallback(NULL),  	mBorderColor( p.border_color() ),  	mAllowNoTexture( FALSE ), @@ -1056,6 +1055,12 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)  	mDefaultImageName(p.default_image_name),  	mFallbackImage(p.fallback_image)  { + +	// Default of defaults is white image for diff tex +	// +	LLUUID whiteImage( gSavedSettings.getString( "UIImgWhiteUUID" ) ); +	setBlankImageAssetID( whiteImage ); +  	setAllowNoTexture(p.allow_no_texture);  	setCanApplyImmediately(p.can_apply_immediately);  	mCommitOnSelection = !p.no_commit_on_selection; @@ -1292,6 +1297,10 @@ void LLTextureCtrl::onFloaterClose()  	if (floaterp)  	{ +		if (mOnCloseCallback) +		{ +			mOnCloseCallback(this,LLSD()); +		}  		floaterp->setOwner(NULL);  	} diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 599d9c70c5..ad79042ef1 100755 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -126,6 +126,7 @@ public:  	// LLTextureCtrl interface  	void			showPicker(BOOL take_focus); +	bool			isPickerShown() { return !mFloaterHandle.isDead(); }  	void			setLabel(const std::string& label);  	void			setLabelWidth(S32 label_width) {mLabelWidth =label_width;}	  	const std::string&	getLabel() const							{ return mLabel; } @@ -145,6 +146,9 @@ public:  	const std::string&	getDefaultImageName() const					{ return mDefaultImageName; } +	void			setBlankImageAssetID( const LLUUID& id )	{ mBlankImageAssetID = id; } +	const LLUUID&	getBlankImageAssetID() const { return mBlankImageAssetID; } +  	void			setCaption(const std::string& caption);  	void			setCanApplyImmediately(BOOL b); @@ -174,7 +178,7 @@ public:  	void setDropCallback(drag_n_drop_callback cb)	{ mDropCallback = cb; }  	void setOnCancelCallback(commit_callback_t cb)	{ mOnCancelCallback = cb; } -	 +	void setOnCloseCallback(commit_callback_t cb)	{ mOnCloseCallback = cb; }  	void setOnSelectCallback(commit_callback_t cb)	{ mOnSelectCallback = cb; }  	/* @@ -195,12 +199,14 @@ private:  	drag_n_drop_callback	 	mDropCallback;  	commit_callback_t		 	mOnCancelCallback;  	commit_callback_t		 	mOnSelectCallback; +	commit_callback_t		 	mOnCloseCallback;  	texture_selected_callback	mOnTextureSelectedCallback;  	LLPointer<LLViewerFetchedTexture> mTexturep;  	LLUIColor				 	mBorderColor;  	LLUUID					 	mImageItemID;  	LLUUID					 	mImageAssetID;  	LLUUID					 	mDefaultImageAssetID; +	LLUUID					 	mBlankImageAssetID;  	LLUIImagePtr				mFallbackImage;  	std::string					mDefaultImageName;  	LLHandle<LLFloater>			mFloaterHandle; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index be5fde9e2b..6173e76a35 100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1896,9 +1896,9 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe  	LLCore::HttpStatus status(response->getStatus());  	LL_DEBUGS("Texture") << "HTTP COMPLETE: " << mID -						 << " status: " << status.toHex() -						 << " '" << status.toString() << "'" -						 << llendl; +			 << " status: " << status.toHex() +			 << " '" << status.toString() << "'" +			 << llendl;  //	unsigned int offset(0), length(0), full_length(0);  //	response->getRange(&offset, &length, &full_length);  // 	llwarns << "HTTP COMPLETE: " << mID << " handle: " << handle diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index 094694dc06..3da934b148 100755 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -400,7 +400,7 @@ void audio_update_volume(bool force_update)  		gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler"));  		if(!LLViewerCamera::getInstance()->cameraUnderWater()) -			gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff")); +		gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));  		else  			gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelUnderwaterRolloff")); @@ -494,18 +494,18 @@ void audio_update_wind(bool force_update)  	LLViewerRegion* region = gAgent.getRegion();  	if (region)  	{ -		// Scale down the contribution of weather-simulation wind to the -		// ambient wind noise.  Wind velocity averages 3.5 m/s, with gusts to 7 m/s -		// whereas steady-state avatar walk velocity is only 3.2 m/s. -		// Without this the world feels desolate on first login when you are -		// standing still. -		static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f); -		LLVector3 scaled_wind_vec = gWindVec * wind_level; - -		// Mix in the avatar's motion, subtract because when you walk north, -		// the apparent wind moves south. -		LLVector3 final_wind_vec = scaled_wind_vec - gAgent.getVelocity(); - +        // Scale down the contribution of weather-simulation wind to the +        // ambient wind noise.  Wind velocity averages 3.5 m/s, with gusts to 7 m/s +        // whereas steady-state avatar walk velocity is only 3.2 m/s. +        // Without this the world feels desolate on first login when you are +        // standing still. +        static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f); +        LLVector3 scaled_wind_vec = gWindVec * wind_level; +         +        // Mix in the avatar's motion, subtract because when you walk north, +        // the apparent wind moves south. +        LLVector3 final_wind_vec = scaled_wind_vec - gAgent.getVelocity(); +          		// rotate the wind vector to be listener (agent) relative  		gRelativeWindVec = gAgent.getFrameAgent().rotateToLocal( final_wind_vec ); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index a62f73deef..afbb59e723 100755 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -401,6 +401,25 @@ static bool handleRenderDeferredChanged(const LLSD& newvalue)  	return true;  } +// This looks a great deal like handleRenderDeferredChanged because +// Advanced Lighting (Materials) implies bumps and shiny so disabling +// bumps should further disable that feature. +// +static bool handleRenderBumpChanged(const LLSD& newval) +{ +	LLRenderTarget::sUseFBO = newval.asBoolean(); +	if (gPipeline.isInit()) +	{ +		gPipeline.updateRenderBump(); +		gPipeline.updateRenderDeferred(); +		gPipeline.releaseGLBuffers(); +		gPipeline.createGLBuffers(); +		gPipeline.resetVertexBuffers(); +		LLViewerShaderMgr::instance()->setShaders(); +	} +	return true; +} +  static bool handleRenderUseImpostorsChanged(const LLSD& newvalue)  {  	LLVOAvatar::sUseImpostors = newvalue.asBoolean(); @@ -629,7 +648,7 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));  	gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));  	gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); -	gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); +	gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleRenderBumpChanged, _2));  	gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));  	gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	gSavedSettings.getControl("RenderUseImpostors")->getSignal()->connect(boost::bind(&handleRenderUseImpostorsChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index cf59e67955..b07fe39e37 100755 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -98,6 +98,7 @@ BOOL gDepthDirty = FALSE;  BOOL gResizeScreenTexture = FALSE;  BOOL gWindowResized = FALSE;  BOOL gSnapshot = FALSE; +BOOL gShaderProfileFrame = FALSE;  U32 gRecentFrameCount = 0; // number of 'recent' frames  LLFrameTimer gRecentFPSTime; @@ -114,7 +115,8 @@ void render_disconnected_background();  void display_startup()  { -	if (   !gViewerWindow->getActive() +	if (   !gViewerWindow +		|| !gViewerWindow->getActive()  		|| !gViewerWindow->getWindow()->getVisible()   		|| gViewerWindow->getWindow()->getMinimized() )  	{ @@ -125,7 +127,14 @@ void display_startup()  	// Update images?  	//gImageList.updateImages(0.01f); -	LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName(); +	 +	// Written as branch to appease GCC which doesn't like different +	// pointer types across ternary ops +	// +	if (!LLViewerFetchedTexture::sWhiteImagep.isNull()) +	{ +		LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName(); +	}  	LLGLSDefault gls_default; @@ -147,10 +156,12 @@ void display_startup()  	LLGLSUIDefault gls_ui;  	gPipeline.disableLights(); +	if (gViewerWindow)  	gViewerWindow->setup2DRender();  	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);  	gGL.color4f(1,1,1,1); +	if (gViewerWindow)  	gViewerWindow->draw();  	gGL.flush(); @@ -159,7 +170,9 @@ void display_startup()  	LLGLState::checkStates();  	LLGLState::checkTextureChannels(); +	if (gViewerWindow && gViewerWindow->getWindow())  	gViewerWindow->getWindow()->swapBuffers(); +  	glClear(GL_DEPTH_BUFFER_BIT);  } @@ -340,6 +353,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		return;  	} + +	if (gShaderProfileFrame) +	{ +		LLGLSLShader::initProfile(); +	} +  	//LLGLState::verify(FALSE);  	///////////////////////////////////////////////// @@ -1018,6 +1037,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  	LLAppViewer::instance()->pingMainloopTimeout("Display:Done");  	gShiftFrame = false; + +	if (gShaderProfileFrame) +	{ +		gShaderProfileFrame = FALSE; +		LLGLSLShader::finishProfile(); +	}  }  void render_hud_attachments() @@ -1037,6 +1062,7 @@ void render_hud_attachments()  	if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())  	{ +		LLPipeline::sRenderingHUDs = TRUE;  		LLCamera hud_cam = *LLViewerCamera::getInstance();  		hud_cam.setOrigin(-1.f,0,0);  		hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1)); @@ -1081,10 +1107,13 @@ void render_hud_attachments()  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA); +		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_MASK); +		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP); +		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_MATERIAL);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY); @@ -1109,6 +1138,7 @@ void render_hud_attachments()  			gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);  		}  		LLPipeline::sUseOcclusion = use_occlusion; +		LLPipeline::sRenderingHUDs = FALSE;  	}  	gGL.matrixMode(LLRender::MM_PROJECTION);  	gGL.popMatrix(); diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 61b1b8d846..ab19a12014 100755 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -256,7 +256,7 @@ class AddFavoriteLandmarkCallback : public LLInventoryCallback  public:  	AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}  	void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; } - +	  private:  	void fire(const LLUUID& inv_item); @@ -283,13 +283,13 @@ public:  	// virtual  	void fire(const LLUUID& item_id) -	{ +{  		mFireFunc(item_id);  	}  	// virtual  	~LLBoostFuncInventoryCallback() -	{ +{  		mDestroyFunc();  	} diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index beca08203f..5e2f05f468 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -147,6 +147,8 @@ void handle_test_load_url(void*);  //extern BOOL gDebugAvatarRotation;  extern BOOL gDebugClicks;  extern BOOL gDebugWindowProc; +extern BOOL gShaderProfileFrame; +  //extern BOOL gDebugTextEditorTips;  //extern BOOL gDebugSelectMgr; @@ -291,6 +293,7 @@ void request_friendship(const LLUUID& agent_id);  // Tools menu  void handle_selected_texture_info(void*); +void handle_selected_material_info();  void handle_dump_followcam(void*);  void handle_viewer_enable_message_log(void*); @@ -1189,28 +1192,6 @@ class LLAdvancedCheckWireframe : public view_listener_t  	}  }; -////////////////////// -// TEXTURE ATLAS // -////////////////////// - -class LLAdvancedToggleTextureAtlas : public view_listener_t -{ -	bool handleEvent(const LLSD& userdata) -	{ -		LLViewerTexture::sUseTextureAtlas = !LLViewerTexture::sUseTextureAtlas; -		gSavedSettings.setBOOL("EnableTextureAtlas", LLViewerTexture::sUseTextureAtlas) ; -		return true; -	} -}; - -class LLAdvancedCheckTextureAtlas : public view_listener_t -{ -	bool handleEvent(const LLSD& userdata) -	{ -		bool new_value = LLViewerTexture::sUseTextureAtlas; // <-- make this using LLCacheControl -		return new_value; -	} -};  //////////////////////////  // DUMP SCRIPTED CAMERA // @@ -6463,7 +6444,7 @@ class LLAttachmentDetachFromPoint : public view_listener_t  				LLViewerObject *attached_object = (*iter);  				ids_to_remove.push_back(attached_object->getAttachmentItemID());  			} -		} +			}  		if (!ids_to_remove.empty())  		{  			LLAppearanceMgr::instance().removeItemsFromAvatar(ids_to_remove); @@ -6920,6 +6901,47 @@ void handle_selected_texture_info(void*)  	}  } +void handle_selected_material_info() +{ +	for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin(); +		iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++) +	{ +		LLSelectNode* node = *iter; +		 +		std::string msg; +		msg.assign("Material info for: \n"); +		msg.append(node->mName); +		 +		U8 te_count = node->getObject()->getNumTEs(); +		// map from material ID to list of faces using it +		typedef std::map<LLMaterialID, std::vector<U8> > map_t; +		map_t faces_per_material; +		for (U8 i = 0; i < te_count; i++) +		{ +			if (!node->isTESelected(i)) continue; +	 +			const LLMaterialID& material_id = node->getObject()->getTE(i)->getMaterialID(); +			faces_per_material[material_id].push_back(i); +		} +		// Per-material, dump which faces are using it. +		map_t::iterator it; +		for (it = faces_per_material.begin(); it != faces_per_material.end(); ++it) +		{ +			const LLMaterialID& material_id = it->first; +			msg += llformat("%s on face ", material_id.asString().c_str()); +			for (U8 i = 0; i < it->second.size(); ++i) +			{ +				msg.append( llformat("%d ", (S32)(it->second[i]))); +			} +			msg.append("\n"); +		} + +		LLSD args; +		args["MESSAGE"] = msg; +		LLNotificationsUtil::add("SystemMessage", args); +	} +} +  void handle_test_male(void*)  {  	LLAppearanceMgr::instance().wearOutfitByName("Male Shape & Outfit"); @@ -7022,6 +7044,15 @@ class LLAdvancedClickRenderShadowOption: public view_listener_t  	}  }; +class LLAdvancedClickRenderProfile: public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +		gShaderProfileFrame = TRUE; +		return true; +	} +}; +  void menu_toggle_attached_lights(void* user_data)  {  	LLPipeline::sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); @@ -8442,11 +8473,10 @@ void initialize_menus()  	view_listener_t::addMenu(new LLAdvancedToggleInfoDisplay(), "Advanced.ToggleInfoDisplay");  	view_listener_t::addMenu(new LLAdvancedCheckInfoDisplay(), "Advanced.CheckInfoDisplay");  	view_listener_t::addMenu(new LLAdvancedSelectedTextureInfo(), "Advanced.SelectedTextureInfo"); +	commit.add("Advanced.SelectedMaterialInfo", boost::bind(&handle_selected_material_info));  	view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");  	view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");  	// Develop > Render -	view_listener_t::addMenu(new LLAdvancedToggleTextureAtlas(), "Advanced.ToggleTextureAtlas"); -	view_listener_t::addMenu(new LLAdvancedCheckTextureAtlas(), "Advanced.CheckTextureAtlas");  	view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");  	view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO");  	view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred"); @@ -8460,7 +8490,7 @@ void initialize_menus()  	view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles");  	view_listener_t::addMenu(new LLAdvancedCheckRenderShadowOption(), "Advanced.CheckRenderShadowOption");  	view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption"); -	 +	view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");  	#ifdef TOGGLE_HACKED_GODLIKE_VIEWER  	view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode"); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 064e96e394..6f7b2f40e6 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -201,6 +201,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe  	mTotalCRC(0),  	mListIndex(-1),  	mTEImages(NULL), +	mTENormalMaps(NULL), +	mTESpecularMaps(NULL),  	mGLName(0),  	mbCanSelect(TRUE),  	mFlags(0), @@ -321,6 +323,18 @@ void LLViewerObject::deleteTEImages()  {  	delete[] mTEImages;  	mTEImages = NULL; +	 +	if (mTENormalMaps != NULL) +	{ +		delete[] mTENormalMaps; +		mTENormalMaps = NULL; +	} +	 +	if (mTESpecularMaps != NULL) +	{ +		delete[] mTESpecularMaps; +		mTESpecularMaps = NULL; +	}	  }  void LLViewerObject::markDead() @@ -516,6 +530,17 @@ void LLViewerObject::setNameValueList(const std::string& name_value_list)  	}  } +void LLViewerObject::setSelected(BOOL sel) +{ +	mUserSelected = sel; +	resetRot(); + +	if (!sel) +	{ +		setAllTESelected(false); +	} +} +  // This method returns true if the object is over land owned by the  // agent.  bool LLViewerObject::isReturnable() @@ -3796,19 +3821,19 @@ LLViewerObject* LLViewerObject::getRootEdit() const  } -BOOL LLViewerObject::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +BOOL LLViewerObject::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  										  S32 face,  										  BOOL pick_transparent,  										  S32* face_hit, -										  LLVector3* intersection, +										  LLVector4a* intersection,  										  LLVector2* tex_coord, -										  LLVector3* normal, -										  LLVector3* bi_normal) +										  LLVector4a* normal, +										  LLVector4a* tangent)  {  	return false;  } -BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end) +BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end)  {  	if (mDrawable.isNull() || mDrawable->isDead())  	{ @@ -3825,11 +3850,7 @@ BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVect  	size.setSub(ext[1], ext[0]);  	size.mul(0.5f); -	LLVector4a starta, enda; -	starta.load3(start.mV); -	enda.load3(end.mV); - -	return LLLineSegmentBoxIntersect(starta, enda, center, size); +	return LLLineSegmentBoxIntersect(start, end, center, size);  }  U8 LLViewerObject::getMediaType() const @@ -3928,25 +3949,39 @@ void LLViewerObject::setNumTEs(const U8 num_tes)  		{  			LLPointer<LLViewerTexture> *new_images;  			new_images = new LLPointer<LLViewerTexture>[num_tes]; +			 +			LLPointer<LLViewerTexture> *new_normmaps; +			new_normmaps = new LLPointer<LLViewerTexture>[num_tes]; +			 +			LLPointer<LLViewerTexture> *new_specmaps; +			new_specmaps = new LLPointer<LLViewerTexture>[num_tes];  			for (i = 0; i < num_tes; i++)  			{  				if (i < getNumTEs())  				{  					new_images[i] = mTEImages[i]; +					new_normmaps[i] = mTENormalMaps[i]; +					new_specmaps[i] = mTESpecularMaps[i];  				}  				else if (getNumTEs())  				{  					new_images[i] = mTEImages[getNumTEs()-1]; +					new_normmaps[i] = mTENormalMaps[getNumTEs()-1]; +					new_specmaps[i] = mTESpecularMaps[getNumTEs()-1];  				}  				else  				{  					new_images[i] = NULL; +					new_normmaps[i] = NULL; +					new_specmaps[i] = NULL;  				}  			}  			deleteTEImages();  			mTEImages = new_images; +			mTENormalMaps = new_normmaps; +			mTESpecularMaps = new_specmaps;  		}  		else  		{ @@ -4025,12 +4060,18 @@ void LLViewerObject::sendTEUpdate() const  void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)  {  	LLPrimitive::setTE(te, texture_entry); -//  This doesn't work, don't get any textures. -//	if (mDrawable.notNull() && mDrawable->isVisible()) -//	{ -		const LLUUID& image_id = getTE(te)->getID(); + +	const LLUUID& image_id = getTE(te)->getID();  		mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); -//	} +	 +	if (getTE(te)->getMaterialParams().notNull()) +	{ +		const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID(); +		mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); +		 +		const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID(); +		mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); +	}  }  void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep) @@ -4065,6 +4106,52 @@ S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image)  	return retval;  } +S32 LLViewerObject::setTENormalMapCore(const U8 te, LLViewerTexture *image) +{ +	S32 retval = TEM_CHANGE_TEXTURE; +	const LLUUID& uuid = image ? image->getID() : LLUUID::null; +	if (uuid != getTE(te)->getID() || +		uuid == LLUUID::null) +	{ +		LLTextureEntry* tep = getTE(te); +		LLMaterial* mat = NULL; +		if (tep) +		{ +		   mat = tep->getMaterialParams(); +		} + +		if (mat) +		{ +			mat->setNormalID(uuid); +		} +	} +	changeTENormalMap(te,image);	 +	return retval; +} + +S32 LLViewerObject::setTESpecularMapCore(const U8 te, LLViewerTexture *image) +{ +	S32 retval = TEM_CHANGE_TEXTURE; +	const LLUUID& uuid = image ? image->getID() : LLUUID::null; +	if (uuid != getTE(te)->getID() || +		uuid == LLUUID::null) +	{ +		LLTextureEntry* tep = getTE(te); +		LLMaterial* mat = NULL; +		if (tep) +		{ +			mat = tep->getMaterialParams(); +		} + +		if (mat) +		{ +			mat->setSpecularID(uuid); +		}		 +	} +	changeTESpecularMap(te, image); +	return retval; +} +  //virtual  void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)   { @@ -4075,6 +4162,26 @@ void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)  	mTEImages[index] = new_image ;  } +void LLViewerObject::changeTENormalMap(S32 index, LLViewerTexture* new_image) +{ +	if(index < 0 || index >= getNumTEs()) +	{ +		return ; +	} +	mTENormalMaps[index] = new_image ; +	refreshMaterials(); +} + +void LLViewerObject::changeTESpecularMap(S32 index, LLViewerTexture* new_image) +{ +	if(index < 0 || index >= getNumTEs()) +	{ +		return ; +	} +	mTESpecularMaps[index] = new_image ; +	refreshMaterials(); +} +  S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)  {  	// Invalid host == get from the agent's sim @@ -4083,6 +4190,19 @@ S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)  	return setTETextureCore(te,image);  } +S32 LLViewerObject::setTENormalMap(const U8 te, const LLUUID& uuid) +{ +	LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture( +		uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid); +	return setTENormalMapCore(te, image); +} + +S32 LLViewerObject::setTESpecularMap(const U8 te, const LLUUID& uuid) +{ +	LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture( +		uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid); +	return setTESpecularMapCore(te, image); +}  S32 LLViewerObject::setTEColor(const U8 te, const LLColor3& color)  { @@ -4243,6 +4363,61 @@ S32 LLViewerObject::setTEGlow(const U8 te, const F32 glow)  	return retval;  } +S32 LLViewerObject::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) +{ +	S32 retval = 0; +	const LLTextureEntry *tep = getTE(te); +	if (!tep) +	{ +		LL_WARNS("Material") << "No texture entry for te " << (S32)te +							 << ", object " << mID +							 << ", material " << pMaterialID +							 << LL_ENDL; +	} +	//else if (pMaterialID != tep->getMaterialID()) +	{ +		LL_DEBUGS("Material") << "Changing texture entry for te " << (S32)te +							 << ", object " << mID +							 << ", material " << pMaterialID +							 << LL_ENDL; +		retval = LLPrimitive::setTEMaterialID(te, pMaterialID); +		refreshMaterials(); +	} +	return retval; +} + +S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) +{ +	S32 retval = 0; +	const LLTextureEntry *tep = getTE(te); +	if (!tep) +	{ +		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl; +		return 0; +	} + +	retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams); +	LL_DEBUGS("Material") << "Changing material params for te " << (S32)te +							<< ", object " << mID +			               << " (" << retval << ")" +							<< LL_ENDL; +	setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null); +	setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null); + +	refreshMaterials(); +	return retval; +} + +void LLViewerObject::refreshMaterials() +{ +	setChanged(ALL_CHANGED); +	if (mDrawable.notNull()) +	{ +		gPipeline.markTextured(mDrawable); +		gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); +		dirtySpatialGroup(TRUE); +	} +}  S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t)  { @@ -4344,6 +4519,50 @@ LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const  } +LLViewerTexture *LLViewerObject::getTENormalMap(const U8 face) const +{ +	//	llassert(mTEImages); +	 +	if (face < getNumTEs()) +	{ +		LLViewerTexture* image = mTENormalMaps[face]; +		if (image) +		{ +			return image; +		} +		else +		{ +			return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep); +		} +	} +	 +	llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl; +	 +	return NULL; +} + +LLViewerTexture *LLViewerObject::getTESpecularMap(const U8 face) const +{ +	//	llassert(mTEImages); +	 +	if (face < getNumTEs()) +	{ +		LLViewerTexture* image = mTESpecularMaps[face]; +		if (image) +		{ +			return image; +		} +		else +		{ +			return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep); +		} +	} +	 +	llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl; +	 +	return NULL; +} +  void LLViewerObject::fitFaceTexture(const U8 face)  {  	llinfos << "fitFaceTexture not implemented" << llendl; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 316dbce7d0..ea0d55cda5 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -211,7 +211,7 @@ public:  	LLViewerRegion* getRegion() const				{ return mRegionp; }  	BOOL isSelected() const							{ return mUserSelected; } -	virtual void setSelected(BOOL sel)				{ mUserSelected = sel; resetRot();} +	virtual void setSelected(BOOL sel);  	const LLUUID &getID() const						{ return mID; }  	U32 getLocalID() const							{ return mLocalID; } @@ -258,17 +258,17 @@ public:  	//detect if given line segment (in agent space) intersects with this viewer object.  	//returns TRUE if intersection detected and returns information about intersection -	virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +	virtual BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  									  S32 face = -1,                          // which face to check, -1 = ALL_SIDES  									  BOOL pick_transparent = FALSE,  									  S32* face_hit = NULL,                   // which face was hit -									  LLVector3* intersection = NULL,         // return the intersection point +									  LLVector4a* intersection = NULL,         // return the intersection point  									  LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -									  LLVector3* normal = NULL,               // return the surface normal at the intersection point -									  LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point +									  LLVector4a* normal = NULL,               // return the surface normal at the intersection point +									  LLVector4a* tangent = NULL             // return the surface tangent at the intersection point  		); -	virtual BOOL lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end); +	virtual BOOL lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end);  	virtual const LLVector3d getPositionGlobal() const;  	virtual const LLVector3 &getPositionRegion() const; @@ -301,7 +301,11 @@ public:  	/*virtual*/	void	setNumTEs(const U8 num_tes);  	/*virtual*/	void	setTE(const U8 te, const LLTextureEntry &texture_entry);  	/*virtual*/ S32		setTETexture(const U8 te, const LLUUID &uuid); -	S32 				setTETextureCore(const U8 te, LLViewerTexture *image); +	/*virtual*/ S32		setTENormalMap(const U8 te, const LLUUID &uuid); +	/*virtual*/ S32		setTESpecularMap(const U8 te, const LLUUID &uuid); +	S32 setTETextureCore(const U8 te, LLViewerTexture *image); +	S32 setTENormalMapCore(const U8 te, LLViewerTexture *image); +	S32 setTESpecularMapCore(const U8 te, LLViewerTexture *image);  	/*virtual*/ S32		setTEColor(const U8 te, const LLColor3 &color);  	/*virtual*/ S32		setTEColor(const U8 te, const LLColor4 &color);  	/*virtual*/ S32		setTEScale(const U8 te, const F32 s, const F32 t); @@ -318,10 +322,22 @@ public:  	/*virtual*/	S32		setTEFullbright(const U8 te, const U8 fullbright );  	/*virtual*/	S32		setTEMediaFlags(const U8 te, const U8 media_flags );  	/*virtual*/ S32     setTEGlow(const U8 te, const F32 glow); +	/*virtual*/ S32     setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); +	/*virtual*/ S32		setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams); + +	// Used by Materials update functions to properly kick off rebuilds +	// of VBs etc when materials updates require changes. +	// +	void refreshMaterials(); +  	/*virtual*/	BOOL	setMaterial(const U8 material);  	virtual		void	setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive  	virtual     void    changeTEImage(S32 index, LLViewerTexture* new_image)  ; +	virtual     void    changeTENormalMap(S32 index, LLViewerTexture* new_image)  ; +	virtual     void    changeTESpecularMap(S32 index, LLViewerTexture* new_image)  ;  	LLViewerTexture		*getTEImage(const U8 te) const; +	LLViewerTexture		*getTENormalMap(const U8 te) const; +	LLViewerTexture		*getTESpecularMap(const U8 te) const;  	void fitFaceTexture(const U8 face);  	void sendTEUpdate() const;			// Sends packed representation of all texture entry information @@ -596,6 +612,8 @@ public:  	S32				mListIndex;  	LLPointer<LLViewerTexture> *mTEImages; +	LLPointer<LLViewerTexture> *mTENormalMaps; +	LLPointer<LLViewerTexture> *mTESpecularMaps;  	// Selection, picking and rendering variables  	U32				mGLName;			// GL "name" used by selection code diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 421e354610..adc346529e 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -143,7 +143,7 @@ public:  	CapabilityMap mCapabilities;  	CapabilityMap mSecondCapabilitiesTracker;  - +	  	LLEventPoll* mEventPoll;  	S32 mSeedCapMaxAttempts; @@ -220,7 +220,7 @@ public:  		}      } -   void result(const LLSD& content) +    void result(const LLSD& content)      {  		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);  		if(!regionp) //region was removed @@ -1587,7 +1587,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("EventQueueGet");  	if (gSavedSettings.getBOOL("UseHTTPInventory")) -	{	 +	{  		capabilityNames.append("FetchLib2");  		capabilityNames.append("FetchLibDescendents2");  		capabilityNames.append("FetchInventory2"); @@ -1610,7 +1610,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("LandResources");  	capabilityNames.append("MapLayer");  	capabilityNames.append("MapLayerGod"); -	capabilityNames.append("MeshUploadFlag");	 +	capabilityNames.append("MeshUploadFlag");  	capabilityNames.append("NavMeshGenerationStatus");  	capabilityNames.append("NewFileAgentInventory");  	capabilityNames.append("ObjectMedia"); @@ -1621,6 +1621,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("ProductInfoRequest");  	capabilityNames.append("ProvisionVoiceAccountRequest");  	capabilityNames.append("RemoteParcelRequest"); +	capabilityNames.append("RenderMaterials");  	capabilityNames.append("RequestTextureDownload");  	capabilityNames.append("ResourceCostSelected");  	capabilityNames.append("RetrieveNavMeshSrc"); @@ -1650,7 +1651,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("ViewerMetrics");  	capabilityNames.append("ViewerStartAuction");  	capabilityNames.append("ViewerStats"); - +	  	// Please add new capabilities alphabetically to reduce  	// merge conflicts.  } @@ -1658,8 +1659,8 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  void LLViewerRegion::setSeedCapability(const std::string& url)  {  	if (getCapability("Seed") == url) -    {	 -		//llwarns << "Ignoring duplicate seed capability" << llendl; +    { +		// llwarns << "Ignoring duplicate seed capability" << llendl;  		//Instead of just returning we build up a second set of seed caps and compare them   		//to the "original" seed cap received and determine why there is problem!  		LLSD capabilityNames = LLSD::emptyArray(); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index b5fe4677b7..56cd0c9ea1 100755 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -342,7 +342,7 @@ public:  	void getNeighboringRegionsStatus( std::vector<S32>& regions );  	const LLViewerRegionImpl * getRegionImpl() const { return mImpl; }  	LLViewerRegionImpl * getRegionImplNC() { return mImpl; } - +	  public:  	struct CompareDistance  	{ diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index ba9818946c..b9e0847935 100755 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -44,6 +44,18 @@  #if LL_DARWIN  #include "OpenGL/OpenGL.h" + +// include spec exp clamp to fix older mac rendering artifacts +// +#define SINGLE_FP_PERMUTATION(shader)					\ +	if (gGLManager.mIsMobileGF)							\ +	{																\ +		shader.addPermutation("SINGLE_FP_ONLY","1");		\ +	} + + +#else +#define SINGLE_FP_PERMUTATION(shader)  #endif  #ifdef LL_RELEASE_FOR_DOWNLOAD @@ -68,7 +80,7 @@ LLGLSLShader			gTransformPositionProgram;  LLGLSLShader			gTransformTexCoordProgram;  LLGLSLShader			gTransformNormalProgram;  LLGLSLShader			gTransformColorProgram; -LLGLSLShader			gTransformBinormalProgram; +LLGLSLShader			gTransformTangentProgram;  //utility shaders  LLGLSLShader	gOcclusionProgram; @@ -143,6 +155,9 @@ LLGLSLShader		gUnderWaterProgram;  //interface shaders  LLGLSLShader		gHighlightProgram; +LLGLSLShader		gHighlightNormalProgram; +LLGLSLShader		gHighlightSpecularProgram; +  LLGLSLShader		gPathfindingProgram;  LLGLSLShader		gPathfindingNoNormalsProgram; @@ -200,13 +215,20 @@ LLGLSLShader			gDeferredEmissiveProgram;  LLGLSLShader			gDeferredPostProgram;  LLGLSLShader			gDeferredCoFProgram;  LLGLSLShader			gDeferredDoFCombineProgram; +LLGLSLShader			gDeferredPostGammaCorrectProgram;  LLGLSLShader			gFXAAProgram;  LLGLSLShader			gDeferredPostNoDoFProgram;  LLGLSLShader			gDeferredWLSkyProgram;  LLGLSLShader			gDeferredWLCloudProgram;  LLGLSLShader			gDeferredStarProgram; +LLGLSLShader			gDeferredFullbrightShinyProgram; +LLGLSLShader			gDeferredSkinnedFullbrightShinyProgram; +LLGLSLShader			gDeferredSkinnedFullbrightProgram;  LLGLSLShader			gNormalMapGenProgram; +// Deferred materials shaders +LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; +  LLViewerShaderMgr::LLViewerShaderMgr() :  	mVertexShaderLevel(SHADER_COUNT, 0),  	mMaxAvatarShaderLevel(0) @@ -271,9 +293,20 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gUnderWaterProgram);  	mShaderList.push_back(&gDeferredSunProgram);  	mShaderList.push_back(&gDeferredSoftenProgram); +	mShaderList.push_back(&gDeferredMaterialProgram[1]); +	mShaderList.push_back(&gDeferredMaterialProgram[5]); +	mShaderList.push_back(&gDeferredMaterialProgram[9]); +	mShaderList.push_back(&gDeferredMaterialProgram[13]); +	mShaderList.push_back(&gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT]); +	mShaderList.push_back(&gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT]); +	mShaderList.push_back(&gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT]); +	mShaderList.push_back(&gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT]);	  	mShaderList.push_back(&gDeferredAlphaProgram);  	mShaderList.push_back(&gDeferredSkinnedAlphaProgram);  	mShaderList.push_back(&gDeferredFullbrightProgram); +	mShaderList.push_back(&gDeferredFullbrightShinyProgram); +	mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram); +	mShaderList.push_back(&gDeferredSkinnedFullbrightProgram);  	mShaderList.push_back(&gDeferredEmissiveProgram);  	mShaderList.push_back(&gDeferredAvatarEyesProgram);  	mShaderList.push_back(&gDeferredWaterProgram); @@ -451,6 +484,12 @@ void LLViewerShaderMgr::setShaders()  		S32 deferred_class = 0;  		S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0; +		static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback"); +		if (!use_transform_feedback) +		{ +			transform_class = 0; +		} +		  		if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&  		    gSavedSettings.getBOOL("RenderDeferred") &&  			gSavedSettings.getBOOL("RenderAvatarVP") && @@ -740,6 +779,8 @@ void LLViewerShaderMgr::unloadShaders()  	gAvatarEyeballProgram.unload();  	gAvatarPickProgram.unload();  	gHighlightProgram.unload(); +	gHighlightNormalProgram.unload(); +	gHighlightSpecularProgram.unload();  	gWLSkyProgram.unload();  	gWLCloudProgram.unload(); @@ -760,7 +801,7 @@ void LLViewerShaderMgr::unloadShaders()  	gTransformTexCoordProgram.unload();  	gTransformNormalProgram.unload();  	gTransformColorProgram.unload(); -	gTransformBinormalProgram.unload(); +	gTransformTangentProgram.unload();  	mVertexShaderLevel[SHADER_LIGHTING] = 0;  	mVertexShaderLevel[SHADER_OBJECT] = 0; @@ -780,9 +821,6 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	// Load basic dependency shaders first  	// All of these have to load for any shaders to function -#if LL_DARWIN // Mac can't currently handle all 8 lights,  -	S32 sum_lights_class = 2; -#else   	S32 sum_lights_class = 3;  	// class one cards will get the lower sum lights @@ -793,7 +831,6 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	{  		sum_lights_class = 2;  	} -#endif  	// If we have sun and moon only checked, then only sum those lights.  	if (gPipeline.getLightingDetail() == 0) @@ -801,6 +838,14 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  		sum_lights_class = 1;  	} +#if LL_DARWIN +	// Work around driver crashes on older Macs when using deferred rendering +	// NORSPEC-59 +	// +	if (gGLManager.mIsMobileGF) +		sum_lights_class = 3; +#endif +	  	// Use the feature table to mask out the max light level to use.  Also make sure it's at least 1.  	S32 max_light_class = gSavedSettings.getS32("RenderShaderLightingMaxLevel");  	sum_lights_class = llclamp(sum_lights_class, 1, max_light_class); @@ -826,12 +871,14 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  		shaders.push_back( make_pair( "objects/indexedTextureV.glsl",			1 ) );  	}  	shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl",		1 ) ); - +	 +	boost::unordered_map<std::string, std::string> attribs; +	  	// We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.  	for (U32 i = 0; i < shaders.size(); i++)  	{  		// Note usage of GL_VERTEX_SHADER_ARB -		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB) == 0) +		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, &attribs) == 0)  		{  			return FALSE;  		} @@ -879,11 +926,11 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) );  	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) );  	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); -	 +  	for (U32 i = 0; i < shaders.size(); i++)  	{  		// Note usage of GL_FRAGMENT_SHADER_ARB -		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, index_channels[i]) == 0) +		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, &attribs, index_channels[i]) == 0)  		{  			return FALSE;  		} @@ -1097,12 +1144,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredPostProgram.unload();		  		gDeferredCoFProgram.unload();		  		gDeferredDoFCombineProgram.unload(); +		gDeferredPostGammaCorrectProgram.unload();  		gFXAAProgram.unload();  		gDeferredWaterProgram.unload();  		gDeferredWLSkyProgram.unload();  		gDeferredWLCloudProgram.unload();  		gDeferredStarProgram.unload(); +		gDeferredFullbrightShinyProgram.unload(); +		gDeferredSkinnedFullbrightShinyProgram.unload(); +		gDeferredSkinnedFullbrightProgram.unload(); +  		gNormalMapGenProgram.unload(); +		for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) +		{ +			gDeferredMaterialProgram[i].unload(); +		}  		return TRUE;  	} @@ -1196,10 +1252,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true;  		gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true;  		gDeferredSkinnedAlphaProgram.mShaderFiles.clear(); -		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		 +		gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1"); +		gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); +		gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1"); +		gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");  		success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL);  		// Hack to include uniforms for lighting without linking in lighting file @@ -1216,7 +1275,57 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredBumpProgram.createShader(NULL, NULL);  	} +	 +	gDeferredMaterialProgram[1].mFeatures.hasLighting = false; +	gDeferredMaterialProgram[5].mFeatures.hasLighting = false; +	gDeferredMaterialProgram[9].mFeatures.hasLighting = false; +	gDeferredMaterialProgram[13].mFeatures.hasLighting = false; +	gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; +	gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; +	gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; +	gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; +	for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) +	{ +		if (success) +		{ +			gDeferredMaterialProgram[i].mName = llformat("Deferred Material Shader %d", i); +			 +			U32 alpha_mode = i & 0x3; + +			gDeferredMaterialProgram[i].mShaderFiles.clear(); +			gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB)); +			gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB)); +			gDeferredMaterialProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +			gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0"); +			gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0"); +			gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); +			gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); +			bool has_skin = i & 0x10; +			gDeferredMaterialProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0"); + +			SINGLE_FP_PERMUTATION(gDeferredMaterialProgram[i]); + +			if (has_skin) +			{ +				gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true; +			} + +			success = gDeferredMaterialProgram[i].createShader(NULL, NULL); +		} +	} + +	gDeferredMaterialProgram[1].mFeatures.hasLighting = true; +	gDeferredMaterialProgram[5].mFeatures.hasLighting = true; +	gDeferredMaterialProgram[9].mFeatures.hasLighting = true; +	gDeferredMaterialProgram[13].mFeatures.hasLighting = true; +	gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; +	gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; +	gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; +	gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + + +	  	if (success)  	{  		gDeferredTreeProgram.mName = "Deferred Tree Shader"; @@ -1254,6 +1363,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + +		SINGLE_FP_PERMUTATION(gDeferredLightProgram); +  		success = gDeferredLightProgram.createShader(NULL, NULL);  	} @@ -1264,6 +1376,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredMultiLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + +		SINGLE_FP_PERMUTATION(gDeferredMultiLightProgram); +  		success = gDeferredMultiLightProgram.createShader(NULL, NULL);  	} @@ -1274,6 +1389,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + +		SINGLE_FP_PERMUTATION(gDeferredSpotLightProgram); +  		success = gDeferredSpotLightProgram.createShader(NULL, NULL);  	} @@ -1284,6 +1402,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + +		SINGLE_FP_PERMUTATION(gDeferredMultiSpotLightProgram); +  		success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);  	} @@ -1310,6 +1431,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER_ARB));  		gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + +		SINGLE_FP_PERMUTATION(gDeferredSunProgram); +  		success = gDeferredSunProgram.createShader(NULL, NULL);  	} @@ -1320,6 +1444,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredBlurLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + +		SINGLE_FP_PERMUTATION(gDeferredBlurLightProgram); +  		success = gDeferredBlurLightProgram.createShader(NULL, NULL);  	} @@ -1346,8 +1473,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAlphaProgram.mShaderFiles.clear();  		gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAlphaProgram.addPermutation("USE_INDEXED_TEX", "1"); +		gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); +		gDeferredAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");  		gDeferredAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		SINGLE_FP_PERMUTATION(gDeferredAlphaProgram); +  		success = gDeferredAlphaProgram.createShader(NULL, NULL);  		// Hack @@ -1385,6 +1517,50 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader"; +		gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; +		gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true; +		gDeferredFullbrightShinyProgram.mFeatures.hasTransport = true; +		gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels-1; +		gDeferredFullbrightShinyProgram.mShaderFiles.clear(); +		gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		success = gDeferredFullbrightShinyProgram.createShader(NULL, &mShinyUniforms); +	} + +	if (success) +	{ +		gDeferredSkinnedFullbrightProgram.mName = "Skinned Fullbright Shader"; +		gDeferredSkinnedFullbrightProgram.mFeatures.calculatesAtmospherics = true; +		gDeferredSkinnedFullbrightProgram.mFeatures.hasGamma = true; +		gDeferredSkinnedFullbrightProgram.mFeatures.hasTransport = true; +		gDeferredSkinnedFullbrightProgram.mFeatures.hasObjectSkinning = true; +		gDeferredSkinnedFullbrightProgram.mFeatures.disableTextureIndex = true; +		gDeferredSkinnedFullbrightProgram.mShaderFiles.clear(); +		gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredSkinnedFullbrightProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		success = gDeferredSkinnedFullbrightProgram.createShader(NULL, NULL); +	} + +	if (success) +	{ +		gDeferredSkinnedFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader"; +		gDeferredSkinnedFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; +		gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasGamma = true; +		gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasTransport = true; +		gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; +		gDeferredSkinnedFullbrightShinyProgram.mFeatures.disableTextureIndex = true; +		gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.clear(); +		gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredSkinnedFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		success = gDeferredSkinnedFullbrightShinyProgram.createShader(NULL, &mShinyUniforms); +	} + +	if (success) +	{  		gDeferredEmissiveProgram.mName = "Deferred Emissive Shader";  		gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true;  		gDeferredEmissiveProgram.mFeatures.hasGamma = true; @@ -1420,6 +1596,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSoftenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		SINGLE_FP_PERMUTATION(gDeferredSoftenProgram); +  		if (gSavedSettings.getBOOL("RenderDeferredSSAO"))  		{ //if using SSAO, take screen space light map into account as if shadows are enabled  			gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2); @@ -1435,6 +1613,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");  		success = gDeferredShadowProgram.createShader(NULL, NULL);  	} @@ -1444,6 +1623,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredShadowCubeProgram.mShaderFiles.clear();  		gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");  		gDeferredShadowCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredShadowCubeProgram.createShader(NULL, NULL);  	} @@ -1455,6 +1635,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredShadowAlphaMaskProgram.mShaderFiles.clear();  		gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");  		gDeferredShadowAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);  	} @@ -1466,6 +1647,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarShadowProgram.mShaderFiles.clear();  		gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");  		gDeferredAvatarShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredAvatarShadowProgram.createShader(NULL, &mAvatarUniforms);  	} @@ -1477,6 +1659,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAttachmentShadowProgram.mShaderFiles.clear();  		gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");  		gDeferredAttachmentShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL);  	} @@ -1515,8 +1698,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true;  		gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;  		gDeferredAvatarAlphaProgram.mShaderFiles.clear(); -		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaNoColorV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedNoColorF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1"); +		gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1"); +		gDeferredAvatarAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");  		gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredAvatarAlphaProgram.createShader(NULL, &mAvatarUniforms); @@ -1524,6 +1710,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true;  		gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true;  	} +	 +	if (success) +	{ +		gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process"; +		gDeferredPostGammaCorrectProgram.mShaderFiles.clear(); +		gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredPostGammaCorrectProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL); +	}  	if (success)  	{ @@ -2306,6 +2502,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectSimpleProgram.mFeatures.hasAtmospherics = true;  			gSkinnedObjectSimpleProgram.mFeatures.hasLighting = true;  			gSkinnedObjectSimpleProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectSimpleProgram.mFeatures.hasAlphaMask = true;  			gSkinnedObjectSimpleProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectSimpleProgram.mShaderFiles.clear();  			gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2322,6 +2519,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightProgram.mFeatures.hasTransport = true;  			gSkinnedObjectFullbrightProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectFullbrightProgram.mFeatures.hasAlphaMask = true;			  			gSkinnedObjectFullbrightProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2372,6 +2570,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightShinyProgram.mFeatures.isShiny = true;  			gSkinnedObjectFullbrightShinyProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectFullbrightShinyProgram.mFeatures.hasAlphaMask = true;  			gSkinnedObjectFullbrightShinyProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2388,6 +2587,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectShinySimpleProgram.mFeatures.hasGamma = true;  			gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true;  			gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectShinySimpleProgram.mFeatures.hasAlphaMask = true;  			gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true;  			gSkinnedObjectShinySimpleProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectShinySimpleProgram.mShaderFiles.clear(); @@ -2425,6 +2625,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasTransport = true;  			gSkinnedObjectFullbrightWaterProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasAlphaMask = true;  			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true;  			gSkinnedObjectFullbrightWaterProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; @@ -2444,6 +2645,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasAlphaMask = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; @@ -2462,6 +2664,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasGamma = true;  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAtmospherics = true;  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAlphaMask = true;  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.isShiny = true;  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasWaterFog = true;  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.disableTextureIndex = true; @@ -2602,6 +2805,26 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  	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";  		gUIProgram.mShaderFiles.clear();  		gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2845,7 +3068,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()  		gTransformTexCoordProgram.unload();  		gTransformNormalProgram.unload();  		gTransformColorProgram.unload(); -		gTransformBinormalProgram.unload(); +		gTransformTangentProgram.unload();  		return TRUE;  	} @@ -2908,16 +3131,16 @@ BOOL LLViewerShaderMgr::loadTransformShaders()  	if (success)  	{ -		gTransformBinormalProgram.mName = "Binormal Transform Shader"; -		gTransformBinormalProgram.mShaderFiles.clear(); -		gTransformBinormalProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB)); -		gTransformBinormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; +		gTransformTangentProgram.mName = "Binormal Transform Shader"; +		gTransformTangentProgram.mShaderFiles.clear(); +		gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB)); +		gTransformTangentProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];  		const char* varyings[] = { -			"binormal_out", +			"tangent_out",  		}; -		success = gTransformBinormalProgram.createShader(NULL, NULL, 1, varyings); +		success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings);  	} diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index e3d28f2f5c..8c7de05062 100755 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -28,6 +28,7 @@  #define LL_VIEWER_SHADER_MGR_H  #include "llshadermgr.h" +#include "llmaterial.h"  class LLViewerShaderMgr: public LLShaderMgr  { @@ -216,7 +217,7 @@ extern LLGLSLShader			gTransformPositionProgram;  extern LLGLSLShader			gTransformTexCoordProgram;  extern LLGLSLShader			gTransformNormalProgram;  extern LLGLSLShader			gTransformColorProgram; -extern LLGLSLShader			gTransformBinormalProgram; +extern LLGLSLShader			gTransformTangentProgram; @@ -300,6 +301,9 @@ extern LLGLSLShader			gGlowExtractProgram;  //interface shaders  extern LLGLSLShader			gHighlightProgram; +extern LLGLSLShader			gHighlightNormalProgram; +extern LLGLSLShader			gHighlightSpecularProgram; +  extern LLGLSLShader			gPathfindingProgram;  extern LLGLSLShader			gPathfindingNoNormalsProgram; @@ -349,6 +353,7 @@ extern LLGLSLShader			gDeferredCoFProgram;  extern LLGLSLShader			gDeferredDoFCombineProgram;  extern LLGLSLShader			gFXAAProgram;  extern LLGLSLShader			gDeferredPostNoDoFProgram; +extern LLGLSLShader			gDeferredPostGammaCorrectProgram;  extern LLGLSLShader			gDeferredAvatarShadowProgram;  extern LLGLSLShader			gDeferredAttachmentShadowProgram;  extern LLGLSLShader			gDeferredAlphaProgram; @@ -359,6 +364,13 @@ extern LLGLSLShader			gDeferredAvatarAlphaProgram;  extern LLGLSLShader			gDeferredWLSkyProgram;  extern LLGLSLShader			gDeferredWLCloudProgram;  extern LLGLSLShader			gDeferredStarProgram; +extern LLGLSLShader			gDeferredFullbrightShinyProgram; +extern LLGLSLShader			gDeferredSkinnedFullbrightShinyProgram; +extern LLGLSLShader			gDeferredSkinnedFullbrightProgram;  extern LLGLSLShader			gNormalMapGenProgram; + +// Deferred materials shaders +extern LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; +  #endif diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp index f9a725547f..2b3e293229 100755 --- a/indra/newview/llviewerstatsrecorder.cpp +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -166,6 +166,7 @@ void LLViewerStatsRecorder::recordRequestCacheMissesEvent(S32 count)  void LLViewerStatsRecorder::writeToLog( F32 interval )  { +	size_t data_size = 0;  	F64 delta_time = LLTimer::getTotalSeconds() - mLastSnapshotTime;  	S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures; @@ -187,7 +188,6 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )  		<< mObjectUpdateFailures << " update failures"  		<< llendl; -	U32 data_size;  	if (mObjectCacheFile == NULL)  	{  		mStartTime = LLTimer::getTotalSeconds(); @@ -255,9 +255,9 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )  		<< "\n";  	data_size = data_msg.str().size(); -	if (fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ) != data_size) +	if ( data_size != fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ))  	{ -		llwarns << "failed to write full stats to " << STATS_FILE_NAME << llendl; +				llwarns << "Unable to write complete column data to " << STATS_FILE_NAME << llendl;  	}  	clearStats(); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index eb6c453e76..6cc9f4ace1 100755 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -55,8 +55,6 @@  #include "llappviewer.h"  #include "llface.h"  #include "llviewercamera.h" -#include "lltextureatlas.h" -#include "lltextureatlasmanager.h"  #include "lltextureentry.h"  #include "lltexturemanagerbridge.h"  #include "llmediaentry.h" @@ -73,6 +71,7 @@ LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sMissingAssetImagep =  LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL;  LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL;  LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL; +LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sFlatNormalImagep = NULL;  LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap ;  LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL ;  const std::string sTesterName("TextureTester"); @@ -98,7 +97,6 @@ S32 LLViewerTexture::sMinLargeImageSize = 65536 ; //256 * 256.  S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA ;  BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE ;  F32 LLViewerTexture::sCurrentTime = 0.0f ; -BOOL LLViewerTexture::sUseTextureAtlas        = FALSE ;  F32  LLViewerTexture::sTexelPixelRatio = 1.0f;  LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF; @@ -277,7 +275,7 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(  }  LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile( -	                                               const std::string& filename, +	                                               const std::string& filename,												     												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority, @@ -290,7 +288,7 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(  }  //static  -LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url, +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,									   									 FTType f_type,  									 BOOL usemipmaps,  									 LLViewerTexture::EBoostLevel boost_priority, @@ -397,7 +395,7 @@ void LLViewerTextureManager::init()  	LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE);  	LLViewerTexture::initClass() ; -	 +  	// Create a texture manager bridge.  	gTextureManagerBridgep = new LLViewerTextureManagerBridge; @@ -425,6 +423,7 @@ void LLViewerTextureManager::cleanup()  	LLViewerFetchedTexture::sSmokeImagep = NULL;  	LLViewerFetchedTexture::sMissingAssetImagep = NULL;  	LLViewerFetchedTexture::sWhiteImagep = NULL; +	LLViewerFetchedTexture::sFlatNormalImagep = NULL;  	LLViewerMediaTexture::cleanUpClass() ;	  } @@ -565,8 +564,7 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity  		}  	}  	sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max); -	LLViewerTexture::sUseTextureAtlas = gSavedSettings.getBOOL("EnableTextureAtlas") ; -	 +		  	F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ;  	F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed();  	sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1); @@ -632,9 +630,14 @@ void LLViewerTexture::init(bool firstinit)  	mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval ;  	mAdditionalDecodePriority = 0.f ;	  	mParcelMedia = NULL ; -	mNumFaces = 0 ; +	  	mNumVolumes = 0; -	mFaceList.clear() ; +	mFaceList[LLRender::DIFFUSE_MAP].clear() ; +	mFaceList[LLRender::NORMAL_MAP].clear() ; +	mFaceList[LLRender::SPECULAR_MAP].clear() ; +	mNumFaces[LLRender::DIFFUSE_MAP] =  +	mNumFaces[LLRender::NORMAL_MAP] =  +	mNumFaces[LLRender::SPECULAR_MAP] = 0 ;  	mVolumeList.clear();  } @@ -646,7 +649,9 @@ S8 LLViewerTexture::getType() const  void LLViewerTexture::cleanup()  { -	mFaceList.clear() ; +	mFaceList[LLRender::DIFFUSE_MAP].clear() ; +	mFaceList[LLRender::NORMAL_MAP].clear() ; +	mFaceList[LLRender::SPECULAR_MAP].clear() ;  	mVolumeList.clear();  } @@ -762,38 +767,57 @@ void LLViewerTexture::setKnownDrawSize(S32 width, S32 height)  }  //virtual -void LLViewerTexture::addFace(LLFace* facep)  +void LLViewerTexture::addFace(U32 ch, LLFace* facep)   { -	if(mNumFaces >= mFaceList.size()) +	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + +	if(mNumFaces[ch] >= mFaceList[ch].size())  	{ -		mFaceList.resize(2 * mNumFaces + 1) ;		 +		mFaceList[ch].resize(2 * mNumFaces[ch] + 1) ;		  	} -	mFaceList[mNumFaces] = facep ; -	facep->setIndexInTex(mNumFaces) ; -	mNumFaces++ ; +	mFaceList[ch][mNumFaces[ch]] = facep ; +	facep->setIndexInTex(ch, mNumFaces[ch]) ; +	mNumFaces[ch]++ ;  	mLastFaceListUpdateTimer.reset() ;  }  //virtual -void LLViewerTexture::removeFace(LLFace* facep)  +void LLViewerTexture::removeFace(U32 ch, LLFace* facep)   { -	if(mNumFaces > 1) +	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + +	if(mNumFaces[ch] > 1)  	{ -		S32 index = facep->getIndexInTex() ;  -		mFaceList[index] = mFaceList[--mNumFaces] ; -		mFaceList[index]->setIndexInTex(index) ; +		S32 index = facep->getIndexInTex(ch) ;  +		llassert(index < mFaceList[ch].size()); +		llassert(index < mNumFaces[ch]); +		mFaceList[ch][index] = mFaceList[ch][--mNumFaces[ch]] ; +		mFaceList[ch][index]->setIndexInTex(ch, index) ;  	}  	else   	{ -		mFaceList.clear() ; -		mNumFaces = 0 ; +		mFaceList[ch].clear() ; +		mNumFaces[ch] = 0 ;  	}  	mLastFaceListUpdateTimer.reset() ;  } -S32 LLViewerTexture::getNumFaces() const +S32 LLViewerTexture::getTotalNumFaces() const  { -	return mNumFaces ; +	S32 ret = 0; + +	for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) +	{ +		ret += mNumFaces[i]; +	} + +	return ret; +} + +S32 LLViewerTexture::getNumFaces(U32 ch) const +{ +	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); +	return mNumFaces[ch];  } @@ -816,6 +840,8 @@ void LLViewerTexture::removeVolume(LLVOVolume* volumep)  	if(mNumVolumes > 1)  	{  		S32 index = volumep->getIndexInTex() ;  +		llassert(index < mVolumeList.size()); +		llassert(index < mNumVolumes);  		mVolumeList[index] = mVolumeList[--mNumVolumes] ;  		mVolumeList[index]->setIndexInTex(index) ;  	} @@ -837,18 +863,22 @@ void LLViewerTexture::reorganizeFaceList()  	static const F32 MAX_WAIT_TIME = 20.f; // seconds  	static const U32 MAX_EXTRA_BUFFER_SIZE = 4 ; -	if(mNumFaces + MAX_EXTRA_BUFFER_SIZE > mFaceList.size()) +	if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)  	{ -		return ; +		return;  	} -	if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME) +	for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)  	{ -		return ; +		if(mNumFaces[i] + MAX_EXTRA_BUFFER_SIZE > mFaceList[i].size()) +		{ +			return ; +		} +			 +		mFaceList[i].erase(mFaceList[i].begin() + mNumFaces[i], mFaceList[i].end());  	} - +	  	mLastFaceListUpdateTimer.reset() ; -	mFaceList.erase(mFaceList.begin() + mNumFaces, mFaceList.end());  }  void LLViewerTexture::reorganizeVolumeList() @@ -1177,7 +1207,7 @@ void LLViewerFetchedTexture::destroyTexture()  	{  		return ;  	} - +	  	//LL_DEBUGS("Avatar") << mID << llendl;  	destroyGLTexture() ;  	mFullyLoaded = FALSE ; @@ -1194,9 +1224,14 @@ void LLViewerFetchedTexture::addToCreateTexture()  		mGLTexturep->setComponents(mComponents) ;  		force_update = true ; -		for(U32 i = 0 ; i < mNumFaces ; i++) +		for (U32 j = 0; j < LLRender::NUM_TEXTURE_CHANNELS; ++j)  		{ -			mFaceList[i]->dirtyTexture() ; +			llassert(mNumFaces[j] <= mFaceList[j].size()); + +			for(U32 i = 0 ; i < mNumFaces[j]; i++) +			{ +				mFaceList[j][i]->dirtyTexture() ; +			}  		}  		//discard the cached raw image and the saved raw image @@ -1340,11 +1375,8 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)  		return FALSE;  	} -	if(!(res = insertToAtlas())) -	{ -		res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel); -		resetFaceAtlas() ; -	} +	res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel); +	  	setActive() ;  	if (!needsToSaveRawImage()) @@ -1633,28 +1665,32 @@ void LLViewerFetchedTexture::updateVirtualSize()  		addTextureStats(0.f, FALSE) ;//reset  	} -	for(U32 i = 0 ; i < mNumFaces ; i++) -	{				 -		LLFace* facep = mFaceList[i] ; -		if( facep ) -		{ -			LLDrawable* drawable = facep->getDrawable(); -			if (drawable) +	for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) +	{ +		llassert(mNumFaces[ch] <= mFaceList[ch].size()); + +		for(U32 i = 0 ; i < mNumFaces[ch]; i++) +		{				 +			LLFace* facep = mFaceList[ch][i] ; +			if( facep )  			{ -				if(drawable->isRecentlyVisible()) +				LLDrawable* drawable = facep->getDrawable(); +				if (drawable)  				{ -					if (getBoostLevel() == LLViewerTexture::BOOST_NONE &&  -						drawable->getVObj() && drawable->getVObj()->isSelected()) +					if(drawable->isRecentlyVisible())  					{ -						setBoostLevel(LLViewerTexture::BOOST_SELECTED); +						if (getBoostLevel() == LLViewerTexture::BOOST_NONE &&  +							drawable->getVObj() && drawable->getVObj()->isSelected()) +						{ +							setBoostLevel(LLViewerTexture::BOOST_SELECTED); +						} +						addTextureStats(facep->getVirtualSize()) ; +						setAdditionalDecodePriority(facep->getImportanceToCamera()) ;  					} -					addTextureStats(facep->getVirtualSize()) ; -					setAdditionalDecodePriority(facep->getImportanceToCamera()) ;  				}  			}  		}  	} -  	//reset whether or not a face was selected after 10 seconds  	const F32 SELECTION_RESET_TIME = 10.f; @@ -2739,190 +2775,6 @@ F32 LLViewerFetchedTexture::getElapsedLastReferencedSavedRawImageTime() const  {   	return sCurrentTime - mLastReferencedSavedRawImageTime ;  } -//---------------------------------------------------------------------------------------------- -//atlasing -//---------------------------------------------------------------------------------------------- -void LLViewerFetchedTexture::resetFaceAtlas() -{ -	//Nothing should be done here. -} - -//invalidate all atlas slots for this image. -void LLViewerFetchedTexture::invalidateAtlas(BOOL rebuild_geom) -{ -	for(U32 i = 0 ; i < mNumFaces ; i++) -	{ -		LLFace* facep = mFaceList[i] ; -		facep->removeAtlas() ; -		if(rebuild_geom && facep->getDrawable() && facep->getDrawable()->getSpatialGroup()) -		{ -			facep->getDrawable()->getSpatialGroup()->setState(LLSpatialGroup::GEOM_DIRTY); -		} -	} -} - -BOOL LLViewerFetchedTexture::insertToAtlas() -{ -	if(!LLViewerTexture::sUseTextureAtlas) -	{ -		return FALSE ; -	} -	if(getNumFaces() < 1) -	{ -		return FALSE ; -	}						 -	if(mGLTexturep->getDiscardLevelInAtlas() > 0 && mRawDiscardLevel >= mGLTexturep->getDiscardLevelInAtlas()) -	{ -		return FALSE ; -	} -	if(!LLTextureAtlasManager::getInstance()->canAddToAtlas(mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents(), mGLTexturep->getTexTarget())) -	{ -		return FALSE ; -	} - -	BOOL ret = TRUE ;//if ret is set to false, will generate a gl texture for this image. -	S32 raw_w = mRawImage->getWidth() ; -	S32 raw_h = mRawImage->getHeight() ; -	F32 xscale = 1.0f, yscale = 1.0f ; -	LLPointer<LLTextureAtlasSlot> slot_infop; -	LLTextureAtlasSlot* cur_slotp ;//no need to be smart pointer. -	LLSpatialGroup* groupp ; -	LLFace* facep; - -	//if the atlas slot pointers for some faces are null, process them later. -	ll_face_list_t waiting_list ; -	for(U32 i = 0 ; i < mNumFaces ; i++) -	{ -		{ -			facep = mFaceList[i] ;			 -			 -			//face can not use atlas. -			if(!facep->canUseAtlas()) -			{ -				if(facep->getAtlasInfo()) -				{ -					facep->removeAtlas() ;	 -				} -				ret = FALSE ; -				continue ; -			} - -			//the atlas slot is updated -			slot_infop = facep->getAtlasInfo() ; -			groupp = facep->getDrawable()->getSpatialGroup() ;	 - -			if(slot_infop)  -			{ -				if(slot_infop->getSpatialGroup() != groupp) -				{ -					if((cur_slotp = groupp->getCurUpdatingSlot(this))) //switch slot -					{ -						facep->setAtlasInfo(cur_slotp) ; -						facep->setAtlasInUse(TRUE) ; -						continue ; -					} -					else //do not forget to update slot_infop->getSpatialGroup(). -					{ -						LLSpatialGroup* gp = slot_infop->getSpatialGroup() ; -						gp->setCurUpdatingTime(gFrameCount) ; -						gp->setCurUpdatingTexture(this) ; -						gp->setCurUpdatingSlot(slot_infop) ; -					} -				} -				else //same group -				{ -					if(gFrameCount && slot_infop->getUpdatedTime() == gFrameCount)//slot is just updated -					{ -						facep->setAtlasInUse(TRUE) ; -						continue ; -					} -				} -			}				 -			else -			{ -				//if the slot is null, wait to process them later. -				waiting_list.push_back(facep) ; -				continue ; -			} -						 -			//---------- -			//insert to atlas -			if(!slot_infop->getAtlas()->insertSubTexture(mGLTexturep, mRawDiscardLevel, mRawImage, slot_infop->getSlotCol(), slot_infop->getSlotRow()))			 -			{ -				 -				//the texture does not qualify to add to atlas, do not bother to try for other faces. -				//invalidateAtlas(); -				return FALSE ; -			} -			 -			//update texture scale		 -			slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ; -			slot_infop->setTexCoordScale(xscale, yscale) ; -			slot_infop->setValid() ; -			slot_infop->setUpdatedTime(gFrameCount) ; -			 -			//update spatial group atlas info -			groupp->setCurUpdatingTime(gFrameCount) ; -			groupp->setCurUpdatingTexture(this) ; -			groupp->setCurUpdatingSlot(slot_infop) ; - -			//make the face to switch to the atlas. -			facep->setAtlasInUse(TRUE) ; -		} -	} - -	//process the waiting_list -	for(std::vector<LLFace*>::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter) -	{ -		facep = (LLFace*)*iter ;	 -		groupp = facep->getDrawable()->getSpatialGroup() ; - -		//check if this texture already inserted to atlas for this group -		if((cur_slotp = groupp->getCurUpdatingSlot(this))) -		{ -			facep->setAtlasInfo(cur_slotp) ; -			facep->setAtlasInUse(TRUE) ;		 -			continue ; -		} - -		//need to reserve a slot from atlas -		slot_infop = LLTextureAtlasManager::getInstance()->reserveAtlasSlot(llmax(mFullWidth, mFullHeight), getComponents(), groupp, this) ;	 - -		facep->setAtlasInfo(slot_infop) ; -		 -		groupp->setCurUpdatingTime(gFrameCount) ; -		groupp->setCurUpdatingTexture(this) ; -		groupp->setCurUpdatingSlot(slot_infop) ; - -		//slot allocation failed. -		if(!slot_infop || !slot_infop->getAtlas()) -		{			 -			ret = FALSE ; -			facep->setAtlasInUse(FALSE) ; -			continue ; -		} -				 -		//insert to atlas -		if(!slot_infop->getAtlas()->insertSubTexture(mGLTexturep, mRawDiscardLevel, mRawImage, slot_infop->getSlotCol(), slot_infop->getSlotRow())) -		{ -			//the texture does not qualify to add to atlas, do not bother to try for other faces. -			ret = FALSE ; -			//invalidateAtlas(); -			break ;  -		} -		 -		//update texture scale		 -		slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ; -		slot_infop->setTexCoordScale(xscale, yscale) ; -		slot_infop->setValid() ; -		slot_infop->setUpdatedTime(gFrameCount) ; - -		//make the face to switch to the atlas. -		facep->setAtlasInUse(TRUE) ; -	} -	 -	return ret ; -}  //----------------------------------------------------------------------------------------------  //end of LLViewerFetchedTexture @@ -3269,11 +3121,14 @@ BOOL LLViewerMediaTexture::findFaces()  	LLViewerTexture* tex = gTextureList.findImage(mID) ;  	if(tex) //this media is a parcel media for tex.  	{ -		const ll_face_list_t* face_list = tex->getFaceList() ; -		U32 end = tex->getNumFaces() ; -		for(U32 i = 0 ; i < end ; i++) +		for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)  		{ -			mMediaFaceList.push_back((*face_list)[i]) ; +			const ll_face_list_t* face_list = tex->getFaceList(ch) ; +			U32 end = tex->getNumFaces(ch) ; +			for(U32 i = 0 ; i < end ; i++) +			{ +				mMediaFaceList.push_back((*face_list)[i]) ; +			}  		}  	} @@ -3338,7 +3193,7 @@ void LLViewerMediaTexture::addMediaToFace(LLFace* facep)  		return ; //no need to add the face because the media is not in playing.  	} -	switchTexture(facep) ; +	switchTexture(LLRender::DIFFUSE_MAP, facep) ;  }  void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)  @@ -3355,19 +3210,19 @@ void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)  	}	  	mIsPlaying = FALSE ; //set to remove the media from the face. -	switchTexture(facep) ; +	switchTexture(LLRender::DIFFUSE_MAP, facep) ;  	mIsPlaying = TRUE ; //set the flag back. -	if(getNumFaces() < 1) //no face referencing to this media +	if(getTotalNumFaces() < 1) //no face referencing to this media  	{  		stopPlaying() ;  	}  }  //virtual  -void LLViewerMediaTexture::addFace(LLFace* facep)  +void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep)   { -	LLViewerTexture::addFace(facep) ; +	LLViewerTexture::addFace(ch, facep) ;  	const LLTextureEntry* te = facep->getTextureEntry() ;  	if(te && te->getID().notNull()) @@ -3394,9 +3249,9 @@ void LLViewerMediaTexture::addFace(LLFace* facep)  }  //virtual  -void LLViewerMediaTexture::removeFace(LLFace* facep)  +void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep)   { -	LLViewerTexture::removeFace(facep) ; +	LLViewerTexture::removeFace(ch, facep) ;  	const LLTextureEntry* te = facep->getTextureEntry() ;  	if(te && te->getID().notNull()) @@ -3414,24 +3269,35 @@ void LLViewerMediaTexture::removeFace(LLFace* facep)  				}  			} -			// -			//we have some trouble here: the texture of the face is changed. -			//we need to find the former texture, and remove it from the list to avoid memory leaking. -			if(!mNumFaces) +			std::vector<const LLTextureEntry*> te_list; +			 +			for (U32 ch = 0; ch < 3; ++ch)  			{ -				mTextureList.clear() ; -				return ; +				// +				//we have some trouble here: the texture of the face is changed. +				//we need to find the former texture, and remove it from the list to avoid memory leaking. +				 +				llassert(mNumFaces[ch] <= mFaceList[ch].size()); + +				for(U32 j = 0 ; j < mNumFaces[ch] ; j++) +				{ +					te_list.push_back(mFaceList[ch][j]->getTextureEntry());//all textures are in use. +				}  			} -			S32 end = getNumFaces() ; -			std::vector<const LLTextureEntry*> te_list(end) ; -			S32 i = 0 ;			 -			for(U32 j = 0 ; j < mNumFaces ; j++) + +			if (te_list.empty())  			{ -				te_list[i++] = mFaceList[j]->getTextureEntry() ;//all textures are in use. +				mTextureList.clear() ; +				return ;  			} + +			S32 end = te_list.size(); +  			for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();  				iter != mTextureList.end(); ++iter)  			{ +				S32 i = 0; +  				for(i = 0 ; i < end ; i++)  				{  					if(te_list[i] && te_list[i]->getID() == (*iter)->getID())//the texture is in use. @@ -3476,7 +3342,7 @@ void LLViewerMediaTexture::stopPlaying()  	mIsPlaying = FALSE ;			  } -void LLViewerMediaTexture::switchTexture(LLFace* facep) +void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep)  {  	if(facep)  	{ @@ -3492,7 +3358,7 @@ void LLViewerMediaTexture::switchTexture(LLFace* facep)  		if(mIsPlaying) //old textures switch to the media texture  		{ -			facep->switchTexture(this) ; +			facep->switchTexture(ch, this) ;  		}  		else //switch to old textures.  		{ @@ -3508,7 +3374,7 @@ void LLViewerMediaTexture::switchTexture(LLFace* facep)  				{  					tex = LLViewerFetchedTexture::sDefaultImagep ;  				} -				facep->switchTexture(tex) ; +				facep->switchTexture(ch, tex) ;  			}  		}  	} @@ -3547,14 +3413,17 @@ void LLViewerMediaTexture::setPlaying(BOOL playing)  		for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)  		{ -			switchTexture(*iter) ; +			switchTexture(LLRender::DIFFUSE_MAP, *iter) ;  		}  	}  	else //stop playing this media  	{ -		for(U32 i = mNumFaces ; i ; i--) +		U32 ch = LLRender::DIFFUSE_MAP; +		 +		llassert(mNumFaces[ch] <= mFaceList[ch].size()); +		for(U32 i = mNumFaces[ch] ; i ; i--)  		{ -			switchTexture(mFaceList[i - 1]) ; //current face could be removed in this function. +			switchTexture(ch, mFaceList[ch][i - 1]) ; //current face could be removed in this function.  		}  	}  	return ; @@ -3576,14 +3445,18 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()  	if(mIsPlaying) //media is playing  	{ -		for(U32 i = 0 ; i < mNumFaces ; i++) +		for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)  		{ -			LLFace* facep = mFaceList[i] ; -			if(facep->getDrawable()->isRecentlyVisible()) +			llassert(mNumFaces[ch] <= mFaceList[ch].size()); +			for(U32 i = 0 ; i < mNumFaces[ch] ; i++)  			{ -				addTextureStats(facep->getVirtualSize()) ; -			} -		}		 +				LLFace* facep = mFaceList[ch][i] ; +				if(facep->getDrawable()->isRecentlyVisible()) +				{ +					addTextureStats(facep->getVirtualSize()) ; +				} +			}		 +		}  	}  	else //media is not in playing  	{ diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index f2e1a90713..c96f89017f 100755 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -34,6 +34,7 @@  #include "llgltypes.h"  #include "llrender.h"  #include "llmetricperformancetester.h" +#include "llface.h"  #include <map>  #include <list> @@ -41,7 +42,6 @@  #define MIN_VIDEO_RAM_IN_MEGA_BYTES    32  #define MAX_VIDEO_RAM_IN_MEGA_BYTES    512 // 512MB max for performance reasons. -class LLFace;  class LLImageGL ;  class LLImageRaw;  class LLViewerObject; @@ -98,7 +98,6 @@ public:  		DYNAMIC_TEXTURE,  		FETCHED_TEXTURE,  		LOD_TEXTURE, -		ATLAS_TEXTURE,  		INVALID_TEXTURE_TYPE  	}; @@ -140,12 +139,15 @@ public:  	LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;} +	S32 getFullWidth() const { return mFullWidth; } +	S32 getFullHeight() const { return mFullHeight; }	  	/*virtual*/ void setKnownDrawSize(S32 width, S32 height); -	virtual void addFace(LLFace* facep) ; -	virtual void removeFace(LLFace* facep) ;  -	S32 getNumFaces() const; -	const ll_face_list_t* getFaceList() const {return &mFaceList;} +	virtual void addFace(U32 channel, LLFace* facep) ; +	virtual void removeFace(U32 channel, LLFace* facep) ;  +	S32 getTotalNumFaces() const; +	S32 getNumFaces(U32 ch) const; +	const ll_face_list_t* getFaceList(U32 channel) const {llassert(channel < LLRender::NUM_TEXTURE_CHANNELS); return &mFaceList[channel];}  	virtual void addVolume(LLVOVolume* volumep);  	virtual void removeVolume(LLVOVolume* volumep); @@ -182,8 +184,8 @@ protected:  	mutable F32 mAdditionalDecodePriority;  // priority add to mDecodePriority.  	LLFrameTimer mLastReferencedTimer;	 -	ll_face_list_t    mFaceList ; //reverse pointer pointing to the faces using this image as texture -	U32               mNumFaces ; +	ll_face_list_t    mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture +	U32               mNumFaces[LLRender::NUM_TEXTURE_CHANNELS];  	LLFrameTimer      mLastFaceListUpdateTimer ;  	ll_volume_list_t  mVolumeList; @@ -214,8 +216,7 @@ public:  	static S32 sMaxSmallImageSize ;  	static BOOL sFreezeImageScalingDown ;//do not scale down image res if set.  	static F32  sCurrentTime ; -	static BOOL sUseTextureAtlas ; - +	  	enum EDebugTexels  	{  		DEBUG_TEXELS_OFF, @@ -400,17 +401,12 @@ protected:  	S32 getCurrentDiscardLevelForFetching() ;  private: -	void init(bool firstinit) ;	 +	void init(bool firstinit) ;  	void cleanup() ;  	void saveRawImage() ;  	void setCachedRawImage() ; -	//for atlas -	void resetFaceAtlas() ; -	void invalidateAtlas(BOOL rebuild_geom) ; -	BOOL insertToAtlas() ; -  private:  	BOOL  mFullyLoaded;  	BOOL  mInDebug; @@ -447,7 +443,7 @@ protected:  	S8  mHasFetcher;				// We've made a fecth request  	S8  mIsFetching;				// Fetch request is active  	bool mCanUseHTTP ;              //This texture can be fetched through http if true. - +	  	FTType mFTType; // What category of image is this - map tile, server bake, etc?  	mutable S8 mIsMissingAsset;		// True if we know that there is no image asset with this image id in the database.		 @@ -496,6 +492,7 @@ public:  	static LLPointer<LLViewerFetchedTexture> sWhiteImagep;	// Texture to show NOTHING (whiteness)  	static LLPointer<LLViewerFetchedTexture> sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local.  	static LLPointer<LLViewerFetchedTexture> sSmokeImagep; // Old "Default" translucent texture +	static LLPointer<LLViewerFetchedTexture> sFlatNormalImagep; // Flat normal map denoting no bumpiness on a surface  };  // @@ -553,12 +550,12 @@ public:  	void addMediaToFace(LLFace* facep) ;  	void removeMediaFromFace(LLFace* facep) ; -	/*virtual*/ void addFace(LLFace* facep) ; -	/*virtual*/ void removeFace(LLFace* facep) ;  +	/*virtual*/ void addFace(U32 ch, LLFace* facep) ; +	/*virtual*/ void removeFace(U32 ch, LLFace* facep) ;   	/*virtual*/ F32  getMaxVirtualSize() ;  private: -	void switchTexture(LLFace* facep) ; +	void switchTexture(U32 ch, LLFace* facep) ;  	BOOL findFaces() ;  	void stopPlaying() ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index d2af48f528..d9f3548a29 100755 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -119,6 +119,9 @@ void LLViewerTextureList::doPreloadImages()  	LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();  	LLUIImageList* image_list = LLUIImageList::getInstance(); +	// Set the default flat normal map +	LLViewerFetchedTexture::sFlatNormalImagep = LLViewerTextureManager::getFetchedTextureFromFile("flatnormal.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_BUMP); +	  	image_list->initFromFile();  	// turn off clamping and bilinear filtering for uv picking images @@ -324,7 +327,7 @@ void LLViewerTextureList::restoreGL()  /////////////////////////////////////////////////////////////////////////////// -LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename, +LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,												     												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority, @@ -376,7 +379,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&  	}  	LLPointer<LLViewerFetchedTexture> imagep = findImage(new_id); - +	  	if (!imagep.isNull())  	{  		LLViewerFetchedTexture *texture = imagep.get(); @@ -432,7 +435,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&  } -LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, +LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,											         												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority, @@ -475,7 +478,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,  		{  			llwarns << "FTType mismatch: requested " << f_type << " image has " << imagep->getFTType() << llendl;  		} -		 +	  	}  	if (imagep.isNull())  	{ @@ -488,7 +491,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,  }  //when this function is called, there is no such texture in the gTextureList with image_id. -LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, +LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,											         												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority, diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index fe4d5b3e4d..65a906d3c0 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -229,13 +229,13 @@ LLFrameTimer	gAwayTriggerTimer;  BOOL			gShowOverlayTitle = FALSE;  LLViewerObject*  gDebugRaycastObject = NULL; -LLVector3       gDebugRaycastIntersection; -LLVector2       gDebugRaycastTexCoord; -LLVector3       gDebugRaycastNormal; -LLVector3       gDebugRaycastBinormal; -S32				gDebugRaycastFaceHit; -LLVector3		gDebugRaycastStart; -LLVector3		gDebugRaycastEnd; +LLVector4a       gDebugRaycastIntersection; +LLVector2        gDebugRaycastTexCoord; +LLVector4a       gDebugRaycastNormal; +LLVector4a       gDebugRaycastTangent; +S32				 gDebugRaycastFaceHit; +LLVector4a		 gDebugRaycastStart; +LLVector4a		 gDebugRaycastEnd;  // HUD display lines in lower right  BOOL				gDisplayWindInfo = FALSE; @@ -2841,7 +2841,7 @@ void LLViewerWindow::updateUI()  											  &gDebugRaycastIntersection,  											  &gDebugRaycastTexCoord,  											  &gDebugRaycastNormal, -											  &gDebugRaycastBinormal, +											  &gDebugRaycastTangent,  											  &gDebugRaycastStart,  											  &gDebugRaycastEnd);  	} @@ -3739,7 +3739,7 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot,  BOOL pick_trans  }  LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth, -										   LLVector3* intersection) +										   LLVector4a* intersection)  {  	S32 x = mouse_x;  	S32 y = mouse_y; @@ -3751,14 +3751,17 @@ LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 dep  	}  	// world coordinates of mouse +	// VECTORIZE THIS  	LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);  	LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin();  	LLVector3 mouse_world_start = mouse_point_global;  	LLVector3 mouse_world_end   = mouse_point_global + mouse_direction_global * depth; -	return LLHUDIcon::lineSegmentIntersectAll(mouse_world_start, mouse_world_end, intersection); - +	LLVector4a start, end; +	start.load3(mouse_world_start.mV); +	end.load3(mouse_world_end.mV); +	return LLHUDIcon::lineSegmentIntersectAll(start, end, intersection);  }  LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 depth, @@ -3766,12 +3769,12 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  												S32 this_face,  												BOOL pick_transparent,  												S32* face_hit, -												LLVector3 *intersection, +												LLVector4a *intersection,  												LLVector2 *uv, -												LLVector3 *normal, -												LLVector3 *binormal, -												LLVector3* start, -												LLVector3* end) +												LLVector4a *normal, +												LLVector4a *tangent, +												LLVector4a* start, +												LLVector4a* end)  {  	S32 x = mouse_x;  	S32 y = mouse_y; @@ -3806,17 +3809,27 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  	if (!LLViewerJoystick::getInstance()->getOverrideCamera())  	{ //always set raycast intersection to mouse_world_end unless  		//flycam is on (for DoF effect) -		gDebugRaycastIntersection = mouse_world_end; +		gDebugRaycastIntersection.load3(mouse_world_end.mV);  	} +	LLVector4a mw_start; +	mw_start.load3(mouse_world_start.mV); +	LLVector4a mw_end; +	mw_end.load3(mouse_world_end.mV); + +	LLVector4a mh_start; +	mh_start.load3(mouse_hud_start.mV); +	LLVector4a mh_end; +	mh_end.load3(mouse_hud_end.mV); +  	if (start)  	{ -		*start = mouse_world_start; +		*start = mw_start;  	}  	if (end)  	{ -		*end = mouse_world_end; +		*end = mw_end;  	}  	LLViewerObject* found = NULL; @@ -3825,16 +3838,16 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  	{  		if (this_object->isHUDAttachment()) // is a HUD object?  		{ -			if (this_object->lineSegmentIntersect(mouse_hud_start, mouse_hud_end, this_face, pick_transparent, -												  face_hit, intersection, uv, normal, binormal)) +			if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, +												  face_hit, intersection, uv, normal, tangent))  			{  				found = this_object;  			}  		}  		else // is a world object  		{ -			if (this_object->lineSegmentIntersect(mouse_world_start, mouse_world_end, this_face, pick_transparent, -												  face_hit, intersection, uv, normal, binormal)) +			if (this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent, +												  face_hit, intersection, uv, normal, tangent))  			{  				found = this_object;  			} @@ -3842,20 +3855,20 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  	}  	else // check ALL objects  	{ -		found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, pick_transparent, -													face_hit, intersection, uv, normal, binormal); +		found = gPipeline.lineSegmentIntersectInHUD(mh_start, mh_end, pick_transparent, +													face_hit, intersection, uv, normal, tangent);  		if (!found) // if not found in HUD, look in world:  		{ -			found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, pick_transparent, -														  face_hit, intersection, uv, normal, binormal); +			found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, +														  face_hit, intersection, uv, normal, tangent);  			if (found && !pick_transparent)  			{  				gDebugRaycastIntersection = *intersection;  			}  		}  	} - +		  	return found;  } @@ -5112,6 +5125,7 @@ LLPickInfo::LLPickInfo()  	  mXYCoords(-1, -1),  	  mIntersection(),  	  mNormal(), +	  mTangent(),  	  mBinormal(),  	  mHUDIcon(NULL),  	  mPickTransparent(FALSE) @@ -5133,6 +5147,7 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,  	  mSTCoords(-1.f, -1.f),  	  mXYCoords(-1, -1),  	  mNormal(), +	  mTangent(),  	  mBinormal(),  	  mHUDIcon(NULL),  	  mPickTransparent(pick_transparent) @@ -5143,19 +5158,26 @@ void LLPickInfo::fetchResults()  {  	S32 face_hit = -1; -	LLVector3 intersection, normal, binormal; +	LLVector4a intersection, normal; +	LLVector4a tangent; +  	LLVector2 uv;  	LLHUDIcon* hit_icon = gViewerWindow->cursorIntersectIcon(mMousePt.mX, mMousePt.mY, 512.f, &intersection); +	LLVector4a origin; +	origin.load3(LLViewerCamera::getInstance()->getOrigin().mV);  	F32 icon_dist = 0.f;  	if (hit_icon)  	{ -		icon_dist = (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec(); +		LLVector4a delta; +		delta.setSub(intersection, origin); +		icon_dist = delta.getLength3().getF32();  	} +  	LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f,  									NULL, -1, mPickTransparent, &face_hit, -									&intersection, &uv, &normal, &binormal); +									&intersection, &uv, &normal, &tangent);  	mPickPt = mMousePt; @@ -5165,9 +5187,13 @@ void LLPickInfo::fetchResults()  	LLViewerObject* objectp = hit_object; + +	LLVector4a delta; +	delta.setSub(origin, intersection); +  	if (hit_icon &&   		(!objectp ||  -		icon_dist < (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec())) +		icon_dist < delta.getLength3().getF32()))  	{  		// was this name referring to a hud icon?  		mHUDIcon = hit_icon; @@ -5204,11 +5230,16 @@ void LLPickInfo::fetchResults()  			{  				mPickType = PICK_OBJECT;  			} -			mObjectOffset = gAgentCamera.calcFocusOffset(objectp, intersection, mPickPt.mX, mPickPt.mY); + +			LLVector3 v_intersection(intersection.getF32ptr()); + +			mObjectOffset = gAgentCamera.calcFocusOffset(objectp, v_intersection, mPickPt.mX, mPickPt.mY);  			mObjectID = objectp->mID;  			mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset; -			mPosGlobal = gAgent.getPosGlobalFromAgent(intersection); +			 + +			mPosGlobal = gAgent.getPosGlobalFromAgent(v_intersection);  			if (mWantSurfaceInfo)  			{ @@ -5252,7 +5283,16 @@ void LLPickInfo::getSurfaceInfo()  	mIntersection = LLVector3(0,0,0);  	mNormal       = LLVector3(0,0,0);  	mBinormal     = LLVector3(0,0,0); +	mTangent	  = LLVector4(0,0,0,0); +	LLVector4a tangent; +	LLVector4a intersection; +	LLVector4a normal; + +	tangent.clear(); +	normal.clear(); +	intersection.clear(); +  	LLViewerObject* objectp = getObject();  	if (objectp) @@ -5260,10 +5300,10 @@ void LLPickInfo::getSurfaceInfo()  		if (gViewerWindow->cursorIntersect(llround((F32)mMousePt.mX), llround((F32)mMousePt.mY), 1024.f,  										   objectp, -1, mPickTransparent,  										   &mObjectFace, -										   &mIntersection, +										   &intersection,  										   &mSTCoords, -										   &mNormal, -										   &mBinormal)) +										   &normal, +										   &tangent))  		{  			// if we succeeded with the intersect above, compute the texture coordinates: @@ -5272,10 +5312,26 @@ void LLPickInfo::getSurfaceInfo()  				LLFace* facep = objectp->mDrawable->getFace(mObjectFace);  				if (facep)  				{ -				mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal); -			} +					mUVCoords = facep->surfaceToTexture(mSTCoords, intersection, normal); +				}  			} +			mIntersection.set(intersection.getF32ptr()); +			mNormal.set(normal.getF32ptr()); +			mTangent.set(tangent.getF32ptr()); + +			//extrapoloate binormal from normal and tangent +			 +			LLVector4a binormal; +			binormal.setCross3(normal, tangent); +			binormal.mul(tangent.getF32ptr()[3]); + +			mBinormal.set(binormal.getF32ptr()); + +			mBinormal.normalize(); +			mNormal.normalize(); +			mTangent.normalize(); +  			// and XY coords:  			updateXYCoords(); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index b33488fd78..89f6e3bc26 100755 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -115,6 +115,7 @@ public:  	LLVector2       mSTCoords;  	LLCoordScreen	mXYCoords;  	LLVector3		mNormal; +	LLVector4		mTangent;  	LLVector3		mBinormal;  	BOOL			mPickTransparent;  	void		    getSurfaceInfo(); @@ -357,19 +358,19 @@ public:  	void			pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(const LLPickInfo& pick_info), BOOL pick_transparent = FALSE);  	LLPickInfo		pickImmediate(S32 x, S32 y, BOOL pick_transparent);  	LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth, -										   LLVector3* intersection); +										   LLVector4a* intersection);  	LLViewerObject* cursorIntersect(S32 mouse_x = -1, S32 mouse_y = -1, F32 depth = 512.f,  									LLViewerObject *this_object = NULL,  									S32 this_face = -1,  									BOOL pick_transparent = FALSE,  									S32* face_hit = NULL, -									LLVector3 *intersection = NULL, +									LLVector4a *intersection = NULL,  									LLVector2 *uv = NULL, -									LLVector3 *normal = NULL, -									LLVector3 *binormal = NULL, -									LLVector3* start = NULL, -									LLVector3* end = NULL); +									LLVector4a *normal = NULL, +									LLVector4a *tangent = NULL, +									LLVector4a* start = NULL, +									LLVector4a* end = NULL);  	// Returns a pointer to the last object hit @@ -499,13 +500,13 @@ extern LLFrameTimer		gAwayTimer;				// tracks time before setting the avatar awa  extern LLFrameTimer		gAwayTriggerTimer;		// how long the avatar has been away  extern LLViewerObject*  gDebugRaycastObject; -extern LLVector3        gDebugRaycastIntersection; +extern LLVector4a       gDebugRaycastIntersection;  extern LLVector2        gDebugRaycastTexCoord; -extern LLVector3        gDebugRaycastNormal; -extern LLVector3        gDebugRaycastBinormal; +extern LLVector4a       gDebugRaycastNormal; +extern LLVector4a       gDebugRaycastTangent;  extern S32				gDebugRaycastFaceHit; -extern LLVector3		gDebugRaycastStart; -extern LLVector3		gDebugRaycastEnd; +extern LLVector4a		gDebugRaycastStart; +extern LLVector4a		gDebugRaycastEnd;  extern BOOL			gDisplayCameraPos;  extern BOOL			gDisplayWindInfo; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 725670d33f..15d5dd63c7 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -803,17 +803,17 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c  //------------------------------------------------------------------------  LLVOAvatar::~LLVOAvatar()  { -	if (!mFullyLoaded) -	{ +		if (!mFullyLoaded) +		{  		debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud"); -	} -	else -	{ +		} +		else +		{  		debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding"); -	} +		}  	logPendingPhases(); -	 +  	lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;  	std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer()); @@ -1197,7 +1197,7 @@ void LLVOAvatar::initInstance(void)  		registerMotion( ANIM_AGENT_TARGET,					LLTargetingMotion::create );  		registerMotion( ANIM_AGENT_WALK_ADJUST,				LLWalkAdjustMotion::create );  	} - +	  	LLAvatarAppearance::initInstance();  	// preload specific motions here @@ -1389,19 +1389,20 @@ void LLVOAvatar::renderCollisionVolumes()  	if (mNameText.notNull())  	{ -		LLVector3 unused; -		mNameText->lineSegmentIntersect(LLVector3(0,0,0), LLVector3(0,0,1), unused, TRUE); +		LLVector4a unused; +	 +		mNameText->lineSegmentIntersect(unused, unused, unused, TRUE);  	}  } -BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  									  S32 face,  									  BOOL pick_transparent,  									  S32* face_hit, -									  LLVector3* intersection, +									  LLVector4a* intersection,  									  LLVector2* tex_coord, -									  LLVector3* normal, -									  LLVector3* bi_normal) +									  LLVector4a* normal, +									  LLVector4a* tangent)  {  	if ((isSelf() && !gAgent.needsRenderAvatar()) || !LLPipeline::sPickAvatar)  	{ @@ -1418,8 +1419,8 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  			glh::matrix4f inverse = mat.inverse();  			glh::matrix4f norm_mat = inverse.transpose(); -			glh::vec3f p1(start.mV); -			glh::vec3f p2(end.mV); +			glh::vec3f p1(start.getF32ptr()); +			glh::vec3f p2(end.getF32ptr());  			inverse.mult_matrix_vec(p1);  			inverse.mult_matrix_vec(p2); @@ -1438,12 +1439,12 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  				if (intersection)  				{ -					*intersection = LLVector3(res_pos.v); +					intersection->load3(res_pos.v);  				}  				if (normal)  				{ -					*normal = LLVector3(res_norm.v); +					normal->load3(res_norm.v);  				}  				return TRUE; @@ -1479,7 +1480,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e -	LLVector3 position; +	LLVector4a position;  	if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position))  	{  		if (intersection) @@ -1493,14 +1494,14 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	return FALSE;  } -LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, +LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,  									  S32 face,  									  BOOL pick_transparent,  									  S32* face_hit, -									  LLVector3* intersection, +									  LLVector4a* intersection,  									  LLVector2* tex_coord, -									  LLVector3* normal, -									  LLVector3* bi_normal) +									  LLVector4a* normal, +									  LLVector4a* tangent)  {  	if (isSelf() && !gAgent.needsRenderAvatar())  	{ @@ -1511,8 +1512,8 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector  	if (lineSegmentBoundingBox(start, end))  	{ -		LLVector3 local_end = end; -		LLVector3 local_intersection; +		LLVector4a local_end = end; +		LLVector4a local_intersection;  		for (attachment_map_t::iterator iter = mAttachmentPoints.begin();   			iter != mAttachmentPoints.end(); @@ -1526,7 +1527,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector  			{  				LLViewerObject* attached_object = (*attachment_iter); -				if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, bi_normal)) +				if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, tangent))  				{  					local_end = local_intersection;  					if (intersection) @@ -1543,7 +1544,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector  	return hit;  } -	 +  LLVOAvatar* LLVOAvatar::asAvatar()  {  	return this; @@ -1878,22 +1879,22 @@ LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUU  	}  	if (!result) -	{ +{  		const std::string url = getImageURL(te,uuid);  		if (!url.empty()) -		{ +	{  			LL_DEBUGS("Avatar") << avString() << "from URL " << url << llendl;  			result = LLViewerTextureManager::getFetchedTextureFromUrl(  				url, FTT_SERVER_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid); -		} -		else -		{ +	} +	else +	{  			LL_DEBUGS("Avatar") << avString() << "from host " << uuid << llendl;  			LLHost host = getObjectHost();  			result = LLViewerTextureManager::getFetchedTexture(  				uuid, FTT_HOST_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); -		}  	} +}  	return result;  } @@ -3980,7 +3981,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)  		{  			LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);  			if (hair_mesh) -			{ +		{  				num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);  			}  			first_pass = FALSE; @@ -3990,7 +3991,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)  			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  		}  	} - +	  	return num_indices;  } @@ -5107,9 +5108,9 @@ BOOL LLVOAvatar::loadSkeletonNode ()  {  	if (!LLAvatarAppearance::loadSkeletonNode())  	{ -		return FALSE; -	} - +				return FALSE; +			} +	  	// ATTACHMENTS  	{  		LLAvatarXmlInfo::attachment_info_list_t::iterator iter; @@ -5826,24 +5827,26 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const  	{  		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second;  		if (texture_dict->mWearableType == type) -		{ +	{  			// Thus, you must check to see if the corresponding baked texture is defined.  			// NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing  			// this works for detecting a skirt (most important), but is ineffective at any piece of clothing that  			// gets baked into a texture that always exists (upper or lower).  			if (texture_dict->mIsUsedByBakedTexture) -			{ +	{  				const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;  				return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex); -			} +	}  			return FALSE; -		} +	}  	}  	return FALSE;  } + +  // virtual  void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result )  { @@ -5878,7 +5881,7 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL  			{  				LLAvatarJointMesh* mesh = (*iter);  				if (mesh) -				{ +			{  					mesh->setColor( color );  				}  			} @@ -5946,9 +5949,9 @@ void LLVOAvatar::updateRezzedStatusTimers()  		{  			// load level has decreased. start phase timers for higher load levels.  			for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++) -			{ +		{  				startPhase("load_" + LLVOAvatar::rezStatusToString(i)); -			} +		}  		}  		else if (rez_status > mLastRezzedStatus)  		{ @@ -5957,16 +5960,16 @@ void LLVOAvatar::updateRezzedStatusTimers()  			{  				stopPhase("load_" + LLVOAvatar::rezStatusToString(i));  				stopPhase("first_load_" + LLVOAvatar::rezStatusToString(i), false); -			} +		}  			if (rez_status == 3) -			{ +		{  				// "fully loaded", mark any pending appearance change complete.  				selfStopPhase("update_appearance_from_cof");  				selfStopPhase("wear_inventory_category", false);  				selfStopPhase("process_initial_wearables_update", false);  			}  		} - +		  		mLastRezzedStatus = rez_status;  	}  } @@ -5993,7 +5996,7 @@ void LLVOAvatar::startPhase(const std::string& phase_name)  }  void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check) -{ +		{  	F32 elapsed;  	bool completed;  	if (getPhases().getPhaseValues(phase_name, elapsed, completed)) @@ -6025,7 +6028,7 @@ void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)  void LLVOAvatar::logPendingPhases()  {  	if (!isAgentAvatarValid()) -	{ +		{  		return;  	} @@ -6041,14 +6044,14 @@ void LLVOAvatar::logPendingPhases()  			if (!completed)  			{  				logMetricsTimerRecord(phase_name, elapsed, completed); -			} +		}  		}  	} -} +		}  //static  void LLVOAvatar::logPendingPhasesAllAvatars() -{ +		{  	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();  		 iter != LLCharacter::sInstances.end(); ++iter)  	{ @@ -6059,14 +6062,14 @@ void LLVOAvatar::logPendingPhasesAllAvatars()  		}  		inst->logPendingPhases();  	} -} +		}  void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed) -{ +		{  	if (!isAgentAvatarValid()) -	{ +		{  		return; -	} +		}  	LLSD record;  	record["timer_name"] = phase_name; @@ -6075,15 +6078,15 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse  	record["completed"] = completed;  	U32 grid_x(0), grid_y(0);  	if (getRegion()) -	{ +		{  		record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion());  		grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y); -	} +		}  	record["grid_x"] = LLSD::Integer(grid_x);  	record["grid_y"] = LLSD::Integer(grid_y);  	record["is_using_server_bakes"] = ((bool) isUsingServerBakes());  	record["is_self"] = isSelf(); -	 +		  	if (isAgentAvatarValid())  	{  		gAgentAvatarp->addMetricsTimerRecord(record); @@ -6291,28 +6294,28 @@ void LLVOAvatar::updateMeshTextures()  										   use_lkg_baked_layer[i],  										   last_id_string.c_str());  	} -	 +  	for (U32 i=0; i < mBakedTextureDatas.size(); i++)  	{  		debugColorizeSubMeshes(i, LLColor4::white);  		LLViewerTexLayerSet* layerset = getTexLayerSet(i);  		if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() ) -		{ +	{  			LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID);  			mBakedTextureDatas[i].mIsUsed = TRUE;  			debugColorizeSubMeshes(i,LLColor4::red); - +	  			avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();  			avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end();  			for (; iter != end; ++iter) -			{ +	{  				LLAvatarJointMesh* mesh = (*iter);  				if (mesh) -				{ +		{  					mesh->setTexture( baked_img ); -				} +			}  			}  		}  		else if (!isUsingLocalAppearance() && is_layer_baked[i]) @@ -6356,7 +6359,7 @@ void LLVOAvatar::updateMeshTextures()  				if (mesh)  				{  					mesh->setLayerSet( layerset ); -				} +			}  			}  		}  		else @@ -6378,7 +6381,7 @@ void LLVOAvatar::updateMeshTextures()  		{  			LLAvatarJointMesh* mesh = (*iter);  			if (mesh) -			{ +		{  				mesh->setColor( color );  				mesh->setTexture( hair_img );  			} @@ -6466,17 +6469,18 @@ void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_com  	for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin();  		 iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter) -	{ +{  		const LLMaskedMorph* maskedMorph = (*iter);  		LLPolyMorphTarget* morph_target = dynamic_cast<LLPolyMorphTarget*>(maskedMorph->mMorphTarget);  		if (morph_target) -		{ +	{  			morph_target->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert); -		} +}  	}  } +  // returns TRUE if morph masks are present and not valid for a given baked texture, FALSE otherwise  BOOL LLVOAvatar::morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIndex index)  { @@ -6754,12 +6758,12 @@ void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value)  					LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str()  //					param_location_name(vparam->getParamLocation()).c_str()  		); -} - +	} +	  void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,  	const LLAppearanceMessageContents& contents) -{ +	{  	std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml");  	const std::vector<F32>& params_for_dump = contents.mParamWeights;  	const LLTEContents& tec = contents.mTEContents; @@ -6769,9 +6773,9 @@ void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,  	outfile.open(fullpath, LL_APR_WB );  	apr_file_t* file = outfile.getFileHandle();  	if (!file) -	{ -		return; -	} +		{ +			return; +		}  	else  	{  		LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << llendl; @@ -6805,7 +6809,7 @@ void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,  		apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", i, uuid_str.c_str());  	}  	apr_file_printf(file, "</textures>\n"); -} +	}  void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& contents)  { @@ -6822,7 +6826,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe  		// For future use:  		//mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);  	} - +	  	// Parse visual params, if any.  	S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);  	bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing @@ -7050,19 +7054,19 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  			LLVisualParam* param = contents.mParams[i];  			F32 newWeight = contents.mParamWeights[i]; -			if (is_first_appearance_message || (param->getWeight() != newWeight)) -			{ -				params_changed = TRUE; -				if(is_first_appearance_message) +				if (is_first_appearance_message || (param->getWeight() != newWeight))  				{ -					param->setWeight(newWeight, FALSE); -				} -				else -				{ -					interp_params = TRUE; -					param->setAnimationTarget(newWeight, FALSE); +					params_changed = TRUE; +					if(is_first_appearance_message) +					{ +						param->setWeight(newWeight, FALSE); +					} +					else +					{ +						interp_params = TRUE; +						param->setAnimationTarget(newWeight, FALSE); +					}  				} -			}  		}  		const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT  		if (num_params != expected_tweakable_count) @@ -7318,12 +7322,12 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )  				avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();  				avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end();  				for (; iter != end; ++iter) -				{ +			{  					LLAvatarJointMesh* mesh = (*iter);  					if (mesh) -					{ +			{  						mesh->setTexture( image_baked ); -					} +			}  				}  			} @@ -7347,7 +7351,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )  				{  					LLAvatarJointMesh* mesh = (*iter);  					if (mesh) -					{ +				{  						mesh->setColor( LLColor4::white );  					}  				} @@ -7366,7 +7370,7 @@ std::string get_sequential_numbered_file_name(const std::string& prefix,  	file_num_type::iterator it = file_nums.find(prefix);  	S32 num = 0;  	if (it != file_nums.end()) -	{ +{  		num = it->second;  	}  	file_nums[prefix] = num+1; @@ -7383,6 +7387,10 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara  		outprefix = getFullname() + (isSelf()?"_s":"_o");  	}  	if (outprefix.empty()) +{ +		outprefix = getFullname() + (isSelf()?"_s":"_o"); +	} +	if (outprefix.empty())  	{  		outprefix = std::string("new_archetype");  	} @@ -7408,36 +7416,36 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara  	if (group_by_wearables)  	{  		for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++) -		{ -			const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type); -			apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() ); +	{ +		const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type); +		apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() );  			for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) +		{ +			LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; +			if( (viewer_param->getWearableType() == type) &&  +				(viewer_param->isTweakable() ) )  			{ -				LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; -				if( (viewer_param->getWearableType() == type) &&  -					(viewer_param->isTweakable() ) ) -				{  					dump_visual_param(file, viewer_param, viewer_param->getWeight()); -				}  			} +		} -			for (U8 te = 0; te < TEX_NUM_INDICES; te++) -			{ +		for (U8 te = 0; te < TEX_NUM_INDICES; te++) +		{  				if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type) -				{ -					// MULTIPLE_WEARABLES: extend to multiple wearables? +			{ +				// MULTIPLE_WEARABLES: extend to multiple wearables?  					LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); -					if( te_image ) -					{ -						std::string uuid_str; -						te_image->getID().toString( uuid_str ); -						apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str()); -					} +				if( te_image ) +				{ +					std::string uuid_str; +					te_image->getID().toString( uuid_str ); +					apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str());  				}  			}  		}  	} +		}  	else   	{  		// Just dump all params sequentially. @@ -7449,7 +7457,6 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara  		for (U8 te = 0; te < TEX_NUM_INDICES; te++)  		{ -			{  				// MULTIPLE_WEARABLES: extend to multiple wearables?  				LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);  				if( te_image ) @@ -7461,7 +7468,6 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara  			}  		} -	}  	apr_file_printf( file, "\t</archetype>\n" );  	apr_file_printf( file, "\n</linden_genepool>\n" ); @@ -7583,14 +7589,14 @@ void LLVOAvatar::startAppearanceAnimation()  	}  } -//virtual +// virtual  void LLVOAvatar::bodySizeChanged() -{ +{	  	if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF())  	{	// notify simulator of change in size  		// but not if we are in the middle of updating appearance  		gAgent.sendAgentSetAppearance(); -	} +}  }  BOOL LLVOAvatar::isUsingServerBakes() const @@ -7602,25 +7608,25 @@ BOOL LLVOAvatar::isUsingServerBakes() const  	F32 wt = appearance_version_param->getWeight();  	F32 expect_wt = mUseServerBakes ? 1.0 : 0.0;  	if (!is_approx_equal(wt,expect_wt)) -	{ +{  		llwarns << "wt " << wt << " differs from expected " << expect_wt << llendl;  	}  #endif  	return mUseServerBakes; -} - +		} +		  void LLVOAvatar::setIsUsingServerBakes(BOOL newval) -{ +		{  	mUseServerBakes = newval;  	LLVisualParam* appearance_version_param = getVisualParam(11000);  	llassert(appearance_version_param);  	appearance_version_param->setWeight(newval ? 1.0 : 0.0, false); -} +		}  // virtual  void LLVOAvatar::removeMissingBakedTextures() -{	 +			{  }  //virtual diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 85f6f25009..b05eed344b 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -128,15 +128,15 @@ protected:  public:  	/*virtual*/ void			updateGL();  	/*virtual*/ LLVOAvatar*		asAvatar(); -	virtual U32    	 	 		processUpdateMessage(LLMessageSystem *mesgsys, +	virtual U32    	 	 	processUpdateMessage(LLMessageSystem *mesgsys,  													 void **user_data,  													 U32 block_num,  													 const EObjectUpdateType update_type,  													 LLDataPacker *dp); -	virtual void   	 	 		idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); +	virtual void   	 	 	idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);  	/*virtual*/ BOOL   	 	 	updateLOD(); -	BOOL  	 	 	 	 		updateJointLODs(); -	void						updateLODRiggedAttachments( void ); +	BOOL  	 	 	 	 	updateJointLODs(); +	void					updateLODRiggedAttachments( void );  	/*virtual*/ BOOL   	 	 	isActive() const; // Whether this object needs to do an idleUpdate.  	S32 						totalTextureMemForUUIDS(std::set<LLUUID>& ids);  	bool 						allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const; @@ -162,22 +162,22 @@ public:  	/*virtual*/ void   	 	 	updateRegion(LLViewerRegion *regionp);  	/*virtual*/ void   	 	 	updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax);  	/*virtual*/ void   	 	 	getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); -	/*virtual*/ BOOL   	 	 	lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +	/*virtual*/ BOOL   	 	 	lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  												 S32 face = -1,                    // which face to check, -1 = ALL_SIDES  												 BOOL pick_transparent = FALSE,  												 S32* face_hit = NULL,             // which face was hit -												 LLVector3* intersection = NULL,   // return the intersection point +												 LLVector4a* intersection = NULL,   // return the intersection point  												 LLVector2* tex_coord = NULL,      // return the texture coordinates of the intersection point -												 LLVector3* normal = NULL,         // return the surface normal at the intersection point -												 LLVector3* bi_normal = NULL);     // return the surface bi-normal at the intersection point -	LLViewerObject*	lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, +												 LLVector4a* normal = NULL,         // return the surface normal at the intersection point +												 LLVector4a* tangent = NULL);     // return the surface tangent at the intersection point +	LLViewerObject*	lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,  												 S32 face = -1,                    // which face to check, -1 = ALL_SIDES  												 BOOL pick_transparent = FALSE,  												 S32* face_hit = NULL,             // which face was hit -												 LLVector3* intersection = NULL,   // return the intersection point +												 LLVector4a* intersection = NULL,   // return the intersection point  												 LLVector2* tex_coord = NULL,      // return the texture coordinates of the intersection point -												 LLVector3* normal = NULL,         // return the surface normal at the intersection point -												 LLVector3* bi_normal = NULL);     // return the surface bi-normal at the intersection point +												 LLVector4a* normal = NULL,         // return the surface normal at the intersection point +												 LLVector4a* tangent = NULL);     // return the surface tangent at the intersection point  	//--------------------------------------------------------------------  	// LLCharacter interface and related diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index d54eb5f040..15628d5ab2 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -602,7 +602,7 @@ LLVOAvatarSelf::~LLVOAvatarSelf()   **                                                                             **   *********************************************************************************/ -// virtual +//virtual  BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent)  {  	// update screen joint size @@ -866,10 +866,10 @@ void LLVOAvatarSelf::removeMissingBakedTextures()  		updateMeshTextures();  		if (getRegion() && !getRegion()->getCentralBakeVersion())  		{ -			requestLayerSetUploads(); -		} +		requestLayerSetUploads();  	}  } +}  //virtual  void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp) @@ -1310,7 +1310,7 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr  			discard_level < local_tex_obj->getDiscard())  		{  			local_tex_obj->setDiscard(discard_level); -			requestLayerSetUpdate(index); +				requestLayerSetUpdate(index);  			if (isEditingAppearance())  			{  				LLVisualParamHint::requestHintUpdates(); @@ -1799,11 +1799,11 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te  					{  						requestLayerSetUpdate(type);  						if (isEditingAppearance()) -						{ -							LLVisualParamHint::requestHintUpdates(); -						} +					{ +						LLVisualParamHint::requestHintUpdates();  					}  				} +				}  				else  				{					  					tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL); @@ -2580,25 +2580,25 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe  	//if (!covered_by_baked)  	{  		if (imagep->getID() != IMG_DEFAULT_AVATAR) -		{ +	{  			imagep->setNoDelete();  			if (imagep->getDiscardLevel() != 0) -			{ -				F32 desired_pixels; -				desired_pixels = llmin(mPixelArea, (F32)getTexImageArea()); -				 -				imagep->setBoostLevel(getAvatarBoostLevel()); +		{ +			F32 desired_pixels; +			desired_pixels = llmin(mPixelArea, (F32)getTexImageArea()); + +			imagep->setBoostLevel(getAvatarBoostLevel());  				imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ; -				imagep->resetTextureStats(); -				imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); -				imagep->addTextureStats( desired_pixels / texel_area_ratio ); -				imagep->forceUpdateBindStats() ; -				if (imagep->getDiscardLevel() < 0) -				{ -					mHasGrey = TRUE; // for statistics gathering -				} +			imagep->resetTextureStats(); +			imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); +			imagep->addTextureStats( desired_pixels / texel_area_ratio ); +			imagep->forceUpdateBindStats() ; +			if (imagep->getDiscardLevel() < 0) +			{ +				mHasGrey = TRUE; // for statistics gathering  			}  		} +		}  		else  		{  			// texture asset is missing @@ -2921,17 +2921,17 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )  LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const  { -       /* switch(index) -               case TEX_HEAD_BAKED: -               case TEX_HEAD_BODYPAINT: -                       return mHeadLayerSet; */ +	/* switch(index) +		case TEX_HEAD_BAKED: +		case TEX_HEAD_BODYPAINT: +			return mHeadLayerSet; */         const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index); -       if (texture_dict->mIsUsedByBakedTexture) -       { -               const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; +	if (texture_dict->mIsUsedByBakedTexture) +	{ +		const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;                 return getLayerSet(baked_index); -       } -       return NULL; +	} +	return NULL;  }  LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const @@ -2959,7 +2959,7 @@ void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)  		gAgentAvatarp->mUseLocalAppearance = true;  		if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch) -		{ +{  			gAgentCamera.changeCameraToCustomizeAvatar();  		} diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 6a25b765cf..cab5c4bc1d 100755 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -764,8 +764,8 @@ void LLVOGrass::updateDrawable(BOOL force_damped)  }  // virtual  -BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, -									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, +									  LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  {  	BOOL ret = FALSE; @@ -776,7 +776,8 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  		return FALSE;  	} -	LLVector3 dir = end-start; +	LLVector4a dir; +	dir.setSub(end, start);  	mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion()); @@ -844,23 +845,31 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  		U32 idx0 = 0,idx1 = 0,idx2 = 0; -		if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE)) +		LLVector4a v0a,v1a,v2a,v3a; + +		v0a.load3(v[0].mV); +		v1a.load3(v[1].mV); +		v2a.load3(v[2].mV); +		v3a.load3(v[3].mV); + +		 +		if (LLTriangleRayIntersect(v0a, v1a, v2a, start, dir, a, b, t))  		{  			hit = TRUE;  			idx0 = 0; idx1 = 1; idx2 = 2;  		} -		else if (LLTriangleRayIntersect(v[1], v[3], v[2], start, dir, a, b, t, FALSE)) +		else if (LLTriangleRayIntersect(v1a, v3a, v2a, start, dir, a, b, t))  		{  			hit = TRUE;  			idx0 = 1; idx1 = 3; idx2 = 2;  		} -		else if (LLTriangleRayIntersect(v[2], v[1], v[0], start, dir, a, b, t, FALSE)) +		else if (LLTriangleRayIntersect(v2a, v1a, v0a, start, dir, a, b, t))  		{  			normal1 = -normal1;  			hit = TRUE;  			idx0 = 2; idx1 = 1; idx2 = 0;  		} -		else if (LLTriangleRayIntersect(v[2], v[3], v[1], start, dir, a, b, t, FALSE)) +		else if (LLTriangleRayIntersect(v2a, v3a, v1a, start, dir, a, b, t))  		{  			normal1 = -normal1;  			hit = TRUE; @@ -883,7 +892,8 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  					closest_t = t;  					if (intersection != NULL)  					{ -						*intersection = start+dir*closest_t; +						dir.mul(closest_t); +						intersection->setAdd(start, dir);  					}  					if (tex_coord != NULL) @@ -893,7 +903,7 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  					if (normal != NULL)  					{ -						*normal    = normal1; +						normal->load3(normal1.mV);  					}  					ret = TRUE;  				} diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h index b9835b8802..122806766d 100755 --- a/indra/newview/llvograss.h +++ b/indra/newview/llvograss.h @@ -75,14 +75,14 @@ public:  	/*virtual*/ BOOL    isActive() const; // Whether this object needs to do an idleUpdate.  	/*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); -	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  +	/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,   										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES  										  BOOL pick_transparent = FALSE,  										  S32* face_hit = NULL,                 // which face was hit -										  LLVector3* intersection = NULL,       // return the intersection point +										  LLVector4a* intersection = NULL,       // return the intersection point  										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point -										  LLVector3* normal = NULL,             // return the surface normal at the intersection point -										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point +										  LLVector4a* normal = NULL,             // return the surface normal at the intersection point +										  LLVector4a* tangent = NULL           // return the surface tangent at the intersection point  		);  	static S32 sMaxGrassSpecies; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 0b34bbb90f..43a5ddba42 100755 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -65,7 +65,9 @@ void LLVOPartGroup::initClass()  //static  void LLVOPartGroup::restoreGL()  { -	sVB = new LLVertexBuffer(VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + +	//TODO: optimize out binormal mask here.  Specular and normal coords as well. +	sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW_ARB);  	U32 count = LL_MAX_PARTICLE_COUNT;  	sVB->allocateBuffer(count*4, count*6, true); @@ -410,6 +412,7 @@ void LLVOPartGroup::getGeometry(S32 idx,  	right.setCross3(at, up);  	right.normalize3fast(); +  	up.setCross3(right, at);  	up.normalize3fast(); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index de15f0ef43..9a5c5831ca 100755 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -97,10 +97,10 @@ public:  			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));  			glClientActiveTextureARB(GL_TEXTURE0_ARB);  		} -		if (data_mask & MAP_BINORMAL) +		if (data_mask & MAP_TANGENT)  		{  			glClientActiveTextureARB(GL_TEXTURE2_ARB); -			glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); +			glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));  			glClientActiveTextureARB(GL_TEXTURE0_ARB);  		}  		if (data_mask & MAP_TEXCOORD0) @@ -936,8 +936,8 @@ void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,  	}  } -BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, -									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, +									  LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  { @@ -946,7 +946,9 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect  		return FALSE;  	} -	LLVector3 delta = end-start; +	LLVector4a da; +	da.setSub(end, start); +	LLVector3 delta(da.getF32ptr());  	LLVector3 pdelta = delta;  	pdelta.mV[2] = 0; @@ -955,7 +957,9 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect  	F32 tdelta = 1.f/plength; -	LLVector3 origin = start - mRegionp->getOriginAgent(); +	LLVector3 v_start(start.getF32ptr()); + +	LLVector3 origin = v_start - mRegionp->getOriginAgent();  	if (mRegionp->getLandHeightRegion(origin) > origin.mV[2])  	{ @@ -1010,12 +1014,12 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect  					{  						sample.mV[2] = mRegionp->getLandHeightRegion(sample);  					} -					*intersection = sample + mRegionp->getOriginAgent(); +					intersection->load3((sample + mRegionp->getOriginAgent()).mV);  				}  				if (normal)  				{ -					*normal = mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample)); +					normal->load3((mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample))).mV);  				}  				return TRUE; diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index a15878368e..7b53219be8 100755 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -79,14 +79,14 @@ public:  	void dirtyPatch();  	void dirtyGeom(); -	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  +	/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,   										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES  										  BOOL pick_transparent = FALSE,  										  S32* face_hit = NULL,                 // which face was hit -										  LLVector3* intersection = NULL,       // return the intersection point +										  LLVector4a* intersection = NULL,       // return the intersection point  										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point -										  LLVector3* normal = NULL,             // return the surface normal at the intersection point -										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point +										  LLVector4a* normal = NULL,             // return the surface normal at the intersection point +										  LLVector4a* tangent = NULL           // return the surface tangent at the intersection point  		);  	BOOL			mDirtiedPatch; diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 145a0380d6..cd12cd9552 100755 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -1085,132 +1085,6 @@ void LLVOTree::calcNumVerts(U32& vert_count, U32& index_count, S32 trunk_LOD, S3  	}  } -U32 LLVOTree::drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth,  F32 scale, F32 twist, F32 droop,  F32 branches, F32 alpha) -{ -	U32 ret = 0; -	// -	//  Draws a tree by recursing, drawing branches and then a 'leaf' texture. -	//  If stop_level = -1, simply draws the whole tree as a billboarded texture -	// -	 -	static F32 constant_twist; -	static F32 width = 0; - -	//F32 length = ((scale == 1.f)? mTrunkLength:mBranchLength); -	//F32 aspect = ((scale == 1.f)? mTrunkAspect:mBranchAspect); -	F32 length = ((trunk_depth || (scale == 1.f))? mTrunkLength:mBranchLength); -	F32 aspect = ((trunk_depth || (scale == 1.f))? mTrunkAspect:mBranchAspect); -	 -	constant_twist = 360.f/branches; - -	if (!LLPipeline::sReflectionRender && stop_level >= 0) -	{ -		// -		//  Draw the tree using recursion -		// -		if (depth > stop_level) -		{ -			{ -				llassert(sLODIndexCount[trunk_LOD] > 0); -				width = scale * length * aspect; -				LLMatrix4 scale_mat; -				scale_mat.mMatrix[0][0] = width; -				scale_mat.mMatrix[1][1] = width; -				scale_mat.mMatrix[2][2] = scale*length; -				scale_mat *= matrix; - -				gGL.loadMatrix((F32*) scale_mat.mMatrix); -				gGL.syncMatrices(); - 				glDrawElements(GL_TRIANGLES, sLODIndexCount[trunk_LOD], GL_UNSIGNED_SHORT, indicesp + sLODIndexOffset[trunk_LOD]); -				gPipeline.addTrianglesDrawn(LEAF_INDICES); -				stop_glerror(); -				ret += sLODIndexCount[trunk_LOD]; -			} -			 -			// Recurse to create more branches -			for (S32 i=0; i < (S32)branches; i++)  -			{ -				LLMatrix4 trans_mat; -				trans_mat.setTranslation(0,0,scale*length); -				trans_mat *= matrix; - -				LLQuaternion rot =  -					LLQuaternion(20.f*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)) * -					LLQuaternion(droop*DEG_TO_RAD, LLVector4(0.f, 1.f, 0.f)) * -					LLQuaternion(((constant_twist + ((i%2==0)?twist:-twist))*i)*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)); -				 -				LLMatrix4 rot_mat(rot); -				rot_mat *= trans_mat; - -				ret += drawBranchPipeline(rot_mat, indicesp, trunk_LOD, stop_level, depth - 1, 0, scale*mScaleStep, twist, droop, branches, alpha); -			} -			//  Recurse to continue trunk -			if (trunk_depth) -			{ -				LLMatrix4 trans_mat; -				trans_mat.setTranslation(0,0,scale*length); -				trans_mat *= matrix; - -				LLMatrix4 rot_mat(70.5f*DEG_TO_RAD, LLVector4(0,0,1)); -				rot_mat *= trans_mat; // rotate a bit around Z when ascending  -				ret += drawBranchPipeline(rot_mat, indicesp, trunk_LOD, stop_level, depth, trunk_depth-1, scale*mScaleStep, twist, droop, branches, alpha); -			} -		} -		else -		{ -			// -			//  Draw leaves as two 90 deg crossed quads with leaf textures -			// -			{ -				LLMatrix4 scale_mat; -				scale_mat.mMatrix[0][0] =  -					scale_mat.mMatrix[1][1] = -					scale_mat.mMatrix[2][2] = scale*mLeafScale; - -				scale_mat *= matrix; - -			 -				gGL.loadMatrix((F32*) scale_mat.mMatrix); -				gGL.syncMatrices(); -				glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp); -				gPipeline.addTrianglesDrawn(LEAF_INDICES);							 -				stop_glerror(); -				ret += LEAF_INDICES; -			} -		} -	} -	else -	{ -		// -		//  Draw the tree as a single billboard texture  -		// - -		LLMatrix4 scale_mat; -		scale_mat.mMatrix[0][0] =  -			scale_mat.mMatrix[1][1] = -			scale_mat.mMatrix[2][2] = mBillboardScale*mBillboardRatio; - -		scale_mat *= matrix; -	 -		gGL.matrixMode(LLRender::MM_TEXTURE); -		gGL.translatef(0.0, -0.5, 0.0); -		gGL.matrixMode(LLRender::MM_MODELVIEW); -					 -		gGL.loadMatrix((F32*) scale_mat.mMatrix); -		gGL.syncMatrices(); -		glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp); -		gPipeline.addTrianglesDrawn(LEAF_INDICES); -		stop_glerror(); -		ret += LEAF_INDICES; - -		gGL.matrixMode(LLRender::MM_TEXTURE); -		gGL.loadIdentity(); -		gGL.matrixMode(LLRender::MM_MODELVIEW); -	} - -	return ret; -} -  void LLVOTree::updateRadius()  {  	if (mDrawable.isNull()) @@ -1238,8 +1112,8 @@ void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)  	mDrawable->setPositionGroup(pos);  } -BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, -									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, +									  LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  { @@ -1268,16 +1142,19 @@ BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end  	LLVector3 pos, norm; -	if (linesegment_tetrahedron(start, end, center, size, quat, pos, norm)) +	LLVector3 start3(start.getF32ptr()); +	LLVector3 end3(end.getF32ptr()); + +	if (linesegment_tetrahedron(start3, end3, center, size, quat, pos, norm))  	{  		if (intersection)  		{ -			*intersection = pos; +			intersection->load3(pos.mV);  		}  		if (normal)  		{ -			*normal = norm; +			normal->load3(norm.mV);  		}  		return TRUE;  	} diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index 52debc85ab..2ecb0303a1 100755 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -104,19 +104,16 @@ public:  								 F32 twist,   								 F32 droop,    								 F32 branches,  -								 F32 alpha); +								 F32 alpha);  -	U32 drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth,  F32 scale, F32 twist, F32 droop,  F32 branches, F32 alpha); -  - -	 /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  +	 /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,   										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES  										  BOOL pick_transparent = FALSE,  										  S32* face_hit = NULL,                 // which face was hit -										  LLVector3* intersection = NULL,       // return the intersection point +										  LLVector4a* intersection = NULL,       // return the intersection point  										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point -										  LLVector3* normal = NULL,             // return the surface normal at the intersection point -										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point +										  LLVector4a* normal = NULL,             // return the surface normal at the intersection point +										  LLVector4a* tangent = NULL           // return the surface tangent at the intersection point  		);  	static S32 sMaxTreeSpecies; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8730ef66bb..007c2b9003 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -36,6 +36,7 @@  #include "lldir.h"  #include "llflexibleobject.h"  #include "llfloatertools.h" +#include "llmaterialid.h"  #include "llmaterialtable.h"  #include "llprimitive.h"  #include "llvolume.h" @@ -76,6 +77,7 @@  #include "llviewershadermgr.h"  #include "llvoavatar.h"  #include "llvocache.h" +#include "llmaterialmgr.h"  const S32 MIN_QUIET_FRAMES_COALESCE = 30;  const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; @@ -554,37 +556,9 @@ void LLVOVolume::animateTextures()  				tex_mat.setIdentity();  				LLVector3 trans ; -				if(facep->isAtlasInUse()) -				{ -					// -					//if use atlas for animated texture -					//apply the following transform to the animation matrix. -					// - -					F32 tcoord_xoffset = 0.f ; -					F32 tcoord_yoffset = 0.f ; -					F32 tcoord_xscale = 1.f ; -					F32 tcoord_yscale = 1.f ;			 -					if(facep->isAtlasInUse()) -					{ -						const LLVector2* tmp = facep->getTexCoordOffset() ; -						tcoord_xoffset = tmp->mV[0] ;  -						tcoord_yoffset = tmp->mV[1] ; - -						tmp = facep->getTexCoordScale() ; -						tcoord_xscale = tmp->mV[0] ;  -						tcoord_yscale = tmp->mV[1] ;	 -					} -					trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f)); - -					tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f)); -				} -				else	//non atlas -				{ -					trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));			 -					tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); -				} - +				trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));			 +				tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); +				  				LLVector3 scale(scale_s, scale_t, 1.f);			  				LLQuaternion quat;  				quat.setQuat(rot, 0, 0, -1.f); @@ -918,6 +892,12 @@ LLFace* LLVOVolume::addFace(S32 f)  {  	const LLTextureEntry* te = getTE(f);  	LLViewerTexture* imagep = getTEImage(f); +	if (te->getMaterialParams().notNull()) +	{ +		LLViewerTexture* normalp = getTENormalMap(f); +		LLViewerTexture* specularp = getTESpecularMap(f); +		return mDrawable->addFace(te, imagep, normalp, specularp); +	}  	return mDrawable->addFace(te, imagep);  } @@ -1066,7 +1046,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo  				{ //already cached  					break;  				} -				volume->genBinormals(i); +				volume->genTangents(i);  				LLFace::cacheFaceInVRAM(face);  			}  		} @@ -1415,6 +1395,11 @@ void LLVOVolume::regenFaces()  		facep->setTEOffset(i);  		facep->setTexture(getTEImage(i)); +		if (facep->getTextureEntry()->getMaterialParams().notNull()) +		{ +			facep->setNormalMap(getTENormalMap(i)); +			facep->setSpecularMap(getTESpecularMap(i)); +		}  		facep->setViewerObject(this);  		// If the face had media on it, this will have broken the link between the LLViewerMediaTexture and the face. @@ -1876,7 +1861,7 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color)  	const LLTextureEntry *tep = getTE(te);  	if (!tep)  	{ -		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl; +		LL_WARNS("MaterialTEs") << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;  	}  	else if (color != tep->getColor())  	{ @@ -1988,6 +1973,62 @@ S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow)  	return  res;  } +void LLVOVolume::setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID &pMaterialID, const LLMaterialPtr pMaterialParams, U32 te) +{ +	LLVOVolume* pVol = (LLVOVolume*)gObjectList.findObject(objectID); +	if (pVol) +	{ +		LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << " to TE " << te << LL_ENDL; +		if (te >= pVol->getNumTEs()) +			return; + +		LLTextureEntry* texture_entry = pVol->getTE(te); +		if (texture_entry && (texture_entry->getMaterialID() == pMaterialID)) +		{ +			pVol->setTEMaterialParams(te, pMaterialParams); +		} +	} +} + +S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) +{ +	S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID); +	LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res +								<< ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) +								<< LL_ENDL; +		 +	LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL; +	if (res) +	{ +		LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3)); + +		setChanged(ALL_CHANGED); +		if (!mDrawable.isNull()) +		{ +			gPipeline.markTextured(mDrawable); +			gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); +		} +		mFaceMappingChanged = TRUE; +	} +	return res; +} + +S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) +{ +	S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams); +	LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res +							 << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) +							 << LL_ENDL; +	setChanged(ALL_CHANGED); +	if (!mDrawable.isNull()) +	{ +		gPipeline.markTextured(mDrawable); +		gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); +	} +	mFaceMappingChanged = TRUE; +	return TEM_CHANGE_TEXTURE; +} +  S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t)  {  	S32 res = LLViewerObject::setTEScale(te, s, t); @@ -3573,8 +3614,8 @@ LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const  } -BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, -									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, +									  LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  {  	if (!mbCanSelect  @@ -3606,23 +3647,25 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	if (volume)  	{	 -		LLVector3 v_start, v_end, v_dir; -	 +		LLVector4a local_start = start; +		LLVector4a local_end = end; +		  		if (transform)  		{ -			v_start = agentPositionToVolume(start); -			v_end = agentPositionToVolume(end); -		} -		else -		{ -			v_start = start; -			v_end = end; -		} +			LLVector3 v_start(start.getF32ptr()); +			LLVector3 v_end(end.getF32ptr()); -		LLVector3 p; -		LLVector3 n; +			v_start = agentPositionToVolume(v_start); +			v_end = agentPositionToVolume(v_end); + +			local_start.load3(v_start.mV); +			local_end.load3(v_end.mV); +		} +				 +		LLVector4a p; +		LLVector4a n;  		LLVector2 tc; -		LLVector3 bn; +		LLVector4a tn;  		if (intersection != NULL)  		{ @@ -3639,9 +3682,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  			n = *normal;  		} -		if (bi_normal != NULL) +		if (tangent != NULL)  		{ -			bn = *bi_normal; +			tn = *tangent;  		}  		S32 face_hit = -1; @@ -3667,8 +3710,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  				continue;  			} -			face_hit = volume->lineSegmentIntersect(v_start, v_end, i, -													&p, &tc, &n, &bn); +			face_hit = volume->lineSegmentIntersect(local_start, local_end, i, +													&p, &tc, &n, &tn);  			if (face_hit >= 0 && mDrawable->getNumFaces() > face_hit)  			{ @@ -3677,7 +3720,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  				if (face &&  					(pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))  				{ -					v_end = p; +					local_end = p;  					if (face_hitp != NULL)  					{  						*face_hitp = face_hit; @@ -3687,7 +3730,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  					{  						if (transform)  						{ -							*intersection = volumePositionToAgent(p);  // must map back to agent space +							LLVector3 v_p(p.getF32ptr()); + +							intersection->load3(volumePositionToAgent(v_p).mV);  // must map back to agent space  						}  						else  						{ @@ -3699,27 +3744,36 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  					{  						if (transform)  						{ -							*normal = volumeDirectionToAgent(n); +							LLVector3 v_n(n.getF32ptr()); +							normal->load3(volumeDirectionToAgent(v_n).mV);  						}  						else  						{  							*normal = n;  						} - -						(*normal).normVec(); +						(*normal).normalize3fast();  					} -					if (bi_normal != NULL) +					if (tangent != NULL)  					{  						if (transform)  						{ -							*bi_normal = volumeDirectionToAgent(bn); +							LLVector3 v_tn(tn.getF32ptr()); + +							LLVector4a trans_tangent; +							trans_tangent.load3(volumeDirectionToAgent(v_tn).mV); + +							LLVector4Logical mask; +							mask.clear(); +							mask.setElement<3>(); + +							tangent->setSelectWithMask(mask, tn, trans_tangent);  						}  						else  						{ -							*bi_normal = bn; +							*tangent = tn;  						} -						(*bi_normal).normVec(); +						(*tangent).normalize3fast();  					}  					if (tex_coord != NULL) @@ -3976,6 +4030,11 @@ bool can_batch_texture(LLFace* facep)  		return false;  	} +	if (facep->getTextureEntry()->getMaterialParams().notNull()) +	{ //materials don't work with texture batching yet +		return false; +	} +  	if (facep->getTexture() && facep->getTexture()->getPrimaryFormat() == GL_ALPHA)  	{ //can't batch invisiprims  		return false; @@ -3994,7 +4053,11 @@ static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face");  void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)  {  	LLFastTimer t(FTM_REGISTER_FACE); - +	if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT)) +	{ +		LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; +	} +	  	if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)  	{  		return; @@ -4007,7 +4070,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  	BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) ||  		(type == LLRenderPass::PASS_INVISIBLE) || -		(type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)); +		(type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) || +		(type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) || +		(facep->getTextureEntry()->getFullbright());  	if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL))  	{ @@ -4041,16 +4106,39 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  	//drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD)));  	U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0; -	 +	U8 shiny = facep->getTextureEntry()->getShiny(); +  	LLViewerTexture* tex = facep->getTexture();  	U8 index = facep->getTextureIndex(); +	 +	LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get();  +	LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID();  	bool batchable = false; +	U32 shader_mask = 0xFFFFFFFF; //no shader + +	if (mat) +	{ +		if (type == LLRenderPass::PASS_ALPHA) +		{ +			shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND); +		} +		else +		{ +			shader_mask = mat->getShaderMask(); +		} +	} + +  	if (index < 255 && idx >= 0)  	{ -		if (index < draw_vec[idx]->mTextureList.size()) +		if (mat || draw_vec[idx]->mMaterial) +		{ //can't batch textures when materials are present (yet) +			batchable = false; +		} +		else if (index < draw_vec[idx]->mTextureList.size())  		{  			if (draw_vec[idx]->mTextureList[index].isNull())  			{ @@ -4076,16 +4164,20 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&  		draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&  #endif +		draw_vec[idx]->mMaterial == mat && +		draw_vec[idx]->mMaterialID == mat_id &&  		draw_vec[idx]->mFullbright == fullbright && -		draw_vec[idx]->mBump == bump && +		draw_vec[idx]->mBump  == bump  && +		(!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different  		draw_vec[idx]->mTextureMatrix == tex_mat && -		draw_vec[idx]->mModelMatrix == model_mat) +		draw_vec[idx]->mModelMatrix == model_mat && +		draw_vec[idx]->mShaderMask == shader_mask)  	{  		draw_vec[idx]->mCount += facep->getIndicesCount();  		draw_vec[idx]->mEnd += facep->getGeomCount();  		draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); -		if (index >= draw_vec[idx]->mTextureList.size()) +		if (index < 255 && index >= draw_vec[idx]->mTextureList.size())  		{  			draw_vec[idx]->mTextureList.resize(index+1);  			draw_vec[idx]->mTextureList[index] = tex; @@ -4101,12 +4193,66 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		U32 offset = facep->getIndicesStart();  		U32 count = facep->getIndicesCount();  		LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex,  -			facep->getVertexBuffer(), fullbright, bump);  +			facep->getVertexBuffer(), fullbright, bump);  		draw_info->mGroup = group;  		draw_info->mVSize = facep->getVirtualSize();  		draw_vec.push_back(draw_info);  		draw_info->mTextureMatrix = tex_mat;  		draw_info->mModelMatrix = model_mat; +		 +		draw_info->mBump  = bump; +		draw_info->mShiny = shiny; + +		float alpha[4] = +		{ +			0.00f, +			0.25f, +			0.5f, +			0.75f +		}; +		float spec = alpha[shiny & TEM_SHINY_MASK]; +		LLVector4 specColor(spec, spec, spec, spec); +		draw_info->mSpecColor = specColor; +		draw_info->mEnvIntensity = spec; +		draw_info->mSpecularMap = NULL; +		draw_info->mMaterial = mat; +		draw_info->mShaderMask = shader_mask; + +		if (mat) +		{ +				draw_info->mMaterialID = mat_id; + +				// We have a material.  Update our draw info accordingly. +				 +				if (!mat->getSpecularID().isNull()) +				{ +					LLVector4 specColor; +					specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f); +					specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f); +					specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f); +					specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f); +					draw_info->mSpecColor = specColor; +					draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f); +					draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset()); +				} + +				draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f); +				draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode(); +				draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset()); +				 +		} +		else  +		{ +			if (type == LLRenderPass::PASS_GRASS) +			{ +				draw_info->mAlphaMaskCutoff = 0.5f; +			} +			else +			{ +				draw_info->mAlphaMaskCutoff = 0.33f; +			} +		} +		  		if (type == LLRenderPass::PASS_ALPHA)  		{ //for alpha sorting  			facep->setDrawInfo(draw_info); @@ -4223,6 +4369,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	std::vector<LLFace*> fullbright_faces;  	std::vector<LLFace*> bump_faces; +	std::vector<LLFace*> norm_faces; +	std::vector<LLFace*> spec_faces; +	std::vector<LLFace*> normspec_faces;  	std::vector<LLFace*> simple_faces;  	std::vector<LLFace*> alpha_faces; @@ -4262,7 +4411,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  			}  			if (vobj->isMesh() && -				(vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled())) +				((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))  			{  				continue;  			} @@ -4389,66 +4538,123 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  						LLViewerTexture* tex = facep->getTexture();  						U32 type = gPipeline.getPoolTypeFromTE(te, tex); -						if (type == LLDrawPool::POOL_ALPHA) + +						if (te->getGlow())  						{ -							if (te->getColor().mV[3] > 0.f) -							{ -								if (te->getFullbright()) -								{ -									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); -								} -								else -								{ -									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); -								} +							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); +						} + +						LLMaterial* mat = te->getMaterialParams().get(); + +						if (mat && LLPipeline::sRenderDeferred) +						{ +							U8 alpha_mode = mat->getDiffuseAlphaMode(); + +							bool is_alpha = type == LLDrawPool::POOL_ALPHA && +								(alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND || +								te->getColor().mV[3] < 0.999f); + +							if (is_alpha) +							{ //this face needs alpha blending, override alpha mode +								alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; +							} + +							if (!is_alpha || te->getColor().mV[3] > 0.f)  // //only add the face if it will actually be visible +							{  +								U32 mask = mat->getShaderMask(alpha_mode); +								pool->addRiggedFace(facep, mask);  							}  						} -						else if (te->getShiny()) +						else if (mat)  						{ -							if (te->getFullbright()) +							bool fullbright = te->getFullbright(); +							bool is_alpha = type == LLDrawPool::POOL_ALPHA; +							U8 mode = mat->getDiffuseAlphaMode(); +							bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE || +												mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; +							 +							if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && te->getColor().mV[3] >= 0.999f)  							{ -								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY); +								pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE);  							} -							else +							else if (is_alpha || (te->getColor().mV[3] < 0.999f))  							{ -								if (LLPipeline::sRenderDeferred) -								{ -									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); -								} -								else +								if (te->getColor().mV[3] > 0.f)  								{ -									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); +									pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA : LLDrawPoolAvatar::RIGGED_ALPHA);  								}  							} -						} -						else -						{ -							if (te->getFullbright()) +							else if (gPipeline.canUseVertexShaders() +								&& LLPipeline::sRenderBump  +								&& te->getShiny()  +								&& can_be_shiny)  							{ -								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); +								pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY : LLDrawPoolAvatar::RIGGED_SHINY);  							}  							else  							{ -								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); +								pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE);  							}  						} - -						if (te->getGlow()) -						{ -							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); -						} - -						if (LLPipeline::sRenderDeferred) +						else  						{ -							if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright()) +							if (type == LLDrawPool::POOL_ALPHA)  							{ -								if (te->getBumpmap()) +								if (te->getColor().mV[3] > 0.f)  								{ -									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); +									if (te->getFullbright()) +									{ +										pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); +									} +									else +									{ +										pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); +									} +								} +							} +							else if (te->getShiny()) +							{ +								if (te->getFullbright()) +								{ +									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);  								}  								else  								{ -									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); +									if (LLPipeline::sRenderDeferred) +									{ +										pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); +									} +									else +									{ +										pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); +									} +								} +							} +							else +							{ +								if (te->getFullbright()) +								{ +									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); +								} +								else +								{ +									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); +								} +							} + +						 +							if (LLPipeline::sRenderDeferred) +							{ +								if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright()) +								{ +									if (te->getBumpmap()) +									{ +										pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); +									} +									else +									{ +										pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); +									}  								}  							}  						} @@ -4558,8 +4764,31 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  						if (gPipeline.canUseWindLightShadersOnObjects()  							&& LLPipeline::sRenderBump)  						{ -							if (te->getBumpmap()) -							{ //needs normal + binormal +							if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull()  && !te->getMaterialID().isNull()) +							{ +								LLMaterial* mat = te->getMaterialParams().get(); +								if (mat->getNormalID().notNull()) +								{ +									if (mat->getSpecularID().notNull()) +									{ //has normal and specular maps (needs texcoord1, texcoord2, and tangent) +										normspec_faces.push_back(facep); +									} +									else +									{ //has normal map (needs texcoord1 and tangent) +										norm_faces.push_back(facep); +									} +								} +								else if (mat->getSpecularID().notNull()) +								{ //has specular map but no normal map, needs texcoord2 +									spec_faces.push_back(facep); +								} +								else +								{ //has neither specular map nor normal map, only needs texcoord0 +									simple_faces.push_back(facep); +								}									 +							} +							else if (te->getBumpmap()) +							{ //needs normal + tangent  								bump_faces.push_back(facep);  							}  							else if (te->getShiny() || !te->getFullbright()) @@ -4575,7 +4804,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  						else  						{  							if (te->getBumpmap() && LLPipeline::sRenderBump) -							{ //needs normal + binormal +							{ //needs normal + tangent  								bump_faces.push_back(facep);  							}  							else if ((te->getShiny() && LLPipeline::sRenderBump) || @@ -4616,32 +4845,38 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;  	U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; +	U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT; +	U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2; +	U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2; +  	if (emissive)  	{ //emissive faces are present, include emissive byte to preserve batching  		simple_mask = simple_mask | LLVertexBuffer::MAP_EMISSIVE;  		alpha_mask = alpha_mask | LLVertexBuffer::MAP_EMISSIVE;  		bump_mask = bump_mask | LLVertexBuffer::MAP_EMISSIVE;  		fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_EMISSIVE; +		norm_mask = norm_mask | LLVertexBuffer::MAP_EMISSIVE; +		normspec_mask = normspec_mask | LLVertexBuffer::MAP_EMISSIVE; +		spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE;  	} -	bool batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; +	BOOL batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1;  	if (batch_textures)  	{ -		bump_mask |= LLVertexBuffer::MAP_BINORMAL; -		genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, TRUE); -		genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, TRUE); -		genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, TRUE); -		genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, TRUE); -	} -	else -	{ -		genDrawInfo(group, simple_mask, simple_faces); -		genDrawInfo(group, fullbright_mask, fullbright_faces); -		genDrawInfo(group, bump_mask, bump_faces, FALSE, TRUE); -		genDrawInfo(group, alpha_mask, alpha_faces, TRUE); +		bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT; +		simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; +		alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2; +		fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;  	} -	 + +	genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, batch_textures, FALSE); +	genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, batch_textures); +	genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, batch_textures); +	genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, FALSE); +	genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, norm_faces, FALSE, FALSE); +	genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, spec_faces, FALSE, FALSE); +	genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, normspec_faces, FALSE, FALSE);  	if (!LLPipeline::sDelayVBUpdate)  	{ @@ -4793,11 +5028,18 @@ struct CompareBatchBreakerModified  		{  			return lte->getFullbright() < rte->getFullbright();  		} +		else if (LLPipeline::sRenderDeferred && lte->getMaterialParams() != rte->getMaterialParams()) +		{ +			return lte->getMaterialParams() < rte->getMaterialParams(); +		} +		else if (LLPipeline::sRenderDeferred && (lte->getMaterialParams() == rte->getMaterialParams()) && (lte->getShiny() != rte->getShiny())) +		{ +			return lte->getShiny() < rte->getShiny(); +		}  		else  		{  			return lhs->getTexture() < rhs->getTexture();  		} -		  	}  }; @@ -4811,7 +5053,7 @@ static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB"); -void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures) +void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)  {  	LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); @@ -4881,6 +5123,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  		//pull off next face  		LLFace* facep = *face_iter;  		LLViewerTexture* tex = facep->getTexture(); +		LLMaterialPtr mat = facep->getTextureEntry()->getMaterialParams();  		if (distance_sort)  		{ @@ -4926,6 +5169,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  						if (!can_batch_texture(facep))  						{ //face is bump mapped or has an animated texture matrix -- can't   							//batch more than 1 texture at a time +							facep->setTextureIndex(0);  							break;  						} @@ -4976,13 +5220,20 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  						facep->setTextureIndex(cur_tex);  					}  				} +				else +				{ +					facep->setTextureIndex(0); +				}  				tex = texture_list[0];  			}  			else  			{  				while (i != faces.end() &&  -					(LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) +					(LLPipeline::sTextureBindTest ||  +						(distance_sort ||  +							((*i)->getTexture() == tex && +							((*i)->getTextureEntry()->getMaterialParams() == mat)))))  				{  					facep = *i; @@ -5068,8 +5319,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			index_offset += facep->getGeomCount();  			indices_index += facep->getIndicesCount(); - - +			  			//append face to appropriate render batch  			BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA; @@ -5089,7 +5339,130 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE; -			if (is_alpha) +			LLMaterial* mat = te->getMaterialParams().get(); + +			bool can_be_shiny = true; +			if (mat) +			{ +				U8 mode = mat->getDiffuseAlphaMode(); +				can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE || +								mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; +			} + +			bool use_legacy_bump = te->getBumpmap() && (!mat || mat->getNormalID().isNull()); + +			if (mat && LLPipeline::sRenderDeferred && !hud_group) +			{ +				bool material_pass = false; + +				if (fullbright) +				{ +					if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +					{ +						if (te->getColor().mV[3] >= 0.999f) +						{ +							material_pass = true; +						} +						else +						{ +							registerFace(group, facep, LLRenderPass::PASS_ALPHA); +						} +					} +					else if (is_alpha) +					{ +						registerFace(group, facep, LLRenderPass::PASS_ALPHA); +					} +					else +					{ +						if (mat->getEnvironmentIntensity() > 0 || +							te->getShiny() > 0) +						{ +							material_pass = true; +						} +						else +						{ +							registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); +						} +					} +				} +				else if (no_materials) +				{ +					registerFace(group, facep, LLRenderPass::PASS_SIMPLE); +				} +				else if (te->getColor().mV[3] < 0.999f) +				{ +					registerFace(group, facep, LLRenderPass::PASS_ALPHA); +				} +				else if (use_legacy_bump) +				{ +					// we have a material AND legacy bump settings, but no normal map +					registerFace(group, facep, LLRenderPass::PASS_BUMP); +				} +				else +				{ +					material_pass = true; +				} + +				if (material_pass) +				{ +					U32 pass[] =  +					{ +						LLRenderPass::PASS_MATERIAL, +						LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA, +						LLRenderPass::PASS_MATERIAL_ALPHA_MASK, +						LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, +						LLRenderPass::PASS_SPECMAP, +						LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_SPECMAP_BLEND, +						LLRenderPass::PASS_SPECMAP_MASK, +						LLRenderPass::PASS_SPECMAP_EMISSIVE, +						LLRenderPass::PASS_NORMMAP, +						LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMMAP_BLEND, +						LLRenderPass::PASS_NORMMAP_MASK, +						LLRenderPass::PASS_NORMMAP_EMISSIVE, +						LLRenderPass::PASS_NORMSPEC, +						LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMSPEC_BLEND, +						LLRenderPass::PASS_NORMSPEC_MASK, +						LLRenderPass::PASS_NORMSPEC_EMISSIVE, +					}; + +					U32 mask = mat->getShaderMask(); + +					llassert(mask < sizeof(pass)/sizeof(U32)); + +					mask = llmin(mask, (U32)(sizeof(pass)/sizeof(U32)-1)); + +					registerFace(group, facep, pass[mask]); +				} +			} +			else if (mat) +			{ +				U8 mode = mat->getDiffuseAlphaMode(); +				if (te->getColor().mV[3] < 0.999f) +				{ +					mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; +				} + +				if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +				{ +					registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK : LLRenderPass::PASS_ALPHA_MASK); +				} +				else if (is_alpha || (te->getColor().mV[3] < 0.999f)) +				{ +					registerFace(group, facep, LLRenderPass::PASS_ALPHA); +				} +				else if (gPipeline.canUseVertexShaders() +					&& LLPipeline::sRenderBump  +					&& te->getShiny()  +					&& can_be_shiny) +				{ +					registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_SHINY); +				} +				else +				{ +					registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT : LLRenderPass::PASS_SIMPLE); +				} +			} +			else if (is_alpha)  			{  				// can we safely treat this as an alpha mask?  				if (facep->getFaceColor().mV[3] <= 0.f) @@ -5114,7 +5487,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			}  			else if (gPipeline.canUseVertexShaders()  				&& LLPipeline::sRenderBump  -				&& te->getShiny()) +				&& te->getShiny()  +				&& can_be_shiny)  			{ //shiny  				if (tex->getPrimaryFormat() == GL_ALPHA)  				{ //invisiprim+shiny @@ -5131,7 +5505,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  							registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);  						}  					} -					else if (te->getBumpmap()) +					else if (use_legacy_bump)  					{ //register in deferred bump pass  						registerFace(group, facep, LLRenderPass::PASS_BUMP);  					} @@ -5158,22 +5532,36 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  				}  				else if (fullbright || bake_sunlight)  				{ //fullbright -					registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); -					if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && te->getBumpmap()) +					if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +					{ +						registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); +					} +					else +					{ +						registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); +					} +					if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && use_legacy_bump)  					{ //if this is the deferred render and a bump map is present, register in post deferred bump  						registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);  					}  				}  				else  				{ -					if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap()) +					if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && use_legacy_bump)  					{ //non-shiny or fullbright deferred bump  						registerFace(group, facep, LLRenderPass::PASS_BUMP);  					}  					else  					{ //all around simple  						llassert(mask & LLVertexBuffer::MAP_NORMAL); -						registerFace(group, facep, LLRenderPass::PASS_SIMPLE); +						if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +						{ //material alpha mask can be respected in non-deferred +							registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK); +						} +						else +						{ +							registerFace(group, facep, LLRenderPass::PASS_SIMPLE); +						}  					}  				} @@ -5193,7 +5581,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  				llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright);  				facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); -				if (!force_simple && te->getBumpmap() && LLPipeline::sRenderBump) +				if (!force_simple && LLPipeline::sRenderBump && use_legacy_bump)  				{  					registerFace(group, facep, LLRenderPass::PASS_BUMP);  				} @@ -5282,4 +5670,3 @@ void LLHUDPartition::shift(const LLVector4a &offset)  	//HUD objects don't shift with region crossing.  That would be silly.  } - diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 5482c80f2b..7503f8c5aa 100755 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -31,12 +31,14 @@  #include "llviewertexture.h"  #include "llviewermedia.h"  #include "llframetimer.h" +#include "lllocalbitmaps.h"  #include "m3math.h"		// LLMatrix3  #include "m4math.h"		// LLMatrix4  #include <map>  class LLViewerTextureAnim;  class LLDrawPool; +class LLMaterialID;  class LLSelectNode;  class LLObjectMediaDataClient;  class LLObjectMediaNavigateClient; @@ -135,14 +137,14 @@ public:  	/*virtual*/ U32		getTriangleCount(S32* vcount = NULL) const;  	/*virtual*/ U32		getHighLODTriangleCount(); -	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  +	/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,   										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES  										  BOOL pick_transparent = FALSE,  										  S32* face_hit = NULL,                 // which face was hit -										  LLVector3* intersection = NULL,       // return the intersection point +										  LLVector4a* intersection = NULL,       // return the intersection point  										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point -										  LLVector3* normal = NULL,             // return the surface normal at the intersection point -										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point +										  LLVector4a* normal = NULL,             // return the surface normal at the intersection point +										  LLVector4a* tangent = NULL           // return the surface tangent at the intersection point  		);  				LLVector3 agentPositionToVolume(const LLVector3& pos) const; @@ -157,6 +159,7 @@ public:  				const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const;  				void	markForUpdate(BOOL priority)			{ LLViewerObject::markForUpdate(priority); mVolumeChanged = TRUE; } +				void    faceMappingChanged()                    { mFaceMappingChanged=TRUE; };  	/*virtual*/ void	onShift(const LLVector4a &shift_vector); // Called when the drawable shifts @@ -185,6 +188,11 @@ public:  	/*virtual*/ S32		setTEBumpShinyFullbright(const U8 te, const U8 bump);  	/*virtual*/ S32		setTEMediaFlags(const U8 te, const U8 media_flags);  	/*virtual*/ S32		setTEGlow(const U8 te, const F32 glow); +	/*virtual*/ S32		setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); +	 +	static void	setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te); + +	/*virtual*/ S32		setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);  	/*virtual*/ S32		setTEScale(const U8 te, const F32 s, const F32 t);  	/*virtual*/ S32		setTEScaleS(const U8 te, const F32 s);  	/*virtual*/ S32		setTEScaleT(const U8 te, const F32 t); @@ -378,3 +386,4 @@ protected:  };  #endif // LL_LLVOVOLUME_H + diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp index b04d30db55..dba3970635 100755 --- a/indra/newview/llwlparamset.cpp +++ b/indra/newview/llwlparamset.cpp @@ -33,6 +33,7 @@  #include "llglslshader.h"  #include "lluictrlfactory.h"  #include "llsliderctrl.h" +#include "pipeline.h"  #include <llgl.h> @@ -127,6 +128,13 @@ void LLWLParamSet::update(LLGLSLShader * shader) const  			}  		}  	} +	 +	if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && !LLPipeline::sUnderWaterRender) +	{ +		shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); +	} else { +		shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); +	}  }  void LLWLParamSet::set(const std::string& paramName, float x)  diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 793becf0c8..7996f8a640 100755 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -274,7 +274,9 @@ void LLWorld::removeRegion(const LLHost &host)  	mActiveRegionList.remove(regionp);  	mCulledRegionList.remove(regionp);  	mVisibleRegionList.remove(regionp); -	 + +	mRegionRemovedSignal(regionp); +  	delete regionp;  	updateWaterObjects(); @@ -402,6 +404,19 @@ LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle)  	return NULL;  } +LLViewerRegion* LLWorld::getRegionFromID(const LLUUID& region_id) +{ +	for (region_list_t::iterator iter = mRegionList.begin(); +		 iter != mRegionList.end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		if (regionp->getRegionID() == region_id) +		{ +			return regionp; +		} +	} +	return NULL; +}  void LLWorld::updateAgentOffset(const LLVector3d &offset_global)  { @@ -1244,6 +1259,11 @@ bool LLWorld::isRegionListed(const LLViewerRegion* region) const  	return it != mRegionList.end();  } +boost::signals2::connection LLWorld::setRegionRemovedCallback(const region_remove_signal_t::slot_type& cb) +{ +	return mRegionRemovedSignal.connect(cb); +} +  LLHTTPRegistration<LLEstablishAgentCommunication>  	gHTTPRegistrationEstablishAgentCommunication(  							"/message/EstablishAgentCommunication"); diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index f350009d10..d0b001ba44 100755 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -76,6 +76,7 @@ public:  	LLViewerRegion*			getRegionFromPosGlobal(const LLVector3d &pos);  	LLViewerRegion*			getRegionFromPosAgent(const LLVector3 &pos);  	LLViewerRegion*			getRegionFromHandle(const U64 &handle); +	LLViewerRegion*			getRegionFromID(const LLUUID& region_id);  	BOOL					positionRegionValidGlobal(const LLVector3d& pos);			// true if position is in valid region  	LLVector3d				clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos); @@ -149,6 +150,9 @@ public:  	typedef std::list<LLViewerRegion*> region_list_t;  	const region_list_t& getRegionList() const { return mActiveRegionList; } +	typedef boost::signals2::signal<void(LLViewerRegion*)> region_remove_signal_t; +	boost::signals2::connection setRegionRemovedCallback(const region_remove_signal_t::slot_type& cb); +  	// Returns lists of avatar IDs and their world-space positions within a given distance of a point.  	// All arguments are optional. Given containers will be emptied and then filled.  	// Not supplying origin or radius input returns data on all avatars in the known regions. @@ -168,6 +172,8 @@ private:  	region_list_t	mVisibleRegionList;  	region_list_t	mCulledRegionList; +	region_remove_signal_t mRegionRemovedSignal; +  	// Number of points on edge  	static const U32 mWidth; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 7eed9acb4b..ebf6be4e36 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -233,6 +233,7 @@ LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY("Windlight Sky");  LLFastTimer::DeclareTimer FTM_RENDER_ALPHA("Alpha Objects");  LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS("Avatars");  LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump"); +LLFastTimer::DeclareTimer FTM_RENDER_MATERIALS("Materials");  LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright");  LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow");  LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update"); @@ -262,10 +263,13 @@ std::string gPoolNames[] =  	"POOL_GROUND",  	"POOL_FULLBRIGHT",  	"POOL_BUMP", +	"POOL_MATERIALS",  	"POOL_TERRAIN,"	  	"POOL_SKY",  	"POOL_WL_SKY",  	"POOL_TREE", +	"POOL_ALPHA_MASK", +	"POOL_FULLBRIGHT_ALPHA_MASK",  	"POOL_GRASS",  	"POOL_INVISIBLE",  	"POOL_AVATAR", @@ -352,6 +356,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; @@ -377,6 +382,7 @@ BOOL	LLPipeline::sRenderDeferred = FALSE;  BOOL    LLPipeline::sMemAllocationThrottled = FALSE;  S32		LLPipeline::sVisibleLightCount = 0;  F32		LLPipeline::sMinRenderSize = 0.f; +BOOL	LLPipeline::sRenderingHUDs;  // EventHost API LLPipeline listener.  static LLPipelineListener sPipelineListener; @@ -398,8 +404,8 @@ void validate_framebuffer_object();  bool addDeferredAttachments(LLRenderTarget& target)  { -	return target.addColorAttachment(GL_RGBA) && //specular -			target.addColorAttachment(GL_RGBA); //normal+z	 +	return target.addColorAttachment(GL_SRGB8_ALPHA8) && //specular +			target.addColorAttachment(GL_RGB10_A2); //normal+z  }  LLPipeline::LLPipeline() : @@ -435,10 +441,14 @@ LLPipeline::LLPipeline() :  	mWaterPool(NULL),  	mGroundPool(NULL),  	mSimplePool(NULL), +	mGrassPool(NULL), +	mAlphaMaskPool(NULL), +	mFullbrightAlphaMaskPool(NULL),  	mFullbrightPool(NULL),  	mInvisiblePool(NULL),  	mGlowPool(NULL),  	mBumpPool(NULL), +	mMaterialsPool(NULL),  	mWLSkyPool(NULL),  	mLightMask(0),  	mLightMovingMask(0), @@ -485,10 +495,13 @@ void LLPipeline::init()  	//create render pass pools  	getPool(LLDrawPool::POOL_ALPHA);  	getPool(LLDrawPool::POOL_SIMPLE); +	getPool(LLDrawPool::POOL_ALPHA_MASK); +	getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK);  	getPool(LLDrawPool::POOL_GRASS);  	getPool(LLDrawPool::POOL_FULLBRIGHT);  	getPool(LLDrawPool::POOL_INVISIBLE);  	getPool(LLDrawPool::POOL_BUMP); +	getPool(LLDrawPool::POOL_MATERIALS);  	getPool(LLDrawPool::POOL_GLOW);  	LLViewerStats::getInstance()->mTrianglesDrawnStat.reset(); @@ -917,11 +930,22 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  		BOOL ssao = RenderDeferredSSAO;  		//allocate deferred rendering color buffers -		if (!mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; +		if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;  		if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;  		if (!addDeferredAttachments(mDeferredScreen)) return false; -	 -		if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; +		 +		GLuint screenFormat = GL_RGBA16; +		if (gGLManager.mIsATI) +		{ +			screenFormat = GL_RGBA12; +		} + +		if (gGLManager.mGLVersion < 4.f && gGLManager.mIsNVIDIA) +		{ +			screenFormat = GL_RGBA16F_ARB; +		} +		 +		if (!mScreen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;  		if (samples > 0)  		{  			if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; @@ -1012,11 +1036,18 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  }  //static +void LLPipeline::updateRenderBump() +{ +	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); +} + +//static  void LLPipeline::updateRenderDeferred()  {  	BOOL deferred = ((RenderDeferred &&   					 LLRenderTarget::sUseFBO && -					 LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&	  +					 LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && +					 LLPipeline::sRenderBump &&  					 VertexShaderEnable &&   					 RenderAvatarVP &&  					 WindLightUseAtmosShaders) ? TRUE : FALSE) && @@ -1159,7 +1190,7 @@ void LLPipeline::releaseLUTBuffers()  {  	if (mLightFunc)  	{ -		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R8, 0, 1, &mLightFunc); +		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 0, 1, &mLightFunc);  		mLightFunc = 0;  	}  } @@ -1213,7 +1244,7 @@ void LLPipeline::createGLBuffers()  		for (U32 i = 0; i < 3; i++)  		{ -			mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE); +			mGlow[i].allocate(512,glow_res, GL_RGBA,FALSE,FALSE);  		}  		allocateScreenBuffer(resX,resY); @@ -1264,13 +1295,18 @@ void LLPipeline::createGLBuffers()  	gBumpImageList.restoreGL();  } +F32 lerpf(F32 a, F32 b, F32 w) +{ +	return a + w * (b - a); +} +  void LLPipeline::createLUTBuffers()  {  	if (sRenderDeferred)  	{  		if (!mLightFunc)  		{ -			U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); +			/*U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");  			U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");  			U8* ls = new U8[lightResX*lightResY];  			F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); @@ -1306,11 +1342,58 @@ void LLPipeline::createLUTBuffers()  					// Combined with a bit of noise and trilinear filtering, the banding is hardly noticable.  					ls[y*lightResX+x] = (U8)(llclamp(spec * (1.f / 6), 0.f, 1.f) * 255);  				} +			}*/ +		 + +			U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); +			U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); +			F32* ls = new F32[lightResX*lightResY]; +			//F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Note: only use this when creating new specular lighting functions. +            // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks) +			for (U32 y = 0; y < lightResY; ++y) +			{ +				for (U32 x = 0; x < lightResX; ++x) +				{ +					ls[y*lightResX+x] = 0; +					F32 sa = (F32) x/(lightResX-1); +					F32 spec = (F32) y/(lightResY-1); +					F32 n = spec * spec * 368; +					 +					// Nothing special here.  Just your typical blinn-phong term. +					spec = powf(sa, n); +					 +					// Apply our normalization function. +					// Note: This is the full equation that applies the full normalization curve, not an approximation. +					// This is fine, given we only need to create our LUT once per buffer initialization. +					spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n))); + +					// Since we use R16F, we no longer have a dynamic range issue we need to work around here. +					// Though some older drivers may not like this, newer drivers shouldn't have this problem. +					ls[y*lightResX+x] = spec; + +					 +					//beckmann distribution +					/*F32 alpha = acosf((F32) x/(lightResX-1)); +					F32 m = 1.f - (F32) y/(lightResY-1); + +					F32 cos4_alpha = cosf(alpha); +					cos4_alpha *= cos4_alpha; +					cos4_alpha *= cos4_alpha; + +					F32 tan_alpha = tanf(alpha); +					F32 tan2_alpha = tan_alpha*tan_alpha; + +					F32 k = expf(-(tan2_alpha)/(m*m)) / +						(3.14159f*m*m*cos4_alpha); + +					ls[y*lightResX+x] = k;*/ +				}  			} -			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc); +			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 1, &mLightFunc);  			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); -			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false); +			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R16F, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false); +			//LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_UNSIGNED_BYTE, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);  			gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);  			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); @@ -1516,6 +1599,14 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)  		poolp = mGrassPool;  		break; +	case LLDrawPool::POOL_ALPHA_MASK: +		poolp = mAlphaMaskPool; +		break; + +	case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: +		poolp = mFullbrightAlphaMaskPool; +		break; +  	case LLDrawPool::POOL_FULLBRIGHT:  		poolp = mFullbrightPool;  		break; @@ -1539,7 +1630,9 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)  	case LLDrawPool::POOL_BUMP:  		poolp = mBumpPool;  		break; - +	case LLDrawPool::POOL_MATERIALS: +		poolp = mMaterialsPool; +		break;  	case LLDrawPool::POOL_ALPHA:  		poolp = mAlphaPool;  		break; @@ -1603,20 +1696,44 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima  		return 0;  	} -	bool alpha = te->getColor().mV[3] < 0.999f; +	LLMaterial* mat = te->getMaterialParams().get(); + +	bool color_alpha = te->getColor().mV[3] < 0.999f; +	bool alpha = color_alpha;  	if (imagep)  	{  		alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);  	} - +	 +	if (alpha && mat) +	{ +		switch (mat->getDiffuseAlphaMode()) +		{ +			case 1: +				alpha = true; // Material's alpha mode is set to blend.  Toss it into the alpha draw pool. +				break; +			case 0: //alpha mode set to none, never go to alpha pool +			case 3: //alpha mode set to emissive, never go to alpha pool +				alpha = color_alpha; +				break; +			default: //alpha mode set to "mask", go to alpha pool if fullbright +				alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive.  Toss it into the opaque material draw pool. +				break; +		} +	} +	  	if (alpha)  	{  		return LLDrawPool::POOL_ALPHA;  	} -	else if ((te->getBumpmap() || te->getShiny())) +	else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull()))  	{  		return LLDrawPool::POOL_BUMP;  	} +	else if (mat && !alpha) +	{ +		return LLDrawPool::POOL_MATERIALS; +	}  	else  	{  		return LLDrawPool::POOL_SIMPLE; @@ -3579,8 +3696,8 @@ void LLPipeline::postSort(LLCamera& camera)  	for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)  	{  		LLSpatialGroup* group = *i; -		if (sUseOcclusion &&  -			group->isOcclusionState(LLSpatialGroup::OCCLUDED) || +		if ((sUseOcclusion &&  +			group->isOcclusionState(LLSpatialGroup::OCCLUDED)) ||  			(RenderAutoHideSurfaceAreaLimit > 0.f &&   			group->mSurfaceArea > RenderAutoHideSurfaceAreaLimit*llmax(group->mObjectBoxSize, 10.f)))  		{ @@ -3746,7 +3863,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())  		{ @@ -3969,13 +4088,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(); @@ -3991,7 +4111,7 @@ void LLPipeline::renderHighlights()  			facep->renderSelected(mFaceSelectImagep, color);  		}  	} - +	  	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))  	{  		// Paint 'em red! @@ -4013,6 +4133,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 @@ -5002,8 +5183,8 @@ void LLPipeline::renderDebug()  			LLSpatialPartition* part = region->getSpatialPartition(i);  			if (part)  			{ -				if ( hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES) || -					 !hud_only && hasRenderType(part->mDrawableType) ) +				if ( (hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES)) || +					 (!hud_only && hasRenderType(part->mDrawableType)) )  				{  					part->renderDebug();  				} @@ -5318,6 +5499,32 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )  		}  		break; +	case LLDrawPool::POOL_ALPHA_MASK: +		if (mAlphaMaskPool) +		{ +			llassert(0); +			llwarns << "Ignoring duplicate alpha mask pool." << llendl; +			break; +		} +		else +		{ +			mAlphaMaskPool = (LLRenderPass*) new_poolp; +		} +		break; + +	case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: +		if (mFullbrightAlphaMaskPool) +		{ +			llassert(0); +			llwarns << "Ignoring duplicate alpha mask pool." << llendl; +			break; +		} +		else +		{ +			mFullbrightAlphaMaskPool = (LLRenderPass*) new_poolp; +		} +		break; +		  	case LLDrawPool::POOL_GRASS:  		if (mGrassPool)  		{ @@ -5385,7 +5592,17 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )  			mBumpPool = new_poolp;  		}  		break; - +	case LLDrawPool::POOL_MATERIALS: +		if (mMaterialsPool) +		{ +			llassert(0); +			llwarns << "Ignorning duplicate materials pool." << llendl; +		} +		else +		{ +			mMaterialsPool = new_poolp; +		} +		break;  	case LLDrawPool::POOL_ALPHA:  		if( mAlphaPool )  		{ @@ -5394,7 +5611,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )  		}  		else  		{ -			mAlphaPool = new_poolp; +			mAlphaPool = (LLDrawPoolAlpha*) new_poolp;  		}  		break; @@ -5474,6 +5691,16 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )  		mSimplePool = NULL;  		break; +	case LLDrawPool::POOL_ALPHA_MASK: +		llassert(mAlphaMaskPool == poolp); +		mAlphaMaskPool = NULL; +		break; + +	case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: +		llassert(mFullbrightAlphaMaskPool == poolp); +		mFullbrightAlphaMaskPool = NULL; +		break; +  	case LLDrawPool::POOL_GRASS:  		llassert(mGrassPool == poolp);  		mGrassPool = NULL; @@ -5525,7 +5752,12 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )  		llassert( poolp == mBumpPool );  		mBumpPool = NULL;  		break; -	 +			 +	case LLDrawPool::POOL_MATERIALS: +		llassert(poolp == mMaterialsPool); +		mMaterialsPool = NULL; +		break; +			  	case LLDrawPool::POOL_ALPHA:  		llassert( poolp == mAlphaPool );  		mAlphaPool = NULL; @@ -5588,8 +5820,15 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)  		LLLightState* light = gGL.getLight(1); -		mHWLightColors[1] = diffuse; +		if (LLPipeline::sRenderDeferred) +		{ +			diffuse.mV[0] = powf(diffuse.mV[0], 2.2f); +			diffuse.mV[1] = powf(diffuse.mV[1], 2.2f); +			diffuse.mV[2] = powf(diffuse.mV[2], 2.2f); +		} +		mHWLightColors[1] = diffuse; +				  		light->setDiffuse(diffuse);  		light->setAmbient(LLColor4::black);  		light->setSpecular(LLColor4::black); @@ -5628,6 +5867,13 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)  		}  		backlight_diffuse *= backlight_mag / max_component; +		if (LLPipeline::sRenderDeferred) +		{ +			backlight_diffuse.mV[0] = powf(backlight_diffuse.mV[0], 2.2f); +			backlight_diffuse.mV[1] = powf(backlight_diffuse.mV[1], 2.2f); +			backlight_diffuse.mV[2] = powf(backlight_diffuse.mV[2], 2.2f); +		} +  		mHWLightColors[1] = backlight_diffuse;  		LLLightState* light = gGL.getLight(1); @@ -5834,6 +6080,14 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  		LLVector4 light_pos(mSunDir, 0.0f);  		LLColor4 light_diffuse = mSunDiffuse; + +		if (LLPipeline::sRenderDeferred) +		{ +			light_diffuse.mV[0] = powf(light_diffuse.mV[0], 2.2f); +			light_diffuse.mV[1] = powf(light_diffuse.mV[1], 2.2f); +			light_diffuse.mV[2] = powf(light_diffuse.mV[2], 2.2f); +		} +  		mHWLightColors[0] = light_diffuse;  		LLLightState* light = gGL.getLight(0); @@ -5902,6 +6156,13 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  			F32 x = (3.f * (1.f + light->getLightFalloff())); // why this magic?  probably trying to match a historic behavior.  			float linatten = x / (light_radius); // % of brightness at radius +			if (LLPipeline::sRenderDeferred) +			{ +				light_color.mV[0] = powf(light_color.mV[0], 2.2f); +				light_color.mV[1] = powf(light_color.mV[1], 2.2f); +				light_color.mV[2] = powf(light_color.mV[2], 2.2f); +			} +  			mHWLightColors[cur_light] = light_color;  			LLLightState* light_state = gGL.getLight(cur_light); @@ -5975,6 +6236,13 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  			F32 x = 3.f;  		float linatten = x / (light_radius); // % of brightness at radius +		if (LLPipeline::sRenderDeferred) +		{ +			light_color.mV[0] = powf(light_color.mV[0], 2.2f); +			light_color.mV[1] = powf(light_color.mV[1], 2.2f); +			light_color.mV[2] = powf(light_color.mV[2], 2.2f); +		} +  		mHWLightColors[2] = light_color;  		LLLightState* light = gGL.getLight(2); @@ -6615,20 +6883,26 @@ BOOL LLPipeline::getRenderHighlights(void*)  	return sRenderHighlight;  } -LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, +// static +void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel) +{ +	sRenderHighlightTextureChannel = channel; +} + +LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,  														BOOL pick_transparent,												  														S32* face_hit, -														LLVector3* intersection,         // return the intersection point +														LLVector4a* intersection,         // return the intersection point  														LLVector2* tex_coord,            // return the texture coordinates of the intersection point -														LLVector3* normal,               // return the surface normal at the intersection point -														LLVector3* bi_normal             // return the surface bi-normal at the intersection point +														LLVector4a* normal,               // return the surface normal at the intersection point +														LLVector4a* tangent             // return the surface tangent at the intersection point  	)  {  	LLDrawable* drawable = NULL; -	LLVector3 local_end = end; +	LLVector4a local_end = end; -	LLVector3 position; +	LLVector4a position;  	sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE; @@ -6648,7 +6922,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  				LLSpatialPartition* part = region->getSpatialPartition(j);  				if (part && hasRenderType(part->mDrawableType))  				{ -					LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal); +					LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);  					if (hit)  					{  						drawable = hit; @@ -6663,8 +6937,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  	{  		//save hit info in case we need to restore  		//due to attachment override -		LLVector3 local_normal; -		LLVector3 local_binormal; +		LLVector4a local_normal; +		LLVector4a local_tangent;  		LLVector2 local_texcoord;  		S32 local_face_hit = -1; @@ -6676,14 +6950,22 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  		{  			local_texcoord = *tex_coord;  		} -		if (bi_normal) +		if (tangent) +		{ +			local_tangent = *tangent; +		} +		else  		{ -			local_binormal = *bi_normal; +			local_tangent.clear();  		}  		if (normal)  		{  			local_normal = *normal;  		} +		else +		{ +			local_normal.clear(); +		}  		const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f; @@ -6697,12 +6979,15 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  			LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);  			if (part && hasRenderType(part->mDrawableType))  			{ -				LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal); +				LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);  				if (hit)  				{ +					LLVector4a delta; +					delta.setSub(position, local_end); +  					if (!drawable ||   						!drawable->getVObj()->isAttachment() || -						(position-local_end).magVec() > ATTACHMENT_OVERRIDE_DIST) +						delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST)  					{ //avatar overrides if previously hit drawable is not an attachment or   					  //attachment is far enough away from detected intersection  						drawable = hit; @@ -6720,9 +7005,9 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  						{  							*tex_coord = local_texcoord;  						} -						if (bi_normal) +						if (tangent)  						{ -							*bi_normal = local_binormal; +							*tangent = local_tangent;  						}  						if (normal)  						{ @@ -6756,13 +7041,13 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  	return drawable ? drawable->getVObj().get() : NULL;  } -LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end, +LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,  													  BOOL pick_transparent,													  													  S32* face_hit, -													  LLVector3* intersection,         // return the intersection point +													  LLVector4a* intersection,         // return the intersection point  													  LLVector2* tex_coord,            // return the texture coordinates of the intersection point -													  LLVector3* normal,               // return the surface normal at the intersection point -													  LLVector3* bi_normal             // return the surface bi-normal at the intersection point +													  LLVector4a* normal,               // return the surface normal at the intersection point +													  LLVector4a* tangent				// return the surface tangent at the intersection point  	)  {  	LLDrawable* drawable = NULL; @@ -6782,7 +7067,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co  		LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);  		if (part)  		{ -			LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal); +			LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);  			if (hit)  			{  				drawable = hit; @@ -6886,7 +7171,9 @@ void LLPipeline::doResetVertexBuffers()  	LLVertexBuffer::unbind();	 -	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); +	updateRenderBump(); +	updateRenderDeferred(); +  	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");  	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");  	LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); @@ -6912,6 +7199,17 @@ void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_text  	gGLLastMatrix = NULL;		  } +void LLPipeline::renderMaskedObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture) +{ +	assertInitialized(); +	gGL.loadMatrix(gGLModelView); +	gGLLastMatrix = NULL; +	mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); +	gGL.loadMatrix(gGLModelView); +	gGLLastMatrix = NULL;		 +} + +  void apply_cube_face_rotation(U32 face)  {  	switch (face) @@ -7013,10 +7311,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  	gGL.loadIdentity();  	LLGLDisable test(GL_ALPHA_TEST); - +	  	gGL.setColorMask(true, true);  	glClearColor(0,0,0,0); -		 +	  	{  		{  			LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); @@ -7188,13 +7486,18 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  			{  				if (LLViewerJoystick::getInstance()->getOverrideCamera())  				{ //focus on point under cursor -					focus_point = gDebugRaycastIntersection; +					focus_point.set(gDebugRaycastIntersection.getF32ptr());  				}  				else if (gAgentCamera.cameraMouselook())  				{ //focus on point under mouselook crosshairs +					LLVector4a result; +					result.clear(); +  					gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,  													NULL, -													&focus_point); +													&result); + +					focus_point.set(result.getF32ptr());  				}  				else  				{ @@ -7354,6 +7657,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  					mScreen.bindTexture(0, channel);  					gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);  				} +				 +				if (!LLViewerCamera::getInstance()->cameraUnderWater()) +				{ +					shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); +				} else { +					shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); +				}  				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);  				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); @@ -7395,6 +7705,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  			{  				mScreen.bindTexture(0, channel);  			} +			 +			if (!LLViewerCamera::getInstance()->cameraUnderWater()) +			{ +				shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); +			} else { +				shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); +			}  			gGL.begin(LLRender::TRIANGLE_STRIP);  			gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); @@ -7815,6 +8132,22 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n  	}  } +LLColor3 pow3f(LLColor3 v, F32 f) +{ +	v.mV[0] = powf(v.mV[0], f); +	v.mV[1] = powf(v.mV[1], f); +	v.mV[2] = powf(v.mV[2], f); +	return v; +} + +LLVector4 pow4fsrgb(LLVector4 v, F32 f) +{ +	v.mV[0] = powf(v.mV[0], f); +	v.mV[1] = powf(v.mV[1], f); +	v.mV[2] = powf(v.mV[2], f); +	return v; +} +  static LLFastTimer::DeclareTimer FTM_GI_TRACE("Trace");  static LLFastTimer::DeclareTimer FTM_GI_GATHER("Gather");  static LLFastTimer::DeclareTimer FTM_SUN_SHADOW("Shadow Map"); @@ -8147,6 +8480,10 @@ void LLPipeline::renderDeferredLighting()  								continue;  							} +							col.mV[0] = powf(col.mV[0], 2.2f); +							col.mV[1] = powf(col.mV[1], 2.2f); +							col.mV[2] = powf(col.mV[2], 2.2f); +							  							LLFastTimer ftm(FTM_LOCAL_LIGHTS);  							gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);  							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s); @@ -8203,6 +8540,9 @@ void LLPipeline::renderDeferredLighting()  					setupSpotLight(gDeferredSpotLightProgram, drawablep);  					LLColor3 col = volume->getLightColor(); +					col.mV[0] = powf(col.mV[0], 2.2f); +					col.mV[1] = powf(col.mV[1], 2.2f); +					col.mV[2] = powf(col.mV[2], 2.2f);  					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);  					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s); @@ -8251,9 +8591,13 @@ void LLPipeline::renderDeferredLighting()  					fullscreen_lights.pop_front();  					col[count] = light_colors.front();  					light_colors.pop_front(); - +					 +					col[count].mV[0] = powf(col[count].mV[0], 2.2f); +					col[count].mV[1] = powf(col[count].mV[1], 2.2f); +					col[count].mV[2] = powf(col[count].mV[2], 2.2f); +					  					far_z = llmin(light[count].mV[2]-sqrtf(light[count].mV[3]), far_z); - +					//col[count] = pow4fsrgb(col[count], 2.2f);  					count++;  					if (count == max_count || fullscreen_lights.empty())  					{ @@ -8295,6 +8639,10 @@ void LLPipeline::renderDeferredLighting()  					LLColor3 col = volume->getLightColor(); +					col.mV[0] = powf(col.mV[0], 2.2f); +					col.mV[1] = powf(col.mV[1], 2.2f); +					col.mV[2] = powf(col.mV[2], 2.2f); +					  					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);  					gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);  					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); @@ -8314,6 +8662,65 @@ void LLPipeline::renderDeferredLighting()  		gGL.setColorMask(true, true);  	} +	mScreen.flush(); + +	//gamma correct lighting +	gGL.matrixMode(LLRender::MM_PROJECTION); +	gGL.pushMatrix(); +	gGL.loadIdentity(); +	gGL.matrixMode(LLRender::MM_MODELVIEW); +	gGL.pushMatrix(); +	gGL.loadIdentity(); + +	{ +		LLGLDepthTest depth(GL_FALSE, GL_FALSE); + +		LLVector2 tc1(0,0); +		LLVector2 tc2((F32) mScreen.getWidth()*2, +				  (F32) mScreen.getHeight()*2); + +		mScreen.bindTarget(); +		// Apply gamma correction to the frame here. +		gDeferredPostGammaCorrectProgram.bind(); +		//mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +		S32 channel = 0; +		channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); +		if (channel > -1) +		{ +			mScreen.bindTexture(0,channel); +			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +		} +		 +		gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight()); +		 +		F32 gamma = 1.0/2.2; + +		gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, gamma); +		 +		gGL.begin(LLRender::TRIANGLE_STRIP); +		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +		gGL.vertex2f(-1,-1); +		 +		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +		gGL.vertex2f(-1,3); +		 +		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +		gGL.vertex2f(3,-1); +		 +		gGL.end(); +		 +		gGL.getTexUnit(channel)->unbind(mScreen.getUsage()); +		gDeferredPostGammaCorrectProgram.unbind(); +		mScreen.flush(); +	} + +	gGL.matrixMode(LLRender::MM_PROJECTION); +	gGL.popMatrix(); +	gGL.matrixMode(LLRender::MM_MODELVIEW); +	gGL.popMatrix();	 + +	mScreen.bindTarget(); +  	{ //render non-deferred geometry (alpha, fullbright, glow)  		LLGLDisable blend(GL_BLEND);  		LLGLDisable stencil(GL_STENCIL_TEST); @@ -8338,6 +8745,8 @@ void LLPipeline::renderDeferredLighting()  						 LLPipeline::RENDER_TYPE_PASS_INVISIBLE,  						 LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,  						 LLPipeline::RENDER_TYPE_AVATAR, +						 LLPipeline::RENDER_TYPE_ALPHA_MASK, +						 LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,  						 END_RENDER_TYPES);  		renderGeomPostDeferred(*LLViewerCamera::getInstance()); @@ -8890,11 +9299,22 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  		LLRenderPass::PASS_FULLBRIGHT,   		LLRenderPass::PASS_SHINY,   		LLRenderPass::PASS_BUMP,  -		LLRenderPass::PASS_FULLBRIGHT_SHINY  +		LLRenderPass::PASS_FULLBRIGHT_SHINY , +		LLRenderPass::PASS_MATERIAL, +		LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, +		LLRenderPass::PASS_SPECMAP, +		LLRenderPass::PASS_SPECMAP_EMISSIVE, +		LLRenderPass::PASS_NORMMAP, +		LLRenderPass::PASS_NORMMAP_EMISSIVE, +		LLRenderPass::PASS_NORMSPEC, +		LLRenderPass::PASS_NORMSPEC_EMISSIVE,  	};  	LLGLEnable cull(GL_CULL_FACE); +	//enable depth clamping if available +	LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); +  	if (use_shader)  	{  		gDeferredShadowCubeProgram.bind(); @@ -8961,7 +9381,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  	{  		LLFastTimer ftm(FTM_SHADOW_ALPHA);  		gDeferredShadowAlphaMaskProgram.bind(); -		gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);  		gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);  		U32 mask =	LLVertexBuffer::MAP_VERTEX |  @@ -8969,10 +9388,19 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  					LLVertexBuffer::MAP_COLOR |   					LLVertexBuffer::MAP_TEXTURE_INDEX; -		renderObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE); -		renderObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE); +		renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE); +		renderMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE); +		gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);  		renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE); + +		mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX; +  		gDeferredTreeShadowProgram.bind(); +		renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, mask); +		renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, mask); +		renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, mask); +		renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, mask); +		  		gDeferredTreeShadowProgram.setMinimumAlpha(0.598f);  		renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);  	} @@ -9303,6 +9731,22 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  					LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,  					LLPipeline::RENDER_TYPE_PASS_SHINY,  					LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, +					LLPipeline::RENDER_TYPE_PASS_MATERIAL, +					LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA, +					LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK, +					LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE, +					LLPipeline::RENDER_TYPE_PASS_SPECMAP, +					LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND, +					LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK, +					LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE, +					LLPipeline::RENDER_TYPE_PASS_NORMMAP, +					LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND, +					LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK, +					LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE, +					LLPipeline::RENDER_TYPE_PASS_NORMSPEC, +					LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND, +					LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK, +					LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE,  					END_RENDER_TYPES);  	gGL.setColorMask(false, false); @@ -9822,7 +10266,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  			{  				static LLCullResult result[4]; -				//LLGLEnable enable(GL_DEPTH_CLAMP_NV);  				renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, TRUE, target_width);  			} @@ -10129,11 +10572,13 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  		LLVector4a left;  		left.load3(camera.getLeftAxis().mV);  		left.mul(left); +		llassert(left.dot3(left).getF32() > F_APPROXIMATELY_ZERO);  		left.normalize3fast();  		LLVector4a up;  		up.load3(camera.getUpAxis().mV);  		up.mul(up); +		llassert(up.dot3(up).getF32() > F_APPROXIMATELY_ZERO);  		up.normalize3fast();  		tdim.mV[0] = fabsf(half_height.dot3(left).getF32()); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index a8db93585e..2c023a6f70 100755 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -35,7 +35,8 @@  #include "llspatialpartition.h"  #include "m4math.h"  #include "llpointer.h" -#include "lldrawpool.h" +#include "lldrawpoolalpha.h" +#include "lldrawpoolmaterials.h"  #include "llgl.h"  #include "lldrawable.h"  #include "llrendertarget.h" @@ -59,6 +60,7 @@ class LLCullResult;  class LLVOAvatar;  class LLGLSLShader;  class LLCurlRequest; +class LLDrawPoolAlpha;  class LLMeshResponder; @@ -95,6 +97,7 @@ extern LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY;  extern LLFastTimer::DeclareTimer FTM_RENDER_ALPHA;  extern LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS;  extern LLFastTimer::DeclareTimer FTM_RENDER_BUMP; +extern LLFastTimer::DeclareTimer FTM_RENDER_MATERIALS;  extern LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT;  extern LLFastTimer::DeclareTimer FTM_RENDER_GLOW;  extern LLFastTimer::DeclareTimer FTM_STATESORT; @@ -185,21 +188,21 @@ public:  	void		markMeshDirty(LLSpatialGroup* group);  	//get the object between start and end that's closest to start. -	LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, +	LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,  												BOOL pick_transparent,  												S32* face_hit,                          // return the face hit -												LLVector3* intersection = NULL,         // return the intersection point +												LLVector4a* intersection = NULL,         // return the intersection point  												LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -												LLVector3* normal = NULL,               // return the surface normal at the intersection point -												LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point   +												LLVector4a* normal = NULL,               // return the surface normal at the intersection point +												LLVector4a* tangent = NULL             // return the surface tangent at the intersection point    		); -	LLViewerObject* lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end, +	LLViewerObject* lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,  											  BOOL pick_transparent,  											  S32* face_hit,                          // return the face hit -											  LLVector3* intersection = NULL,         // return the intersection point +											  LLVector4a* intersection = NULL,         // return the intersection point  											  LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -											  LLVector3* normal = NULL,               // return the surface normal at the intersection point -											  LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point +											  LLVector4a* normal = NULL,               // return the surface normal at the intersection point +											  LLVector4a* tangent = NULL             // return the surface tangent at the intersection point  		);  	// Something about these textures has changed.  Dirty them. @@ -256,6 +259,8 @@ public:  	void forAllVisibleDrawables(void (*func)(LLDrawable*));  	void renderObjects(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_texture = FALSE); +	void renderMaskedObjects(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_texture = FALSE); +  	void renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture);  	void grabReferences(LLCullResult& result); @@ -389,12 +394,16 @@ 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();  	static void refreshCachedSettings();  	static void throttleNewMemoryAllocation(BOOL disable); +	 +  	void addDebugBlip(const LLVector3& position, const LLColor4& color);  	void hidePermanentObjects( std::vector<U32>& restoreList ); @@ -425,8 +434,11 @@ public:  		RENDER_TYPE_TERRAIN						= LLDrawPool::POOL_TERRAIN,  		RENDER_TYPE_SIMPLE						= LLDrawPool::POOL_SIMPLE,  		RENDER_TYPE_GRASS						= LLDrawPool::POOL_GRASS, +		RENDER_TYPE_ALPHA_MASK					= LLDrawPool::POOL_ALPHA_MASK, +		RENDER_TYPE_FULLBRIGHT_ALPHA_MASK		= LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK,  		RENDER_TYPE_FULLBRIGHT					= LLDrawPool::POOL_FULLBRIGHT,  		RENDER_TYPE_BUMP						= LLDrawPool::POOL_BUMP, +		RENDER_TYPE_MATERIALS					= LLDrawPool::POOL_MATERIALS,  		RENDER_TYPE_AVATAR						= LLDrawPool::POOL_AVATAR,  		RENDER_TYPE_TREE						= LLDrawPool::POOL_TREE,  		RENDER_TYPE_INVISIBLE					= LLDrawPool::POOL_INVISIBLE, @@ -447,6 +459,22 @@ public:  		RENDER_TYPE_PASS_ALPHA					= LLRenderPass::PASS_ALPHA,  		RENDER_TYPE_PASS_ALPHA_MASK				= LLRenderPass::PASS_ALPHA_MASK,  		RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK	= LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, +		RENDER_TYPE_PASS_MATERIAL				= LLRenderPass::PASS_MATERIAL, +		RENDER_TYPE_PASS_MATERIAL_ALPHA			= LLRenderPass::PASS_MATERIAL_ALPHA, +		RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK	= LLRenderPass::PASS_MATERIAL_ALPHA_MASK, +		RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE= LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, +		RENDER_TYPE_PASS_SPECMAP				= LLRenderPass::PASS_SPECMAP, +		RENDER_TYPE_PASS_SPECMAP_BLEND			= LLRenderPass::PASS_SPECMAP_BLEND, +		RENDER_TYPE_PASS_SPECMAP_MASK			= LLRenderPass::PASS_SPECMAP_MASK, +		RENDER_TYPE_PASS_SPECMAP_EMISSIVE		= LLRenderPass::PASS_SPECMAP_EMISSIVE, +		RENDER_TYPE_PASS_NORMMAP				= LLRenderPass::PASS_NORMMAP, +		RENDER_TYPE_PASS_NORMMAP_BLEND			= LLRenderPass::PASS_NORMMAP_BLEND, +		RENDER_TYPE_PASS_NORMMAP_MASK			= LLRenderPass::PASS_NORMMAP_MASK, +		RENDER_TYPE_PASS_NORMMAP_EMISSIVE		= LLRenderPass::PASS_NORMMAP_EMISSIVE, +		RENDER_TYPE_PASS_NORMSPEC				= LLRenderPass::PASS_NORMSPEC, +		RENDER_TYPE_PASS_NORMSPEC_BLEND			= LLRenderPass::PASS_NORMSPEC_BLEND, +		RENDER_TYPE_PASS_NORMSPEC_MASK			= LLRenderPass::PASS_NORMSPEC_MASK, +		RENDER_TYPE_PASS_NORMSPEC_EMISSIVE		= LLRenderPass::PASS_NORMSPEC_EMISSIVE,  		// Following are object types (only used in drawable mRenderType)  		RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES,  		RENDER_TYPE_VOLUME, @@ -562,7 +590,8 @@ public:  	static BOOL				sRenderDeferred;  	static BOOL             sMemAllocationThrottled;  	static S32				sVisibleLightCount; -	static F32				sMinRenderSize;	 +	static F32				sMinRenderSize; +	static BOOL				sRenderingHUDs;  	//screen texture  	U32 					mScreenWidth; @@ -773,17 +802,20 @@ protected:  	// For quick-lookups into mPools (mapped by texture pointer)  	std::map<uintptr_t, LLDrawPool*>	mTerrainPools;  	std::map<uintptr_t, LLDrawPool*>	mTreePools; -	LLDrawPool*					mAlphaPool; +	LLDrawPoolAlpha*			mAlphaPool;  	LLDrawPool*					mSkyPool;  	LLDrawPool*					mTerrainPool;  	LLDrawPool*					mWaterPool;  	LLDrawPool*					mGroundPool;  	LLRenderPass*				mSimplePool;  	LLRenderPass*				mGrassPool; +	LLRenderPass*				mAlphaMaskPool; +	LLRenderPass*				mFullbrightAlphaMaskPool;  	LLRenderPass*				mFullbrightPool;  	LLDrawPool*					mInvisiblePool;  	LLDrawPool*					mGlowPool;  	LLDrawPool*					mBumpPool; +	LLDrawPool*					mMaterialsPool;  	LLDrawPool*					mWLSkyPool;  	// Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar @@ -822,6 +854,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 ; diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 42568775d9..a9176595c7 100755 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -657,6 +657,15 @@        name="PathfindingGoodColor"        reference="LtGreen" />    <color +      name="MaterialErrorColor" +      reference="LtRed" /> +  <color +      name="MaterialWarningColor" +      reference="DrYellow" /> +  <color +      name="MaterialGoodColor" +      reference="LtGreen" /> +  <color        name="PathfindingDefaultBeaconColor"        reference="Red_80" />    <color diff --git a/indra/newview/skins/default/textures/flatnormal.tga b/indra/newview/skins/default/textures/flatnormal.tga Binary files differnew file mode 100644 index 0000000000..6d5abd1782 --- /dev/null +++ b/indra/newview/skins/default/textures/flatnormal.tga diff --git a/indra/newview/skins/default/textures/materials_ui_x_24.png b/indra/newview/skins/default/textures/materials_ui_x_24.png Binary files differnew file mode 100644 index 0000000000..6d88554914 --- /dev/null +++ b/indra/newview/skins/default/textures/materials_ui_x_24.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index fcab966dee..b0e4b71d21 100755 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -743,6 +743,7 @@ with the same filename but different name    <texture name="default_land_picture.j2c" />    <texture name="default_profile_picture.j2c" />    <texture name="locked_image.j2c" /> +  <texture name="materials_ui_x_24.png" />    <texture name="Progress_1" file_name="icons/Progress_1.png" preload="true" />    <texture name="Progress_2" file_name="icons/Progress_2.png" preload="true" /> diff --git a/indra/newview/skins/default/xui/da/menu_viewer.xml b/indra/newview/skins/default/xui/da/menu_viewer.xml index d695cd1f89..f2ed7c2e64 100755 --- a/indra/newview/skins/default/xui/da/menu_viewer.xml +++ b/indra/newview/skins/default/xui/da/menu_viewer.xml @@ -245,7 +245,7 @@  		<menu label="Gengivelse" name="Rendering">  			<menu_item_check label="Akser" name="Axes"/>  			<menu_item_check label="Wireframe" name="Wireframe"/> -			<menu_item_check label="Lys og skygger" name="Lighting and Shadows"/> +			<menu_item_check label="Lys og skygger" name="Advanced Lighting Model"/>  			<menu_item_check label="Skygger fra sol/måne/andre lyskilder" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO og skygge udjævning" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Globalt lys (eksperimentiel)" name="Global Illumination"/> diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml index 2c9d9fa7f1..47d9fec352 100755 --- a/indra/newview/skins/default/xui/de/menu_viewer.xml +++ b/indra/newview/skins/default/xui/de/menu_viewer.xml @@ -315,7 +315,7 @@  			<menu_item_call label="Texturinfo für ausgewähltes Objekt" name="Selected Texture Info Basis"/>  			<menu_item_check label="Wireframe" name="Wireframe"/>  			<menu_item_check label="Objekt-Objekt Okklusion" name="Object-Object Occlusion"/> -			<menu_item_check label="Licht und Schatten" name="Lighting and Shadows"/> +			<menu_item_check label="Uber Licht Modell" name="Advanced Lighting Model"/>  			<menu_item_check label="Schatten von Sonne-/Mond-Projektoren" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO und Schattenglättung" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Fehler in GL beseitigen" name="Debug GL"/> @@ -393,14 +393,9 @@  				<menu_item_call label="Weiblich testen" name="Test Female"/>  				<menu_item_check label="Avatarauswahl zulassen" name="Allow Select Avatar"/>  			</menu> -			<menu label="Animationsgeschwindigkeit" name="Animation Speed"> -				<menu_item_call label="Alle Animationen 10 % schneller" name="All Animations 10 Faster"/> -				<menu_item_call label="Alle Animationen 10 % langsamer" name="All Animations 10 Slower"/> -				<menu_item_call label="Alle Animationsgeschwindigkeiten zurücksetzen" name="Reset All Animation Speed"/> -				<menu_item_check label="Zeitlupen-Animationen" name="Slow Motion Animations"/> -			</menu>  			<menu_item_call label="Param auf Standard erzwingen" name="Force Params to Default"/>  			<menu_item_check label="Animations-Info" name="Animation Info"/> +			<menu_item_check label="Zeitlupen-Animationen" name="Slow Motion Animations"/>  			<menu_item_check label="Kamerafokus anzeigen" name="Show Look At"/>  			<menu_item_check label="Klickpunkt anzeigen??" name="Show Point At"/>  			<menu_item_check label="Fehler in Landaktualisierung beseitigen" name="Debug Joint Updates"/> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 436e9f8fed..8b9733df17 100755 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2491,534 +2491,10 @@ even though the user gets a free copy.               width="132" />          </panel>           <panel -         border="false" -         follows="all" -         height="367"           label="Texture" -         layout="topleft" -         left_delta="0" -         mouse_opaque="false"           help_topic="toolbox_texture_tab"           name="Texture" -         top_delta="0" -         width="295"> -            <panel.string -             name="string repeats per meter"> -                Repeats Per Meter -            </panel.string> -            <panel.string -             name="string repeats per face"> -                Repeats Per Face -            </panel.string> -            <texture_picker -             can_apply_immediately="true" -             default_image_name="Default" -             fallback_image="locked_image.j2c" -             follows="left|top" -             height="80" -             label="Texture" -             layout="topleft" -             left="10" -             name="texture control" -             tool_tip="Click to choose a picture" -             top="8" -             width="64" /> -            <color_swatch -             can_apply_immediately="true" -             follows="left|top" -             height="80" -             label="Color" -             layout="topleft" -             left_pad="15" -             name="colorswatch" -             tool_tip="Click to open color picker" -             top_delta="0" -             width="64" /> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             layout="topleft" -             left_pad="15" -             name="color trans" -             text_readonly_color="LabelDisabledColor" -             top="6" -             width="110"> -                Transparency % -            </text> -            <spinner -             decimal_digits="0" -             follows="left|top" -             height="19" -             increment="2" -             initial_value="0" -             layout="topleft" -             left_delta="0" -             max_val="100" -             name="ColorTrans" -             top_pad="4" -             width="80" /> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             layout="topleft" -             left_delta="0" -             name="glow label" -             text_readonly_color="LabelDisabledColor" -             top_pad="8" -             width="80"> -                Glow -            </text> -            <spinner -             decimal_digits="2" -             follows="left|top" -             height="19" -             initial_value="0" -             layout="topleft" -             left_delta="0" -             name="glow" -             top_pad="4" -             width="80" /> -            <check_box -             height="19" -             label="Full Bright" -             layout="topleft" -             left_delta="-5" -             name="checkbox fullbright" -             top_pad="4" -             width="81" /> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             layout="topleft" -             left="10" -             name="tex gen" -             text_readonly_color="LabelDisabledColor" -             top_pad="5" -             width="90"> -                Mapping -            </text> -            <combo_box -             height="23" -             layout="topleft" -             left_delta="0" -             name="combobox texgen" -             top_pad="4" -             width="90"> -                <combo_box.item -                 label="Default" -                 name="Default" -                 value="Default" /> -                <combo_box.item -                 label="Planar" -                 name="Planar" -                 value="Planar" /> -            </combo_box> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             layout="topleft" -             name="label shininess" -             left_pad="4" -             text_readonly_color="LabelDisabledColor" -             top_pad="-37" -             width="90"> -                Shininess -            </text> -            <combo_box -             height="23" -             layout="topleft" -             left_delta="0" -             name="combobox shininess" -             top_pad="4" -             width="90"> -                <combo_box.item -                 label="None" -                 name="None" -                 value="None" /> -                <combo_box.item -                 label="Low" -                 name="Low" -                 value="Low" /> -                <combo_box.item -                 label="Medium" -                 name="Medium" -                 value="Medium" /> -                <combo_box.item -                 label="High" -                 name="High" -                 value="High" /> -            </combo_box> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             layout="topleft" -             left_pad="4" -             name="label bumpiness" -             text_readonly_color="LabelDisabledColor" -             top_pad="-37" -             width="90"> -                Bumpiness -            </text> -            <combo_box -             height="23" -             layout="topleft" -             left_delta="0" -             name="combobox bumpiness" -             top_pad="4" -             width="90"> -                <combo_box.item -                 label="None" -                 name="None" -                 value="None" /> -                <combo_box.item -                 label="Brightness" -                 name="Brightness" -                 value="Brightness" /> -                <combo_box.item -                 label="Darkness" -                 name="Darkness" -                 value="Darkness" /> -                <combo_box.item -                 label="woodgrain" -                 name="woodgrain" -                 value="woodgrain" /> -                <combo_box.item -                 label="bark" -                 name="bark" -                 value="bark" /> -                <combo_box.item -                 label="bricks" -                 name="bricks" -                 value="bricks" /> -                <combo_box.item -                 label="checker" -                 name="checker" -                 value="checker" /> -                <combo_box.item -                 label="concrete" -                 name="concrete" -                 value="concrete" /> -                <combo_box.item -                 label="crustytile" -                 name="crustytile" -                 value="crustytile" /> -                <combo_box.item -                 label="cutstone" -                 name="cutstone" -                 value="cutstone" /> -                <combo_box.item -                 label="discs" -                 name="discs" -                 value="discs" /> -                <combo_box.item -                 label="gravel" -                 name="gravel" -                 value="gravel" /> -                <combo_box.item -                 label="petridish" -                 name="petridish" -                 value="petridish" /> -                <combo_box.item -                 label="siding" -                 name="siding" -                 value="siding" /> -                <combo_box.item -                 label="stonetile" -                 name="stonetile" -                 value="stonetile" /> -                <combo_box.item -                 label="stucco" -                 name="stucco" -                 value="stucco" /> -                <combo_box.item -                 label="suction" -                 name="suction" -                 value="suction" /> -                <combo_box.item -                 label="weave" -                 name="weave" -                 value="weave" /> -            </combo_box> -          <!-- -            <line_editor -             bevel_style="in" -             border_style="line" -             border_thickness="1" -             follows="left|top" -             height="16" -             layout="topleft" -             left="10" -             max_length_bytes="63" -             name="Home Url" -             select_on_focus="true" -             top="134" -             width="250" /> -            <check_box -             height="16" -             label="Media Face" -             layout="topleft" -             left_delta="0" -             name="has media" -             top_pad="6" -             width="70" /> -            <button -             follows="left|top" -             font="SansSerifSmall" -             height="20" -             label="Set Media Info" -             label_selected="Set Media Info" -             layout="topleft" -             left_pad="60" -             name="media info set" -             top_delta="-4" -             width="120" /> ---> -            <check_box -             follows="top|left" -             height="16" -             initial_value="false" -             label="Align planar faces" -             layout="topleft" -             left="17" -             name="checkbox planar align" -             tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping." -             top_delta="26" -             width="140" /> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             layout="topleft" -             left="10" -             name="rpt" -             text_readonly_color="LabelDisabledColor" -             top_pad="2" -             width="140"> -                Repeats / Face -            </text> -            <spinner -             follows="left|top" -             height="19" -             initial_value="0" -             label="Horizontal (U)" -             label_width="125" -             layout="topleft" -             left="20" -             max_val="100" -             name="TexScaleU" -             top_pad="5" -             width="185" /> -            <check_box -             height="19" -             label="Flip" -             layout="topleft" -             left_pad="5" -             name="checkbox flip s" -             top_delta="0" -             width="70" /> -            <spinner -             follows="left|top" -             height="19" -             initial_value="0" -             label="Vertical (V)" -             label_width="125" -             layout="topleft" -             left="20" -             max_val="100" -             name="TexScaleV" -             width="185" /> -            <check_box -             height="19" -             label="Flip" -             layout="topleft" -             left_pad="5" -             name="checkbox flip t" -             top_delta="0" -             width="70" /> -            <spinner -             decimal_digits="2" -             follows="left|top" -             height="19" -             increment="1" -             initial_value="0" -			 label="Rotation˚" -             layout="topleft" -			 label_width="135" -             left="10" -             max_val="9999" -             min_val="-9999" -             name="TexRot" -             width="195" /> - -            <spinner -             decimal_digits="1" -             follows="left|top" -             height="23" -             initial_value="1" -			 label="Repeats / Meter" -             layout="topleft" -			 label_width="135" -             left="10" -             max_val="10" -             min_val="0.1" -             name="rptctrl" -             width="195" /> -            <button -             follows="left|top" -             height="23" -             label="Apply" -             label_selected="Apply" -             layout="topleft" -             left_pad="5" -             name="button apply" -             width="75" /> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             layout="topleft" -             left="10" -             name="tex offset" -             text_readonly_color="LabelDisabledColor" -             width="200"> -                Texture Offset -            </text> -            <spinner -             follows="left|top" -             height="19" -             initial_value="0" -             label="Horizontal (U)" -             label_width="125" -             layout="topleft" -             left="20" -             min_val="-1" -             name="TexOffsetU" -             width="185" /> -            <spinner -             follows="left|top" -             height="19" -             initial_value="0" -             label="Vertical (V)" -             label_width="125" -             layout="topleft" -             left_delta="0" -             min_val="-1" -             name="TexOffsetV" -             top_pad="1" -             width="185" /> -        <panel -         border="false" -         follows="left|top" -         layout="topleft" -         mouse_opaque="false" -         background_visible="true" -         bg_alpha_color="DkGray" -         name="Add_Media" -         left="0" -         height="47" -         width="290"> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="18" -             layout="topleft" -             left="10" -             top_pad="3" -             name="media_tex" -             width="190"> -              Media -			</text> -			<button -			 follows="top|left" -			 height="18" -			 image_selected="AddItem_Press" -			 image_unselected="AddItem_Off" -			 image_disabled="AddItem_Disabled" -			 layout="topleft" -			 left_pad="0" -			 name="add_media" -			 tab_stop="false" -			 top_delta="0" -			 tool_tip="Add Media" -			 width="18"> -				<button.commit_callback -				function="BuildTool.AddMedia"/> -			</button> -			<button -			 follows="top|left" -			 height="18" -			 image_selected="TrashItem_Press" -			 image_unselected="TrashItem_Off" -			 layout="topleft" -			 left_pad="5" -			 name="delete_media" -			 tool_tip="Delete this media texture" -			 top_delta="0" -			 width="18"> -				<button.commit_callback -				function="BuildTool.DeleteMedia"/> -			</button> -			<button -			 follows="top|left" -			 tool_tip="Edit this Media" -			 height="12" -             image_disabled="Icon_Gear_Background" -             image_selected="Icon_Gear_Press" -             image_unselected="Icon_Gear_Foreground" -			 layout="topleft" -			 left_pad="10" -			 name="edit_media" -			 top_delta="3" -			 width="12"> -				<button.commit_callback -				function="BuildTool.EditMedia"/> -			</button> -      <text -			 follows="left|top|right" -			 height="9" -			 layout="topleft" -			 left="10" -                         use_ellipses="true" -			 read_only="true" -			 name="media_info" -			 width="180" /> -      <web_browser -        visible="false" -        enabled="false" -        border_visible="true" -        bottom_delta="0" -        follows="top|left" -        left="0" -        name="title_media" -        width="4" -        height="4" -        start_url="about:blank" -        decouple_texture_size="true" /> -     <button -			 follows="right|top" -			 height="22" -			 label="Align" -			 label_selected="Align Media" -			 layout="topleft" -			 right="-16" -			 name="button align" -			 top_delta="-4" -			 tool_tip="Align media texture (must load first)" -			 width="80" /> -		</panel> +         filename="panel_tools_texture.xml">  	   </panel>         <panel           border="false" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 6f7c70196c..752734d7bd 100755 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2371,6 +2371,12 @@                  <menu_item_check.on_click                   function="Advanced.ToggleFrameTest" />              </menu_item_check> +          <menu_item_call +             label="Frame Profile" +             name="Frame Profile"> +            <menu_item_call.on_click +             function="Advanced.ClickRenderProfile" /> +          </menu_item_call>          </menu>        <menu          create_jump_keys="true" @@ -2666,6 +2672,13 @@                  <menu_item_call.on_click                   function="Advanced.SelectedTextureInfo" />              </menu_item_call> +            <menu_item_call +             label="Selected Material Info" +             name="Selected Material Info" +             shortcut="control|alt|shift|M"> +                <menu_item_call.on_click +                 function="Advanced.SelectedMaterialInfo" /> +            </menu_item_call>              <menu_item_check               label="Wireframe"               name="Wireframe" @@ -2692,8 +2705,8 @@            <menu_item_separator />            <menu_item_check -                       label="Lighting and Shadows" -                       name="Lighting and Shadows"> +                       label="Advanced Lighting Model" +                       name="Advanced Lighting Model">              <menu_item_check.on_check               function="CheckControl"               parameter="RenderDeferred" /> @@ -2800,16 +2813,6 @@                   parameter="TextureLoadFullRes" />              </menu_item_check>              <menu_item_check -             label="Texture Atlas (experimental)" -             name="Texture Atlas"> -              <menu_item_check.on_check -               function="CheckControl" -               parameter="EnableTextureAtlas" /> -              <menu_item_check.on_click -               function="ToggleControl" -               parameter="EnableTextureAtlas" /> -            </menu_item_check> -              <menu_item_check               label="Render Attached Lights"               name="Render Attached Lights">                  <menu_item_check.on_check diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 970a11c6c4..9e582cf0de 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3454,7 +3454,7 @@ or you can install it now.     name="DownloadBackgroundTip"     type="notify">  We have downloaded an update to your [APP_NAME] installation. -Version [VERSION] [[INFO_URL] Information about this update] +Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]      <tag>confirm</tag>      <usetemplate       name="okcancelbuttons" @@ -3467,7 +3467,7 @@ Version [VERSION] [[INFO_URL] Information about this update]   name="DownloadBackgroundDialog"   type="alertmodal">  We have downloaded an update to your [APP_NAME] installation. -Version [VERSION] [[INFO_URL] Information about this update] +Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]      <tag>confirm</tag>      <usetemplate       name="okcancelbuttons" @@ -6923,9 +6923,9 @@ Do not allow access if you do not fully understand why it wants access to your a  [FOOTERTEXT]      </footer>    </notification> -	 -	<notification -	 icon="notify.tga" + +  <notification +   icon="notify.tga"  	 name="UnknownScriptQuestion"  	 persist="false"  	 type="notify"> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index cd243d40a4..d7db7caf66 100755 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -211,16 +211,19 @@  		 name="TransparentWater"  		 top_pad="7"  		 width="256" /> -		<check_box -		 control_name="RenderObjectBump" -		 height="16" -		 initial_value="true" -		 label="Bump mapping and shiny" -		 layout="topleft" -		 left_delta="0" -		 name="BumpShiny" -		 top_pad="1" -		width="256" /> +      <check_box +       control_name="RenderObjectBump" +       height="16" +       initial_value="true" +       label="Bump mapping and shiny" +       layout="topleft" +       left_delta="0" +       name="BumpShiny" +       top_pad="1" +      width="256"> +        <check_box.commit_callback +        function="Pref.VertexShaderEnable" /> +      </check_box>      <check_box  		control_name="RenderLocalLights"  		height="16" @@ -262,7 +265,7 @@  		 control_name="RenderDeferred"  		 height="16"  		 initial_value="true" -		 label="Lighting and Shadows" +		 label="Advanced Lighting Model"  		 layout="topleft"  		 left_delta="0"  		 name="UseLightShaders" diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml new file mode 100644 index 0000000000..5ac2ec2b20 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -0,0 +1,766 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel +         border="false" +         follows="all" +         height="420" +         label="Texture" +         layout="topleft" +         left="0" +         mouse_opaque="false" +         help_topic="toolbox_texture_tab" +         name="Texture" +         top="0" +         width="295"> +            <panel.string +             name="string repeats per meter"> +                Repeats Per Meter +            </panel.string> +            <panel.string +             name="string repeats per face"> +                Repeats Per Face +            </panel.string> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left="10" +             name="color label" +             text_readonly_color="LabelDisabledColor" +             top="6" +             width="64"> +                Color +            </text> +            <!-- label is blank because control places it below the box --> +            <color_swatch +             can_apply_immediately="true" +             follows="left|top" +             height="45" +             label="" +             layout="topleft" +             left="10" +             name="colorswatch" +             tool_tip="Click to open color picker" +             top="20" +             width="64" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_pad="15" +             name="color trans" +             text_readonly_color="LabelDisabledColor" +             top="6" +             width="110"> +                Transparency % +            </text> +            <spinner +             decimal_digits="0" +             follows="left|top" +             height="19" +             increment="2" +             initial_value="0" +             layout="topleft" +             left_delta="0" +             max_val="100" +             name="ColorTrans" +             top_pad="4" +             width="80" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_pad="15" +             name="glow label" +             text_readonly_color="LabelDisabledColor" +             top="6" +             width="80"> +                Glow +            </text> +            <spinner +             decimal_digits="2" +             follows="left|top" +             height="19" +             initial_value="0" +             layout="topleft" +             left_delta="0" +             name="glow" +             top_pad="4" +             width="80" /> +            <check_box +             height="19" +             label="Full Bright" +             layout="topleft" +             left="7" +             name="checkbox fullbright" +             top_pad="4" +             width="81" /> +            <combo_box +             height="23" +             layout="topleft" +             left="10" +             name="combobox matmedia" +             top_pad="5" +             width="100"> +                <combo_box.item +                 label="Materials" +                 name="Materials" +                 value="Materials" /> +                <combo_box.item +                 label="Media" +                 name="Media" +                 value="Media" /> +            </combo_box> +            <combo_box +             height="23" +             layout="topleft" +             left_pad="10" +             name="combobox mattype" +             top_delta="0" +             width="155"> +                <combo_box.item +                 label="Texture (diffuse)" +                 name="Texture (diffuse)" +                 value="Texture (diffuse)" /> +                <combo_box.item +                 label="Bumpiness (normal)" +                 name="Bumpiness (normal)" +                 value="Bumpiness (normal)" /> +                <combo_box.item +                 label="Shininess (specular)" +                 name="Shininess (specular)" +                 value="Shininess (specular)" /> +            </combo_box> +            <texture_picker +             can_apply_immediately="true" +             default_image_name="Default" +             fallback_image="materials_ui_x_24.png" +             follows="left|top" +             height="80" +             label="Texture       " +             layout="topleft" +             left="10" +             name="texture control" +             tool_tip="Click to choose a picture" +             top_pad="8" +             width="64" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_pad="10" +             name="label alphamode" +             text_readonly_color="LabelDisabledColor" +             top_delta="0" +             width="90"> +                Alpha mode +            </text> +            <combo_box +             height="23" +             layout="topleft" +             left_delta="0" +             name="combobox alphamode" +             top_pad="4" +             width="120"> +                <combo_box.item +                 label="None" +                 name="None" +                 value="None" /> +                <combo_box.item +                 label="Alpha blending" +                 name="Alpha blending" +                 value="Alpha blending" /> +                <combo_box.item +                 label="Alpha masking" +                 name="Alpha masking" +                 value="Alpha masking" /> +                <combo_box.item +                 label="Emissive mask" +                 name="Emissive mask" +                 value="Emissive mask" /> +            </combo_box> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_delta="0" +             name="label maskcutoff" +             text_readonly_color="LabelDisabledColor" +             top_pad="4" +             width="90"> +                Mask cutoff +            </text> +            <spinner +             decimal_digits="0" +             min_val="0" +             max_val="255" +             follows="left|top" +             height="19" +             initial_value="55" +             layout="topleft" +             top_pad="4" +             left_delta="0" +             increment="1" +             name="maskcutoff" +             width="80" /> +            <texture_picker +             allow_no_texture="true" +             can_apply_immediately="true" +             default_image_name="Default" +             fallback_image="materials_ui_x_24.png" +             follows="left|top" +             height="80" +             label="Texture       " +             layout="topleft" +             left="10" +             name="bumpytexture control" +             tool_tip="Click to choose a picture" +             top_delta="-55" +             width="64" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_pad="10" +             name="label bumpiness" +             text_readonly_color="LabelDisabledColor" +             top_delta="0" +             width="90"> +                Bumpiness +            </text> +            <combo_box +             height="23" +             layout="topleft" +             left_delta="0" +             name="combobox bumpiness" +             top_pad="4" +             width="90"> +                <combo_box.item +                 label="None" +                 name="None" +                 value="None" /> +                <combo_box.item +                 label="Brightness" +                 name="Brightness" +                 value="Brightness" /> +                <combo_box.item +                 label="Darkness" +                 name="Darkness" +                 value="Darkness" /> +                <combo_box.item +                 label="woodgrain" +                 name="woodgrain" +                 value="woodgrain" /> +                <combo_box.item +                 label="bark" +                 name="bark" +                 value="bark" /> +                <combo_box.item +                 label="bricks" +                 name="bricks" +                 value="bricks" /> +                <combo_box.item +                 label="checker" +                 name="checker" +                 value="checker" /> +                <combo_box.item +                 label="concrete" +                 name="concrete" +                 value="concrete" /> +                <combo_box.item +                 label="crustytile" +                 name="crustytile" +                 value="crustytile" /> +                <combo_box.item +                 label="cutstone" +                 name="cutstone" +                 value="cutstone" /> +                <combo_box.item +                 label="discs" +                 name="discs" +                 value="discs" /> +                <combo_box.item +                 label="gravel" +                 name="gravel" +                 value="gravel" /> +                <combo_box.item +                 label="petridish" +                 name="petridish" +                 value="petridish" /> +                <combo_box.item +                 label="siding" +                 name="siding" +                 value="siding" /> +                <combo_box.item +                 label="stonetile" +                 name="stonetile" +                 value="stonetile" /> +                <combo_box.item +                 label="stucco" +                 name="stucco" +                 value="stucco" /> +                <combo_box.item +                 label="suction" +                 name="suction" +                 value="suction" /> +                <combo_box.item +                 label="weave" +                 name="weave" +                 value="weave" /> +              <!-- +                 NORSPEC-182, ensure item doesn't show up in menu until it should +                <combo_box.item +                 label="Use texture" +                 name="Use texture" +                 value="Use texture" /> +                 --> +            </combo_box> +            <texture_picker +             allow_no_texture="true" +             can_apply_immediately="true" +             default_image_name="Default" +             fallback_image="materials_ui_x_24.png" +             follows="left|top" +             height="80" +             label="Texture       " +             layout="topleft" +             left="10" +             name="shinytexture control" +             tool_tip="Click to choose a picture" +             top_delta="-14" +             width="64" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             name="label shininess" +             left_pad="10" +             text_readonly_color="LabelDisabledColor" +             top_delta="6" +             width="90"> +                Shininess +            </text> +            <combo_box +             height="23" +             layout="topleft" +             left_pad="10" +             name="combobox shininess" +             top_delta="-6" +             width="90"> +                <combo_box.item +                 label="None" +                 name="None" +                 value="None" /> +                <combo_box.item +                 label="Low" +                 name="Low" +                 value="Low" /> +                <combo_box.item +                 label="Medium" +                 name="Medium" +                 value="Medium" /> +                <combo_box.item +                 label="High" +                 name="High" +                 value="High" /> +              <!-- +                 NORSPEC-182, ensure item doesn't show up in menu until it should +                <combo_box.item +                 label="Use texture" +                 name="Use texture" +                 value="Use texture" /> +                 --> +            </combo_box> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_delta="-100" +             name="label glossiness" +             text_readonly_color="LabelDisabledColor" +             top_pad="8" +             width="116"> +                Glossiness +            </text> +            <spinner +             decimal_digits="0" +             min_val="0" +             max_val="255" +             follows="left|top" +             height="19" +             initial_value="51" +             increment="1" +             layout="topleft" +             top_delta="-4" +             left_pad="10" +             name="glossiness" +             width="64" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_delta="-126" +             name="label environment" +             text_readonly_color="LabelDisabledColor" +             top_pad="8" +             width="116"> +                Environment +            </text> +            <spinner +             decimal_digits="0" +             min_val="0" +             max_val="255" +             increment="1" +             follows="left|top" +             height="19" +             initial_value="0" +             layout="topleft" +             top_delta="-4" +             left_pad="10" +             name="environment" +             width="64" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_delta="-126" +             name="label shinycolor" +             text_readonly_color="LabelDisabledColor" +             top_pad="8" +             width="116"> +                Color +            </text> +            <!-- label is blank because control places it below the box --> +            <color_swatch +             can_apply_immediately="true" +             follows="left|top" +             height="45" +             label="" +             layout="topleft" +             left_pad="10" +             name="shinycolorswatch" +             tool_tip="Click to open color picker" +             top_delta="-4" +             width="64" /> +            <text +			 follows="left|top|right" +			 height="9" +			 layout="topleft" +			 left="10" +			 top_delta="-50" +             use_ellipses="true" +			 read_only="true" +			 name="media_info" +			 width="280"> +			 URL of chosen media, if any, goes here +			 </text> +			<button +			 follows="top|left" +			 height="18" +			 layout="topleft" +			 left="10" +			 name="add_media" +			 top_pad="4" +			 tool_tip="Add Media" +			 label="Choose..." +			 width="85"> +				<button.commit_callback +				function="BuildTool.AddMedia"/> +			</button> +			<button +			 follows="top|left" +			 height="18" +			 layout="topleft" +			 left_pad="5" +			 name="delete_media" +			 tool_tip="Delete this media texture" +			 top_delta="0" +			 label="Remove" +			 width="85"> +				<button.commit_callback +				function="BuildTool.DeleteMedia"/> +			</button> +            <button +			 follows="left|top" +			 height="18" +			 label="Align" +			 label_selected="Align Media" +			 layout="topleft" +			 left_pad="5" +			 name="button align" +			 top_delta="0" +			 tool_tip="Align media texture (must load first)" +			 width="85" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left="10" +             name="tex gen" +             text_readonly_color="LabelDisabledColor" +             top_pad="60" +             width="140"> +                Mapping +            </text> +            <combo_box +             height="23" +             layout="topleft" +             left_pad="0" +             name="combobox texgen" +             top_pad="-13" +             width="125"> +                <combo_box.item +                 label="Default" +                 name="Default" +                 value="Default" /> +                <combo_box.item +                 label="Planar" +                 name="Planar" +                 value="Planar" /> +            </combo_box> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Horizontal scale" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-100" +             max_val="100" +             name="TexScaleU" +             top_pad="5" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Vertical scale" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-100" +             max_val="100" +             name="TexScaleV" +             width="265" /> +            <spinner +             decimal_digits="1" +             follows="left|top" +             height="19" +             initial_value="" +			 label="Repeats per meter" +             layout="topleft" +			 label_width="205" +             left="10" +             max_val="100" +             min_val="0.1" +             name="rptctrl" +             width="265" /> +           <spinner +             decimal_digits="2" +             follows="left|top" +             height="19" +             increment="1" +             initial_value="0" +			 label="Rotation degrees" +             layout="topleft" +			 label_width="205" +             left="10" +             max_val="9999" +             min_val="-9999" +             name="TexRot" +             width="265" /> + +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Horizontal offset" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-1" +             name="TexOffsetU" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Vertical offset" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-1" +             name="TexOffsetV" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Horizontal scale" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-100" +             max_val="100" +             name="bumpyScaleU" +             top_delta="-115" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Vertical scale" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-100" +             max_val="100" +             name="bumpyScaleV" +             width="265" /> +           <spinner +             decimal_digits="2" +             follows="left|top" +             height="19" +             top_pad="27" +             increment="1" +             initial_value="0" +			 label="Rotation degrees" +             layout="topleft" +			 label_width="205" +             left="10" +             max_val="360" +             min_val="0" +             name="bumpyRot" +             width="265" /> + +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Horizontal offset" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-1" +             name="bumpyOffsetU" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Vertical offset" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-1" +             name="bumpyOffsetV" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Horizontal scale" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-100" +             max_val="100" +             name="shinyScaleU" +             top_delta="-115" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Vertical scale" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-100" +             max_val="100" +             name="shinyScaleV" +             width="265" /> +           <spinner +             decimal_digits="2" +             follows="left|top" +             height="19" +             top_pad="27" +             increment="1" +             initial_value="0" +			 label="Rotation degrees" +             layout="topleft" +			 label_width="205" +             left="10" +             max_val="360" +             min_val="0" +             name="shinyRot" +             width="265" /> + +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Horizontal offset" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-1" +             name="shinyOffsetU" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Vertical offset" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-1" +             name="shinyOffsetV" +             width="265" /> +            <check_box +             follows="top|left" +             height="16" +             initial_value="false" +             label="Align planar faces" +             layout="topleft" +             left="7" +             name="checkbox planar align" +             tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping." +             top_delta="16" +             width="260" /> +            <web_browser +             visible="false" +             enabled="false" +             border_visible="true" +             bottom_delta="0" +             follows="top|left" +             left="0" +             name="title_media" +             width="4" +             height="4" +             start_url="about:blank" +             decouple_texture_size="true" /> +	   </panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index d38133832e..6fe847df50 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -373,6 +373,8 @@ Please try logging in again in a minute.</string>  	<!-- build floater -->  	<string name="multiple_textures">Multiple</string> +<string name="use_texture">Use texture</string> +  	<!-- world map -->  	<string name="texture_loading">Loading...</string>  	<string name="worldmap_offline">Offline</string> @@ -416,7 +418,7 @@ Please try logging in again in a minute.</string>  	<string name="OverrideYourAnimations">Replace your default animations</string>  	<string name="ScriptReturnObjects">Return objects on your behalf</string>  	<string name="UnknownScriptPermission">(unknown)!</string> -	 +  	<!-- Sim Access labels -->  	<string name="SIM_ACCESS_PG">General</string>  	<string name="SIM_ACCESS_MATURE">Moderate</string> diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml index 30842f53f2..1e0ceb2220 100755 --- a/indra/newview/skins/default/xui/es/menu_viewer.xml +++ b/indra/newview/skins/default/xui/es/menu_viewer.xml @@ -293,7 +293,7 @@  		<menu label="Rendering" name="Rendering">  			<menu_item_check label="Axes" name="Axes"/>  			<menu_item_check label="Wireframe" name="Wireframe"/> -			<menu_item_check label="Luces y sombras" name="Lighting and Shadows"/> +			<menu_item_check label="Luces y sombras" name="Advanced Lighting Model"/>  			<menu_item_check label="Sombras del sol/la luna/proyectores" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO y sombras suavizadas" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Capas alfa automáticas (deferidas)" name="Automatic Alpha Masks (deferred)"/> diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml index 457b756c7d..548f144742 100755 --- a/indra/newview/skins/default/xui/fr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml @@ -315,7 +315,7 @@  			<menu_item_call label="Base des infos de la texture sélectionnée" name="Selected Texture Info Basis"/>  			<menu_item_check label="Filaire" name="Wireframe"/>  			<menu_item_check label="Occlusion objet-objet" name="Object-Object Occlusion"/> -			<menu_item_check label="Éclairage et ombres" name="Lighting and Shadows"/> +			<menu_item_check label="Éclairage et ombres" name="Advanced Lighting Model"/>  			<menu_item_check label="Ombres du soleil/de la lune/des projecteurs" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO et lissage des ombres" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Débogage GL" name="Debug GL"/> diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml index c93b92029f..2b7bc71df7 100755 --- a/indra/newview/skins/default/xui/it/menu_viewer.xml +++ b/indra/newview/skins/default/xui/it/menu_viewer.xml @@ -294,7 +294,7 @@  		<menu label="Rendering" name="Rendering">  			<menu_item_check label="Assi" name="Axes"/>  			<menu_item_check label="Wireframe" name="Wireframe"/> -			<menu_item_check label="Luci e ombre" name="Lighting and Shadows"/> +			<menu_item_check label="Luci e ombre" name="Advanced Lighting Model"/>  			<menu_item_check label="Ombra dal sole, dalla luna e dai proiettori" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO e ombre fluide" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Maschera alfa automatica (differita)" name="Automatic Alpha Masks (deferred)"/> diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml index 6f650242b4..89f58d3bac 100755 --- a/indra/newview/skins/default/xui/ja/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml @@ -315,7 +315,7 @@  			<menu_item_call label="選択したテクスチャ情報基底" name="Selected Texture Info Basis"/>  			<menu_item_check label="ワイヤーフレーム" name="Wireframe"/>  			<menu_item_check label="オブジェクト間オクルージョン" name="Object-Object Occlusion"/> -			<menu_item_check label="光と影" name="Lighting and Shadows"/> +			<menu_item_check label="光と影" name="Advanced Lighting Model"/>  			<menu_item_check label="太陽・月・プロジェクタからの影" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO と影の平滑化" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="GL デバッグ" name="Debug GL"/> diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml index 24c961fa26..e1725fc308 100755 --- a/indra/newview/skins/default/xui/pl/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml @@ -236,7 +236,7 @@  		<menu label="Renderowanie" name="Rendering">  			<menu_item_check label="Osie" name="Axes"/>  			<menu_item_check label="Tryb obrazu szkieletowego" name="Wireframe"/> -			<menu_item_check label="Oświetlenie i cienie" name="Lighting and Shadows"/> +			<menu_item_check label="Oświetlenie i cienie" name="Advanced Lighting Model"/>  			<menu_item_check label="Cienie Słońca/Księżyca/Projektory" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO and wygładzanie cienia" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Globalne oświetlenie (eksperymentalne)" name="Global Illumination"/> diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml index 703df84efb..15814fed4c 100755 --- a/indra/newview/skins/default/xui/pt/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml @@ -294,7 +294,7 @@  		<menu label="Rendering" name="Rendering">  			<menu_item_check label="Axes" name="Axes"/>  			<menu_item_check label="Wireframe" name="Wireframe"/> -			<menu_item_check label="Iluminação e sombras" name="Lighting and Shadows"/> +			<menu_item_check label="Iluminação e sombras" name="Advanced Lighting Model"/>  			<menu_item_check label="Sombras da projeção do sol/lua" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO e sombra suave" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Máscaras alpha automáticas (adiadas)" name="Automatic Alpha Masks (deferred)"/> diff --git a/indra/newview/skins/default/xui/ru/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml index d6625361c5..92a9943b93 100755 --- a/indra/newview/skins/default/xui/ru/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml @@ -114,6 +114,7 @@  			<menu_item_call label="Купить" name="Menu Object Buy"/>  			<menu_item_call label="Взять" name="Menu Object Take"/>  			<menu_item_call label="Взять копию" name="Take Copy"/> +			<menu_item_call label="Сохранить в моем инвентаре" name="Save Object Back to My Inventory"/>  			<menu_item_call label="Сохранить в контенте объектов" name="Save Object Back to Object Contents"/>  			<menu_item_call label="Вернуть объект" name="Return Object back to Owner"/>  		</menu> @@ -128,7 +129,6 @@  			<menu_item_call label="Наборы связей..." name="pathfinding_linksets_menu_item"/>  			<menu_item_call label="Персонажи..." name="pathfinding_characters_menu_item"/>  			<menu_item_call label="Просмотр/тестирование..." name="pathfinding_console_menu_item"/> -			<menu_item_call label="Восстановить регион" name="pathfinding_rebake_navmesh_item"/>  		</menu>  		<menu label="Параметры" name="Options">  			<menu_item_check label="Показать расширенные разрешения" name="DebugPermissions"/> @@ -158,13 +158,6 @@  	<menu label="Справка" name="Help">  		<menu_item_call label="Инструкции..." name="How To"/>  		<menu_item_call label="Справка по [SECOND_LIFE]" name="Second Life Help"/> -		<menu_item_call label="Руководство пользователя" name="User’s guide"/> -		<menu_item_call label="База знаний" name="Knowledge Base"/> -		<menu_item_call label="Wiki" name="Wiki"/> -		<menu_item_call label="Форумы сообщества" name="Community Forums"/> -		<menu_item_call label="Портал поддержки" name="Support portal"/> -		<menu_item_call label="Новости [SECOND_LIFE]" name="Second Life News"/> -		<menu_item_call label="Блоги [SECOND_LIFE]" name="Second Life Blogs"/>  		<menu_item_call label="Жалоба" name="Report Abuse"/>  		<menu_item_call label="Сообщить об ошибке" name="Report Bug"/>  		<menu_item_call label="О [APP_NAME]" name="About Second Life"/> @@ -313,7 +306,7 @@  			<menu_item_call label="Выбранная текстура в основе" name="Selected Texture Info Basis"/>  			<menu_item_check label="Каркас" name="Wireframe"/>  			<menu_item_check label="Смыкание объектов" name="Object-Object Occlusion"/> -			<menu_item_check label="Освещение и тени" name="Lighting and Shadows"/> +			<menu_item_check label="Освещение и тени" name="Advanced Lighting Model"/>  			<menu_item_check label="Тени от солнца, луны и прожекторов" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO и сглаживание теней" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Отладка GL" name="Debug GL"/> @@ -391,14 +384,9 @@  				<menu_item_call label="Проверка женщины" name="Test Female"/>  				<menu_item_check label="Разрешить выбор аватара" name="Allow Select Avatar"/>  			</menu> -			<menu label="Скорость анимации" name="Animation Speed"> -				<menu_item_call label="Ускорить все анимации на 10%" name="All Animations 10 Faster"/> -				<menu_item_call label="Замедлить все анимации на 10%" name="All Animations 10 Slower"/> -				<menu_item_call label="Восстановить скорость анимаций" name="Reset All Animation Speed"/> -				<menu_item_check label="Анимация медленных движений" name="Slow Motion Animations"/> -			</menu>  			<menu_item_call label="Скинуть параметры" name="Force Params to Default"/>  			<menu_item_check label="Данные об анимации" name="Animation Info"/> +			<menu_item_check label="Анимация медленных движений" name="Slow Motion Animations"/>  			<menu_item_check label="Показать взгляд" name="Show Look At"/>  			<menu_item_check label="Показать указание" name="Show Point At"/>  			<menu_item_check label="Отладка обновленных движений суставов" name="Debug Joint Updates"/> diff --git a/indra/newview/skins/default/xui/tr/menu_viewer.xml b/indra/newview/skins/default/xui/tr/menu_viewer.xml index c465966fc7..35485bb292 100755 --- a/indra/newview/skins/default/xui/tr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml @@ -313,7 +313,7 @@  			<menu_item_call label="Seçilen Doku Bilgi Temeli" name="Selected Texture Info Basis"/>  			<menu_item_check label="Telkafes" name="Wireframe"/>  			<menu_item_check label="Görünen Nesneler İçin Gölgeleme" name="Object-Object Occlusion"/> -			<menu_item_check label="Işıklandırma ve Gölgeler" name="Lighting and Shadows"/> +			<menu_item_check label="Işıklandırma ve Gölgeler" name="Advanced Lighting Model"/>  			<menu_item_check label="Güneş/Ay/Projektörlerden Gelen Gölgeler" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO ve Gölge Yumuşatma" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="GL Hata Ayıklama" name="Debug GL"/> diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml index 09bdc57819..d4844b191b 100755 --- a/indra/newview/skins/default/xui/zh/menu_viewer.xml +++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml @@ -313,7 +313,7 @@  			<menu_item_call label="已選取材質資訊基礎" name="Selected Texture Info Basis"/>  			<menu_item_check label="線框" name="Wireframe"/>  			<menu_item_check label="物件導向的遮蔽" name="Object-Object Occlusion"/> -			<menu_item_check label="光線和陰影" name="Lighting and Shadows"/> +			<menu_item_check label="光線和陰影" name="Advanced Lighting Model"/>  			<menu_item_check label="來自日/月/投影物的陰影" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="屏幕空間環境光遮蔽和陰影平滑技術" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="GL 除錯" name="Debug GL"/> diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp index 41cb344808..3e55336f2d 100755 --- a/indra/newview/tests/llmediadataclient_test.cpp +++ b/indra/newview/tests/llmediadataclient_test.cpp @@ -39,6 +39,7 @@  #include "../llvovolume.h"  #include "../../llprimitive/llmediaentry.cpp" +#include "../../llprimitive/llmaterialid.cpp"  #include "../../llprimitive/lltextureentry.cpp"  #include "../../llmessage/tests/llcurl_stub.cpp" diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 2578c81224..35451c9621 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -729,7 +729,7 @@ class DarwinManifest(ViewerManifest):                                  'SLVoice',                                  ):                       self.path2basename(libdir, libfile) - +                                  # our apps                  for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),                                           # plugin launcher @@ -1038,9 +1038,6 @@ class Linux_i686Manifest(LinuxManifest):              self.path("libboost_signals-mt.so.*")              self.path("libboost_system-mt.so.*")              self.path("libboost_thread-mt.so.*") -            self.path("libbreakpad_client.so.0.0.0") -            self.path("libbreakpad_client.so.0") -            self.path("libbreakpad_client.so")              self.path("libcollada14dom.so")              self.path("libdb*.so")              self.path("libcrypto.so.*") diff --git a/indra/test/llsaleinfo_tut.cpp b/indra/test/llsaleinfo_tut.cpp index 2689eaa15e..2488af1d7f 100755 --- a/indra/test/llsaleinfo_tut.cpp +++ b/indra/test/llsaleinfo_tut.cpp @@ -156,7 +156,7 @@ namespace tut  		ensure("importStream() fn failed ",  			llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() && -			llsaleinfo.getSaleType() == llsaleinfo1.getSaleType()); +										       llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());		  	}  	template<> template<> diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp index 3357ad812d..8f33b2ad58 100755 --- a/indra/viewer_components/login/lllogin.cpp +++ b/indra/viewer_components/login/lllogin.cpp @@ -137,7 +137,7 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para  	//{  	//	printable_params["params"]["passwd"] = "*******";  	//} -    LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName(self) +	LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName(self)                          << " with uri '" << uri << "', parameters " << printable_params << LL_ENDL;  	// Arriving in SRVRequest state @@ -146,23 +146,23 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para      LLSD rewrittenURIs;      { -        LLEventTimeout filter(replyPump); -        sendProgressEvent("offline", "srvrequest"); +		LLEventTimeout filter(replyPump); +		sendProgressEvent("offline", "srvrequest"); -        // Request SRV record. -        LL_DEBUGS("LLLogin") << "Requesting SRV record from " << uri << LL_ENDL; +      // Request SRV record. +		LL_DEBUGS("LLLogin") << "Requesting SRV record from " << uri << LL_ENDL; -        // *NOTE:Mani - Completely arbitrary default timeout value for SRV request. +      // *NOTE:Mani - Completely arbitrary default timeout value for SRV request.  		F32 seconds_to_timeout = 5.0f;  		if(login_params.has("cfg_srv_timeout"))  		{  			seconds_to_timeout = login_params["cfg_srv_timeout"].asReal();  		} -        // If the SRV request times out (e.g. EXT-3934), simulate response: an -        // array containing our original URI. -        LLSD fakeResponse(LLSD::emptyArray()); -        fakeResponse.append(uri); +		// If the SRV request times out (e.g. EXT-3934), simulate response: an +		// array containing our original URI. +		LLSD fakeResponse(LLSD::emptyArray()); +		fakeResponse.append(uri);  		filter.eventAfter(seconds_to_timeout, fakeResponse);  		std::string srv_pump_name = "LLAres"; @@ -172,13 +172,13 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para  		}  		// Make request -        LLSD request; -        request["op"] = "rewriteURI"; -        request["uri"] = uri; -        request["reply"] = replyPump.getName(); -        rewrittenURIs = postAndWait(self, request, srv_pump_name, filter); -        // EXP-772: If rewrittenURIs fail, try original URI as a fallback. -        rewrittenURIs.append(uri); +		LLSD request; +		request["op"] = "rewriteURI"; +		request["uri"] = uri; +		request["reply"] = replyPump.getName(); +		rewrittenURIs = postAndWait(self, request, srv_pump_name, filter); +		// EXP-772: If rewrittenURIs fail, try original URI as a fallback. +		rewrittenURIs.append(uri);      } // we no longer need the filter      LLEventPump& xmlrpcPump(LLEventPumps::instance().obtain("LLXMLRPCTransaction")); @@ -230,7 +230,7 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para                  // Still Downloading -- send progress update.                  sendProgressEvent("offline", "downloading");              } -				  +	  			LL_DEBUGS("LLLogin") << "Auth Response: " << mAuthResponse << LL_ENDL;              status = mAuthResponse["status"].asString();  | 
